I got these 3 tables:
fieldValues|values|formCustomizeValues |
-----------|------|--------------------|
FieldID |ID |FormCustomizeFieldID|
ValueID |Name |FieldID |
| |ValueID |
-----------|------|--------------------|
And the data on these tables looks like this:
fieldValues|values|formCustomizeValues|
-----------|------|-------------------|
4 |1 |1 |
1 |James |4 |
-----------|------|3 |
4 |2 |-------------------|
2 |Ben |
-----------|------|
|3 |
|Daniel|
What i'm trying to do is to get all the values for the specific field.
so lets say i want to grab all the values with the FieldID that equals to 4, i should get:
James
Ben
Daniel
But i tried 5 different queries and the only things i'm getting is or James, Ben or Daniel.
This is the query that returning me zero results:
SELECT v.* FROM `fieldValues` fv
LEFT JOIN `values` v ON fv.ValueID = v.ID
LEFT JOIN formCustomizeValues fcv ON fcv.FieldID = fv.FieldID AND fcv.ValueID = v.ID
WHERE fv.FieldID = 4 AND fcv.FormCustomizeFieldID = 1
And that query returning me only James, Ben:
SELECT v.* FROM `fieldValues` fv
LEFT JOIN `values` v ON fv.ValueID = v.ID
LEFT JOIN formCustomizeValues fcv ON fcv.ValueID = v.ID
WHERE fv.FieldID = 4
How can i get them all together?
Any help will be appreciated!!
Thanks!
Here is SQLfiddle link: http://sqlfiddle.com/#!2/43b56/1
This is what you want :
1 Query to retrieve names via fieldValues
1 Query to retrieve names via formCustomizeValues
Union to join both result
The query :
SELECT
v.`Name`
FROM
`values` v
INNER JOIN `fieldValues` as fv
on v.`ID` = fv.`ValueID`
and fv.`FieldID` = 4
UNION
SELECT
v.`Name`
FROM
`values` v
INNER JOIN `formCustomizeValues` as fcv
on v.`ID` = fcv.`ValueID`
and fcv.`FieldID` = 4
Here the SQLFIDDLE UPDATED
Setting aside any criticisms of the schema design…
SELECT v.name
FROM `values` v
LEFT JOIN `fieldValues` fv ON fv.ValueID = v.ID
LEFT JOIN `formCustomizeValues` fcv ON fcv.ValueID = v.ID
WHERE fv.FieldID = 4
OR fcv.FormCustomizeFieldID = 1
;
Updated Fiddle.
Update
I see now that your first query that you said resulted in no rows was actually pretty close. You want all the rows from values that are defined in either fieldValues or formCustomizeValues. Using AND results in no rows because no row meets both conditions. Therefore you want to use OR or use a UNION as Ryx5 has suggested.
SELECT v.name
FROM `values` v
LEFT JOIN `fieldValues` fv ON fv.ValueID = v.ID
LEFT JOIN `formCustomizeValues` fcv ON fcv.ValueID = v.ID
WHERE fv.FieldID = 4
OR fcv.FormCustomizeFieldID = 1
;
Updated updated Fiddle.
Related
I'm stuck from last few days and really dont know what to do. i have a database with three tables to get the data.I am not able to use rollup with the inner join and order by. i have the following query that returns the result.
SELECT bb_catg.catg_name,
bi_item_name,
sum(bi_item_qty) as TotalQty,
sum(bi_item_total) as Grandtotal
FROM bb_bill_items
inner join bb_items
on bb_bill_items.item_id = bb_items.item_id
inner join bb_catg
on bb_items.catg_id = bb_catg.catg_id
inner join bb_bill
on bb_bill_items.bil_id = bb_bill.bil_id
where dateandtime = '$date' and paymenttype = '$Status'
group by bb_bill_items.item_id
order by bb_catg.catg_name
Result
catg_name | bi_item_name | TotalQty | Grandtotal
------ | ------------ |--------- |-----------
PASTRIES |Cupcake |1 |270
PASTRIES |Eclair |1 |150
PASTRIES |Mousse |1 |350
----------
total |3 |770
Any help will be appreciated.
you can change below query for you solution :
SELECT bb_catg.catg_name,bi_item_name,
sum(bi_item_qty) as TotalQty,sum(bi_item_total) as Grandtotal
FROM bb_bill_items
inner join bb_items
on bb_bill_items.item_id = bb_items.item_id
inner join bb_catg
on bb_items.catg_id = bb_catg.catg_id
inner join bb_bill
on bb_bill_items.bil_id = bb_bill.bil_id
where dateandtime = '$date' and paymenttype = '$Status'
group by bb_catg.catg_name,bb_items.bi_item_name
order by bb_catg.catg_name
Aggregate function with other column you can add in Group By Clause.
Table transport
Id | FirstLevSubcat | SecondLevSubcat | ThirdLevSubcat
--------------------------------------------------------
8 | 4 | 27 | 1418
Table categories
Id | CategoriesUrl
--------------------
4 | cars
27 | audi
1418 | audi-100
Query if not to use categories table (without inner join) would be like
SELECT count(*) FROM transport
WHERE FirstLevSubcat = 4 AND SecondLevSubcat = 27 AND ThirdLevSubcat = 1418
Trying to get the same result using INNER JOIN
SELECT count(*) FROM transport main_table
INNER JOIN categories cat_table_first ON cat_table_first.IdRows = main_table.FirstLevSubcat
INNER JOIN categories cat_table_second ON cat_table_second.IdRows = main_table.SecondLevSubcat
INNER JOIN categories cat_table_third ON cat_table_third.IdRows = main_table.ThirdLevSubcat
WHERE
cat_table_first.CategoriesUrl = 'cars'
AND cat_table_second.CategoriesUrl = 'audi'
AND cat_table_third.CategoriesUrl = 'audi-100'
At first sight all works
But is such query ok? May be can improve something?
Your query is correct. You can also do it in following way:
SELECT count(*) FROM transport main_table
INNER JOIN categories cat_table_first ON cat_table_first.IdRows = main_table.FirstLevSubcat and cat_table_first.CategoriesUrl = 'cars'
INNER JOIN categories cat_table_second ON cat_table_second.IdRows = main_table.SecondLevSubcat and cat_table_second.CategoriesUrl = 'audi'
INNER JOIN categories cat_table_third ON cat_table_third.IdRows = main_table.ThirdLevSubcat and cat_table_third.CategoriesUrl = 'audi-100'
You can also do it using 3 EXISTS block.
SELECT count(*) FROM transport main_table
WHERE
EXISTS (SELECT NULL FROM categories WHERE main_table.FirstLevSubcat=categories.IdRows AND categories.CategoriesUrl ='cars')
AND
EXISTS (SELECT NULL FROM categories WHERE main_table.SecondLevSubcat=categories.IdRows AND categories.CategoriesUrl ='audi')
AND
EXISTS (SELECT NULL FROM categories WHERE main_table.ThirdLevSubcat=categories.IdRows AND categories.CategoriesUrl ='audi-100')
I want to fetch record associated with all values in array. but the problem is, query is fetching record if any one values in IN() is present in db . i want to fetch record ONLY if all values are true.
SELECT J.ID , J.U_POST_ID,
J.TITLE,J.CREATION_DATE,J.STATUS,
R.FIRST_NAME, R.LAST_NAME,R.CLINICAL_CLINIC_NAME,
J.REQUIREMENT,J.STATE,J.CITY,J.DESCRIPTION,
J.CALL_DUR,J.USER_ID
FROM df_job_meta M
LEFT OUTER JOIN df_job_post J ON M.JOB_ID = J.ID
LEFT OUTER JOIN df_register_users R ON R.ID = J.USER_ID
WHERE
J.STATUS='ACTIVE' AND
R.OCCUPATION !='student' AND
J.STATE IN ('Maharashtra') AND
J.CITY IN ('Nagpur') and
M.VALUE IN ('Clinical','Fresher','BDS Intern','Full Time')
table df_job_meta
---------------------------------------------
***VALUE*** | **META_KEY** | JOB_ID
--------------------------------------------
-----------------------------------------
Part Time | work_hour | 103
-------------------------------
BDS Intern |qualification | 103
----------------------------------------
Clinical |profile | 103
----------------------------------------
1 |num_vacancy | 103
----------------------------------------
1 to 3 Years |experience | 103
--------------------------------------
I think you'll need to generate some Dynamic SQL. For the set of coded values you gave:
SELECT J.ID , J.U_POST_ID,
J.TITLE,J.CREATION_DATE,J.STATUS,
R.FIRST_NAME, R.LAST_NAME,R.CLINICAL_CLINIC_NAME,
J.REQUIREMENT,J.STATE,J.CITY,J.DESCRIPTION,
J.CALL_DUR,J.USER_ID
FROM (
SELECT M1.ID
FROM df_job_meta M1
INNER JOIN df_job_meta M2 ON M1.JOB_ID = M2.JOB_ID
INNER JOIN df_job_meta M3 ON M1.JOB_ID = M3.JOB_ID
INNER JOIN df_job_meta M4 ON M1.JOB_ID = M4.JOB_ID
WHERE M1.VALUE = 'Clinical'
AND M2.VALUE = 'Fresher'
AND M3.VALUE = 'BDS Intern'
AND M4.VALUE = 'Full Time'
) as JOBS_MATCHING_META
LEFT OUTER JOIN df_job_post J ON M.JOB_ID = J.ID
LEFT OUTER JOIN df_register_users R ON R.ID = J.USER_ID
WHERE
J.STATUS='ACTIVE' AND
R.OCCUPATION !='student' AND
J.STATE IN ('Maharashtra') AND
J.CITY IN ('Nagpur')
;
(untested)
I would note that looking at your sample data for df_job_meta whether you need to be looking at the META_KEY column too - ie the value is only valid if it's for the right thing, for example
WHERE M1.META_KEY = 'qualification' AND M1.VALUE = 'BDS Intern'
As a final observation, it looks like yuo are trying to implement some form of facetted search; perhaps it might be worth looking at some alternative data stores that implement that directly?
I've got a SELECT with multiple JOINS for a paginated Tableview. In general this is working for unfiltered results.
The query looks like this:
SELECT seltable.*,
tbl2.name AS tbl2name,
tbl3.name AS tbl3name,
tbl4.name AS tbl4name
FROM
( SELECT * FROM selecttable
WHERE value = 99
ORDER BY datetime DESC
LIMIT 50 OFFSET 0 )
AS seltable
LEFT JOIN table1 AS tbl1 ON seltable.tbl1_uid = tbl1.uid
LEFT JOIN table2 AS tbl2 ON tbl1.tbl2_uid = tbl2.uid
LEFT JOIN table3 AS tbl3 ON tbl2.tbl3_uid = tbl3.uid
LEFT JOIN table4 AS tbl4 ON tbl3.tbl4_uid = tbl4.uid;
Now I've got no clue how to accomplish filtering the results with a condition related to one of the join tables.
When I just set a:
LEFT JOIN tablex AS table ON foreign_table.tblx_uid = table.uid AND {condition}
this condition regards only to the 50 results of the nested SELECT.
Is there any way to achieve using WHERE clauses on the JOIN tables in this scenario?
For sample data see http://sqlfiddle.com/#!2/fad4d/2
Expected results:
to get x team records limited to 5 team uids, where Tournament2 is one of the related tournaments for the team.
Best regards
w1ll1
Try not controlling the pagination in that subquery, instead just use a more conventional query with a composite where clause. HOWEVER, because you are using left joins take care adding filters through the where clause that would override the outer join to produce the effect of an inner join.
SELECT seltable.*,
tbl2.name AS tbl2name,
tbl3.name AS tbl3name,
tbl4.name AS tbl4name
FROM selecttable AS seltable
LEFT JOIN table1 AS tbl1 ON seltable.tbl1_uid = tbl1.uid
LEFT JOIN table2 AS tbl2 ON tbl1.tbl2_uid = tbl2.uid
LEFT JOIN table3 AS tbl3 ON tbl2.tbl3_uid = tbl3.uid
LEFT JOIN table4 AS tbl4 ON tbl3.tbl4_uid = tbl4.uid
WHERE seltable.value = 99
...
ORDER BY seltable.datetime DESC
LIMIT 50 OFFSET 0
Alternatively use more subqueries, like this:
SELECT seltable.*,
tbl2.name AS tbl2name,
tbl3.name AS tbl3name,
tbl4.name AS tbl4name
FROM
( SELECT * FROM selecttable
WHERE value = 99
ORDER BY datetime DESC
LIMIT 50 OFFSET 0 )
AS seltable
LEFT JOIN ( SELECT uid, name
FROM table1
WHERE 1=1 -- amend to suit
) AS tbl1 ON seltable.tbl1_uid = tbl1.uid
LEFT JOIN ( SELECT uid, name
FROM table2
WHERE 1=1 -- amend to suit
) AS tbl2 ON tbl1.tbl2_uid = tbl2.uid
LEFT JOIN ( SELECT uid, name
FROM table3
WHERE 1=1 -- amend to suit
) AS tbl3 ON tbl2.tbl3_uid = tbl3.uid
LEFT JOIN ( SELECT uid, name
FROM table4
WHERE 1=1 -- amend to suit
) AS tbl4 ON tbl3.tbl4_uid = tbl4.uid;
Here is another attempt, based on your sqlfiddle it appears that INNER JOINS may be used:
SELECT theteam.*,
trnmnt.name AS tournamentname,
cat.name AS categoryname,
sport.name AS sportname
FROM (
SELECT * FROM team
ORDER BY team.name ASC )
AS theteam
INNER JOIN tournament_team AS tntm ON tntm.team_uid = theteam.uid
INNER JOIN tournament AS trnmnt ON tntm.tournament_uid = trnmnt.uid AND trnmnt.name = 'Tournament2'
INNER JOIN category AS cat ON trnmnt.category_uid = cat.uid
INNER JOIN sport ON cat.sport_uid = sport.uid
LIMIT 5 OFFSET 0
;
The result of that query is:
| UID | NAME | TOURNAMENTNAME | CATEGORYNAME | SPORTNAME |
|-----|--------|----------------|--------------|-----------|
| 2 | Team02 | Tournament2 | Germany | Soccer |
| 3 | Team03 | Tournament2 | Germany | Soccer |
| 4 | Team04 | Tournament2 | Germany | Soccer |
| 5 | Team05 | Tournament2 | Germany | Soccer |
| 6 | Team06 | Tournament2 | Germany | Soccer |
I need to show all categories, even categories with no items.
I have this query.
SELECT
i.id,
incident_active 'Approved',
incident_verified 'Verified',
category_title 'Category',
ParentCategory 'Parent Category'
FROM
incident i
INNER JOIN
incident_category ic ON i.id = ic.incident_id
RIGHT JOIN
incident_person ip ON i.id = ip.incident_id
RIGHT JOIN
(SELECT
c1.id,
c1.parent_id,
c2.category_title ParentCategory,
CONCAT_WS(' -> ', c2.category_title, c1.category_title) category_title
FROM
category c1
left outer join category c2 ON c1.parent_id = c2.id WHERE c1.parent_id != 0) AS c ON c.id = ic.category_id
WHERE incident_dateadd > DATE_SUB(NOW(), INTERVAL 1 MONTH)
which return:
and this query:
SELECT
c1.id,
c1.parent_id,
c2.category_title ParentCategory,
CONCAT_WS(' -> ', c2.category_title, c1.category_title) category_title
FROM
category c1
left outer join category c2 ON c1.parent_id = c2.id WHERE c1.parent_id != 0
which return:
I've read several times this answer but I can not see why my right join isn't working.
The first result set should have 8 more columns, the columns of categories which parent is Protesta
UPDATE
I got it working whith the following query:
SELECT * FROM (SELECT
i.id,
incident_title 'Título',
incident_description 'Descripción',
incident_date 'Fecha',
incident_active 'Aprobado',
incident_verified 'Veficado',
person_first 'Nombres',
person_last 'Apellidos',
person_email 'Email',
category_id
-- category_title 'Categoría',
-- ParentCategory 'Categoría Padre'
FROM
incident i
INNER JOIN
incident_category ic ON i.id = ic.incident_id
RIGHT JOIN
incident_person ip ON i.id = ip.incident_id
WHERE (incident_dateadd > DATE_SUB(NOW(), INTERVAL 1 MONTH) OR incident_dateadd IS NULL)) a
RIGHT JOIN
(SELECT
c1.id,
c1.parent_id,
c2.category_title ParentCategory,
CONCAT_WS(' -> ', c2.category_title, c1.category_title) category_title
FROM
category c1
left outer join category c2 ON c1.parent_id = c2.id WHERE c1.parent_id != 0) b ON a.category_id = b.id
Although I still don't understand why it was not working with the first version, in my mind both queries are equivalent.
If anyone could explain the differences...
It's the location of your final where clause.
In your fist query, you pull all of your categories and associate them with a bunch of data, getting a compilation of rows. You then use a where clause to filter out many of those rows, some of which happen to be category rows.
Let's look at a simple example.
Table A:
X | Y
-----
1 | hi
2 | bye
3 | what
Table B:
Z | X
-----
A | 1
B | 1
C | 2
Given these tables, if I say the following
SELECT * FROM `B` RIGHT JOIN `A` ON A.X = B.X
my result will be:
Z | X | Y
---------
A | 1 | hi
B | 1 | hi
C | 2 | bye
- | 3 | what
If, however, I add a where clause on the end of that so my query becomes
SELECT * FROM `B` RIGHT JOIN `A` ON A.X = B.X WHERE B.Z > 'A'
some of table A is filtered out. Now I have:
Z | X | Y
---------
B | 1 | hi
C | 2 | bye
However, if my query does the filtering before the join, like so:
SELECT * FROM
(SELECT * FROM `B` WHERE B.Z > 'A') AS B
RIGHT JOIN `A` ON A.X = B.X
my table still contains all the rows from A.
Z | X | Y
---------
B | 1 | hi
C | 2 | bye
- | 3 | what
It's just a matter of order. In your original query, you select all the rows then filter out some. In your working query, you first filter, then you get all the category rows you need.