MySQL INNER JOINs, WHERE CLAUSE not working - mysql

I have a database with 3 tables.
content
page
page_content
page contains id, metadata stuff and so on
content contains headline, bodytext and so on
page_content contains mapping for the ids
Currently it's all done using an ORM solution, but I want to switch to plain mysql.
So I took a query builder, which gave me:
Select
cms.content.title,
cms.content.headline,
cms.content.bodytext,cms.page.pageID
From
cms.page
Inner Join
cms.page_content On cms.page_content.pageID = cms.page.pageID
Inner Join
cms.content On cms.page_content.contentID = cms.content.contentID
This shows same like just
select * from content
So I tried to add a WHERE Clause to the end.
Select
cms.content.title,
cms.content.headline,
cms.content.bodytext,cms.page.pageID
From
cms.page
Inner Join
cms.page_content On cms.page_content.pageID = cms.page.pageID
Inner Join
cms.content On cms.page_content.contentID = cms.content.contentID
WHERE cms.page.pageID=1
But now it returns nothing.

Related

Hibernate / JPA EntityGraph fetchGraph does not fetch all entities because it is based on an innerjoin

I have a problem with EntityGraph on CriteriaApi. Here is what I am doing:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
EntityGraph<LabelFamily> entityGraph = entityManager.createEntityGraph(LabelFamily.class);
entityGraph.addAttributeNodes("childs");
CriteriaQuery<LabelFamily> criteria = builder.createQuery(LabelFamily.class);
Root<LabelFamily> fromPost = criteria.from(LabelFamily.class);
criteria.select(fromPost);
criteria.where(specification.toPredicate(fromPost, criteria, builder));
return entityManager.createQuery(criteria)
.setHint("javax.persistence.fetchgraph", entityGraph)
.getResultList();
I have some specifications in my criteria that defines an inner join on the "childs" (It's legacy code). Then i want to load every child entity (defined by an OneToMany) in one request, therefore i use EntityGraph.
My problem is this: EntityGraph use the inner join declared in my specifications but it is used to filter the result of the request.
Here is the sql request to better understand the underlying problem:
select distinct labelfamil0_.*,
childs1_.*
from label_family labelfamil0_
inner join label_family childs1_ on labelfamil0_.id = childs1_.family_parent_id
inner join flow flows2_ on childs1_.id = flows2_.label_family_project_id
cross join project project3_
where X
But as we can see the relation childs1_ is filtered through an other inner join.
The result I want is something like this:
select distinct labelfamil0_.*,
childs2_.*
from label_family labelfamil0_
inner join label_family childs2_ on labelfamil0_.id = childs2_.family_parent_id
inner join label_family childs1_ on labelfamil0_.id = childs1_.family_parent_id
inner join flow flows2_ on childs1_.id = flows2_.label_family_project_id
cross join project project3_
where X
I want to filter my "parent" entity using a filter on its child, but then i want all the childs of my resulting parents.
I have the correct result if I do not use an entityGraph and I simply EAGER (or LAZY) fetch the relation.
So if I simply do that:
parent.getChilds()
Without using EntityGraph, I get all childs as I wanted
I am using MySQL 5.7, i do not know if that is of any importance.
Version of Spring: 2.5.8 (I use Hibernate imported from the parent pom)

MySQL create Tables/Views

I don't know if the title is correct but here goes my problem.
So, I want to create View in phpmyadmin using data from several tables (picture below), View that represents maintenance for lamps with fields from several tables (substation, post_type, area, lamp_type, failure and maintenance)
Here are tables with connections:
I've manage somehow and created something like this(picture below), which I managed to create using this block of code:
CREATE OR REPLACE VIEW
v_lamp_I
AS
SELECT
lamps.id,
substation.code AS sub_code,
substation.name AS sub_name,
lamps.lamp_code,
post_type.descript AS post_ty,
lamp_type.descript AS lamp_ty,
area.descript AS area_name,
rasvjeta.adress,
DATE_FORMAT(date_maintenance, "%d.%m.%Y.") AS date_main,
lamps.geo_long,
lamps.geo_lat
FROM lamps
INNER JOIN substiation ON substiation.id = lamps.substiation_id
INNER JOIN post_type ON post_type.id = lamps.post_type_id
INNER JOIN lamp_type ON lamp_type.id = lamps.lamp_type_id
INNER JOIN area ON area.id = rasvjeta.area_id
INNER JOIN maintenance ON maintenance.lamps_id = lamps.id
I've managed to create view but the problem is with that view I can see only rows/lamps(sifra_lampe) which were maintained, only 4. In table lamps
I've 24 entries in and only 4 entries for maintenance.But, I want to see all 24 entries and if there was no maintenance for that particular lamp, field can be empty with date format (00-00-00 or it can be NULL) and for entries/lamps that were maintained I want to be visible date field.
Here is table lamps with entries.
And here is view with maintenance date. As you can see there are only 6 entries
I want to see the rest of the entries, for lamps that were not maintained entries can be null or date format like this (00-00-00) and for lamps that were maintained date format can stay the same, in short I want to see all entries not only those which were maintained. Thank you and sorry for long question. I didn't know how to construct meaningful and short question so wrote everything.
create or replace view
v_lamp_I as
SELECT lamps.id,
substation.code AS sub_code,
substation.name AS sub_name,
lamps.lamp_code,
post_type.descript AS post_ty,
lamp_type.descript AS lamp_ty,
area.descript AS area_name,
rasvjeta.adress,
lamps.geo_long,
lamps.geo_lat
FROM lamps
INNER JOIN substiation ON substiation.id = lamps.substiation_id
INNER JOIN post_type ON post_type.id = lamps.post_type_id
INNER JOIN lamp_type ON lamp_type.id = lamps.lamp_type_id
INNER JOIN area ON area.id = rasvjeta.area_id;
CREATE OR REPLACE VIEW
v_lamp_new
AS
select v_lamp_I.*,DATE_FORMAT(date_maintenance, "%d.%m.%Y.") AS date_main
from v_lamp_I
LEFT JOIN maintenance ON v_lamp_I.id = maintenance.lamps_id;
CREATE OR REPLACE VIEW
v_lamp_I
AS
select tbl_lamp.*,DATE_FORMAT(date_maintenance, "%d.%m.%Y.") AS date_main
from (SELECT lamps.id,
substation.code AS sub_code,
substation.name AS sub_name,
lamps.lamp_code,
post_type.descript AS post_ty,
lamp_type.descript AS lamp_ty,
area.descript AS area_name,
rasvjeta.adress,
lamps.geo_long,
lamps.geo_lat
FROM lamps
INNER JOIN substiation ON substiation.id = lamps.substiation_id
INNER JOIN post_type ON post_type.id = lamps.post_type_id
INNER JOIN lamp_type ON lamp_type.id = lamps.lamp_type_id
INNER JOIN area ON area.id = rasvjeta.area_id) as tbl_lamp
LEFT JOIN maintenance ON tbl_lamp.id = maintenance.lamps_id

Using an alias to form an inner join

I have a problem which I cant figure out, and have looked on google and similar questions on here, but they are just not quite the same.
I am trying to build a MySQL Query which has two parts, the first is easy and i have done this fine, as it uses existing relationships, see...
SELECT
clientsites.SiteName,
clients.ClientName,
pafaddresses.PostTown,
pafaddresses.PostCode,
CONCAT("XXXXXXX", Replace(UPPER(pafaddresses.PostCode),' ','')) AS JouneyKeytemp,
clientsites.SiteType
FROM clientsites
INNER JOIN clients ON clientsites.ClientFk = clients.ClientPk
INNER JOIN pafaddresses ON clients.ActualPAF = pafaddresses.id
You will see from this code that an alias is generated which concats two postcodes and looks like xxxxxxxyyyyyy, this does work but for obvious reasons ive removed the actual postcodes.
What I now what to do is to bring in two fields from an unrelated table called Journeys:
SELECT
JourneyKey,
SingleDistance,
SingleTime
FROM journeys
I want to bring in SingleDistance and SingleTime, where the Journey Key = Generated Alias of JourneyKeyTemp.
I have tried adding the following:
INNER JOIN journeys ON JouneyKeytemp = journeys.JourneyKey
But I just keep getting a syntax error.
Any help would be appreciated.
Repeat the expression in join predicate:
INNER JOIN journeys
ON CONCAT("XXXXXXX", Replace(UPPER(pafaddresses.PostCode),' ','')) = journeys.JourneyKey
Or you can create a subquery:
select * from(
SELECT
clientsites.SiteName,
clients.ClientName,
pafaddresses.PostTown,
pafaddresses.PostCode,
CONCAT("XXXXXXX", Replace(UPPER(pafaddresses.PostCode),' ','')) AS JouneyKeytemp,
clientsites.SiteType
FROM clientsites
INNER JOIN clients ON clientsites.ClientFk = clients.ClientPk
INNER JOIN pafaddresses ON clients.ActualPAF = pafaddresses.id)t
INNER JOIN journeys ON t.JouneyKeytemp = journeys.JourneyKey

MediaWiki 1.16.0 - In phpmyadmin select the current articles

I'm trying to get all articles that are the current/latest articles in Mediawiki 1.16.0. I need to do this in phpMyadmin and make a dump from those results.
my SQL:
SELECT
page.page_title, page.page_latest
, revision.rev_id, revision.rev_text_id
, text.old_id, text.old_text
FROM page, revision, text
WHERE rev_id = page_latest AND rev_text_id = old_id
I get the image names also but not a problem. I feel that this SQL above is not getting the latest version of the articles.
If there is a way to not show image names and redirects in the results it would also help.
First of all please don't use that ugly implicit join syntax. It's confusing and error-prone.
Change it to this:
SELECT
page.page_title, page.page_latest
, revision.rev_id, revision.rev_text_id
, text.old_id, text.old_text
FROM page
INNER JOIN revision ON (rev_id = page_latest)
INNER JOIN text ON (rev_text_id = old_id)
Now you can see why: it's getting all pages. There is no where clause, there are just join clauses.
This is the DB layout: http://upload.wikimedia.org/wikipedia/commons/b/b7/MediaWiki_database_schema_1-17_%28r82044%29.png
And here are the description of the fields in the various tables:
http://www.mediawiki.org/wiki/Manual:Database_layout
Revised query
SELECT
p.page_title, p.page_latest
, MAX(revision.rev_id) as rev_id, revision.rev_text_id
, text.old_id, text.old_text
FROM page p
INNER JOIN revision r ON (r.rev_id = p.page_latest)
INNER JOIN `text` t ON (r.rev_text_id = t.old_id)
WHERE p.page_is_redirect = 0 AND p.page_namespace <> 6 /*NS_IMAGE = 6*/
GROUP BY p.page_latest
ORDER BY p.page_title
This filters out the redirects and excludes the pages where namespace = ns_image.
I'm not 100% sure though 'cause I don't have MediaWiki to test.

MYSQL get other table data in a join

I am currently running this SQL
SELECT jm_recipe.name, jm_recipe.slug
FROM jm_recipe
LEFT JOIN jm_category_recipe ON jm_category_recipe.recipe_id = jm_recipe.id
WHERE jm_category_recipe.category_id = $cat"
This returns the desired results except that I also need to return the name of the category that the recipe I am looking for is in, to do this I tried to add the field in to my SELECT statement and also add the table into the FROM clause,
SELECT jm_recipe.name, jm_recipe.slug, jm_category_name
FROM jm_recipe, jm_category
LEFT JOIN jm_category_recipe ON jm_category_recipe.recipe_id = jm_recipe.id
WHERE jm_category_recipe.category_id = $cat"
However this just returns no results, what am i doing wrong?
You need to join both tables:
SELECT jm_recipe.name, jm_recipe.slug, jm.category_name
FROM jm_recipe
INNER JOIN jm_category_recipe ON jm_category_recipe.recipe_id = jm_recipe.id
INNER JOIN jm_category ON jm_recipe.recipe_id = jm_category.recipe_id
WHERE jm_category_recipe.category_id = $cat
I've changed the joins to inner joins as well. You might want to make them both LEFT joins if you have NULLs and want them in the result.
Also, you're vulnerable to SQL Injection by simply copying over $cat.
Here's some PHP specific info for you (I'm assuming you're using PHP.)