I am trying to join two tables while still getting the results from table A even if there is no matching record in table B. I think the where clause is causing the problem but I can't seem to fix it.
SELECT a.id, a.title, a.validation, b.data
FROM client_option_detail AS a LEFT OUTER JOIN client_data AS b
ON a.id = b.client_option_detail_id
WHERE a.client_option_id = ?
AND (b.client_id IS NULL OR b.client_id = ?)
UPDATE:
database layout
client_option client_option_detail
------------- -------------------
id id
title
validation
client_option_id
client client_data
------- ------------
id client_id
client_option_detail_id
data
database sample:
client_option client_option_detail
------------- -------------------------------------------
id id | title | validation | client_option_id
------------- -------------------------------------------
1 1 | test1 | | 1
2 2 | test2 | | 1
3 | test3 | | 1
4 | test4 | | 2
client client_data (primary key - client_id + client_option_detail_id)
-------- -------------------------------------------
id client_id | client_option_detail_id | data
-------- -------------------------------------------
1 1 | 1 | data1
2 1 | 2 | data2
1 | 4 | data3
2 | 3 | data4
2 | 1 | data5
sample query:
SELECT a.id, a.title, a.validation, b.data
FROM client_option_detail AS a LEFT OUTER JOIN client_data AS b
ON a.id = b.client_option_detail_id
WHERE a.client_option_id = 1
AND (b.client_id IS NULL OR b.client_id = 1)
required output:
-------------------------------------------
id | title | validation | data
-------------------------------------------
1 | test1 | | data1
2 | test2 | | data2
3 | test3 | |
SELECT client_option_detail.id, title, validation, data
FROM client_option_detail LEFT OUTER JOIN client_data
ON client_option_detail.id = client_data.client_option_detail_id
It should be okey. I think is your where condition has some problem.
For example : client_option_detail.client_option_id = ?
,? is it contain all the id in client_option_detail ?
You do not need the AND (b.client_id IS NULL OR b.client_id = ?)
SELECT a.id, a.title, a.validation, b.data
FROM client_option_detail AS a
LEFT JOIN client_data AS b
ON a.id = b.client_option_detail_id
WHERE a.client_option_id = ?
output will be something like:
id title validation data
1 foo bar sample_data1
2 apple oranges null
3 try it sample_data2
Like in the sample output number 2, data will be null if there is not matched from table B and information from table A will still be shown
also, if you really wanted to filter based on specified client_id from B, then just put or on the last part like below. It means that if the data contains either specified client_id from B or if it has the specified client_option_id from A, then it will be retrieved.
SELECT a.id, a.title, a.validation, b.data
FROM client_option_detail AS a
LEFT JOIN client_data AS b
ON a.id = b.client_option_detail_id
WHERE a.client_option_id = ? OR b.client_id = ?
for more information, you might want to look at this post
UPDATE:
Try below codes for your update:
SELECT a.id, a.title, a.validation, b.data
FROM client_option_detail AS a
LEFT JOIN client_data AS b
ON a.id = b.client_option_detail_id AND b.client_id = a.client_option_id
WHERE a.client_option_id = 1
or this, i dont know which is right or the one that best suits for your needs but both yields same result based on your sample data:
SELECT a.id, a.title, a.validation, b.data
FROM client_option_detail AS a
LEFT JOIN client_data AS b
ON a.id = b.client_option_detail_id AND b.client_id = 1
WHERE a.client_option_id = 1
tried using SQLize:
I hope I got it right this time. Good luck
Related
I want to ask ..
If i have data but data related in another table
but i want the output is display all data
usually if data related in another table, I using INNER JOIN but the output just data have a relation, if dont have relation, its not display .. IF I using LEFT JOIN or RIGHT JOIN not all data displayed .. IF I using UNION data duplicated
this just example field .. field in real so many
TABLE A
ID | NAMA |
----------------------
1 | Rina |
2 | Deni |
3 | Muti |
4 | Sina |
5 | Sasa |
TABLE B
ID | Rumah |
----------------------
1 | Jabar |
2 | Jateng |
3 | Jatim |
OUTPUT THAT I WANT
ID | NAMA | Rumah
----------------------------------
1 | Rina | Jabar
2 | Deni | Jateng
3 | Muti | Jatim
4 | Sina | -
5 | Sasa | -
short version:
SELECT COALESCE(a.ID, t2.ID),
COALESCE(a.NAMA, '-')
COALESCE(b.Rumah, '-')
FROM TableA a
LEFT JOIN TableB b
ON a.ID = b.ID
RIGHT JOIN TableB t2
ON a.ID = b.ID
If I understand your problem correctly, then a given ID might only have a first or last name, but not both. In this case, simply doing a left or right join will result in the loss of data. One approach here is to do a full outer join between your two tables on the ID, and then use COALESCE to handle possibly missing data appropriately.
SELECT COALESCE(t1.ID, t2.ID) AS ID,
COALESCE(t1.NAMA, '-') AS NAMA,
COALESCE(t2.Rumah, '-') AS Rumah
FROM TableA t1
LEFT JOIN TableB t2
ON t1.ID = t2.ID
UNION
SELECT COALESCE(t1.ID, t2.ID),
COALESCE(t1.NAMA, '-')
COALESCE(t2.Rumah, '-')
FROM TableA t1
RIGHT JOIN TableB t2
ON t1.ID = t2.ID
It should be oh so simple, but perhaps the wine has gone to my head.
Table A (things that need parts)
id | Name | part1 | part2 | part 3 | part 4 | etc
1 | This thing | 1 | 2 | 3 | 2 | etc
2 | another thing | 1 | 1 | 4 | 5 | etc
3 | even more | 11 | 2 | 2 | 2 | etc
Table B (parts)
id | Description
1 | I am a part
2 | I am another Part
3 | Im a very imprtant part
A;; i actually need to do is select all the "parts" that each "thing" needs by its "DESCRIPTION"
so I get a each line in English rather than ID no's
ie
id | Thing name | part 1 | part 2 | part 3 | part 4
1 | This Thing | name of part | name of part | name of part | name of part
Like i said, complete memory overload here and Ive lost the will to live. Any help very gratefull recieved. Thanks in advance.
It will look something like this. Its been a while since I wrote a MySQL query. I am sure somebody could improve on it.
SELECT
a.id,
a.name,
b1.description,
b2.description,
b3.description,
b4.description
FROM
table_a `a`
LEFT JOIN
table_b `b1`
ON a.part1 = b1.id
LEFT JOIN
table_b `b2`
ON a.part2 = b2.id
LEFT JOIN
table_b `b3`
ON a.part3 = b3.id
LEFT JOIN
table_b `b4`
ON a.part4 = b4.id
Your data model has doomed you to complexity from the start.
select
*
from TableA A
left join TableB B1 on A.part1 = B1.id
left join TableB B2 on A.part2 = B1.id
left join TableB B3 on A.part3 = B1.id
left join TableB B4 on A.part4 = B1.id
This is untested, but if you "unpivot" TableA many more possibilities open up.
e.g.
SELECT
A.id
, A.Name
, GROUP_CONCAT(B.Description ORDER BY A.rowno) as PartsList
FROM (
SELECT
A1.id
, A1.Name
, cj.rowno
, CASE
WHEN cj.rowno = 1 THEN part1
WHEN cj.rowno = 2 THEN part2
WHEN cj.rowno = 3 THEN part3
WHEN cj.rowno = 4 THEN part4
END AS LinkID
FROM TableA a1
CROSS JOIN ( 1 AS rowno
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
) cj
) A
LEFT JOIN TableB B ON A.LinkId = B.ID
GROUP BY
A.id
, A.Name
and, if TableA was normalized permanently you would not need these complexities.
I am trying to write a MySQL query to select all rows from table a, as well as information from table b, while also querying the count and sum of values in another table c, for each row of a.
I will try to break that down a bit better, here is a simplified version of my tables:
Table A
+---------+----------+-----------+
| id | name | bid |
+---------+----------+-----------+
| 1 | abc | 1 |
| 2 | def | 1 |
| 3 | ghi | 2 |
+--------------------------------+
Table B
+---------+----------+
| id | name |
+---------+----------+
| 1 | STAN |
| 2 | UCLA |
+--------------------+
Table C
+---------+----------+-----------+
| id | aid | cnumber |
+---------+----------+-----------+
| 1 | 1 | 40 |
| 2 | 1 | 20 |
| 3 | 2 | 10 |
| 4 | 3 | 40 |
| 5 | 3 | 20 |
| 6 | 3 | 10 |
+--------------------------------+
What I need is a query that will return rows containing
a.id | a.name | b.id | b.name | SUM(c.cnumber) | COUNT(c.cnumber)
I am not sure if such a thing is even possible in MySQL.
My current solution is trying to query A + B Left Join and then UNION with A + C Right Join. It's not giving me the results I'm looking for however.
Thanks.
edit:
current query re-written for this problem:
SELECT
a.id,
a.name,
b.id,
b.name
"somecolumn" as dummy_column
"somecolumn1" as dummy_column1
FROM a
LEFT OUTER JOIN b ON a.b.id = b.id
UNION
SELECT
"somecolumn" as dummy_column
"somecolumn1" as dummy_column1
"somecolumn2" as dummy_column2
"somecolumn3" as dummy_column3
COUNT(c.cnumber) AS ccount
SUM(c.cnumber) AS sum
FROM a
RIGHT OUTER JOIN c ON a.id = c.a.id;
Unfortunately MySQL doesn't have FULL OUTER JOIN, and this is my temporary work around, although I don't think it's even the proper idea.
My desired output is all the rows from table A with some info from table B, as well as their totaled inputs in table C.
edit2:
SELECT
a.id,
a.name,
b.id,
SUM(c.cnumber) as totalSum,
(SELECT count(*) FROM c as cc WHERE cc.aid = a.id) as totalCount
FROM
a
LEFT JOIN b ON a.bid = b.id
LEFT JOIN c ON c.aid = a.id;
For future similar questions, solution:
SELECT
a.id AS aid,
a.name,
b.id,
(SELECT SUM(c.rating) FROM c WHERE c.aid = aid) AS totalSum,
(SELECT COUNT(c.rating) FROM c WHERE c.aid = aid) AS totalCount
FROM
a
LEFT JOIN b ON a.bid = b.id;
Your query should be :-
SELECT
a.id,
a.name,
b.id,
(SELECT SUM(c.cnumber) FROM c as cd WHERE cd.aid = a.id) as totalSum,
(SELECT count(*) FROM c as cc WHERE cc.aid = a.id) as totalCount
FROM
a
LEFT JOIN b ON a.bid = b.id
LEFT JOIN c ON c.aid = a.id;
It may help you.
I have tried your example.
SELECT * ,
(SELECT SUM(cnumber) FROM `table_c` WHERE `table_c`.`iaid` = `table_a`.`id`),
(SELECT COUNT(cnumber) FROM `table_c` WHERE `table_c`.`a.id` = `table_a`.`id`)
FROM `table_a`,`table_b` WHERE `table_b`.`id` = `table_a`.`b.id`
i got the Following output.
I have following tables:
A B
id | a | id | b
-------- -------
1 | . | 1 | 1
-------- -------
2 | . | 1 | 2
-------- -------
3 | . | 2 | 1
-------
2 | 2
B.id is a foreign key which references on A.id.
I would like to display A.id, A.a, B.b. But columns from table A should be joined only with the first row from table B which refers to A.id. I also want to select rows from table A which don't have corresponding row in table B.
So the result should looks like this:
A.id | A.a | B.b
----------------
1 | . | 1
----------------
2 | . | 1
----------------
3 | . |
Thanks in advance for any help.
Simply use GROUP BY and LEFT JOIN clauses :
SELECT A.id, A.a, B.b
FROM A
LEFT JOIN B ON B.id = A.id
GROUP BY A.id
ORDER BY A.id ASC
Try this -:
SELECT A.id, A.a, B.b
FROM A
LEFT JOIN (
SELECT b1.id, b1.b
FROM B b1, B b2
WHERE b1.b < b2.b
)B
ON A.id = B.id
GROUP BY A.id
ORDER BY A.id asc
I need a help from mySQL Join tables which should list all users in 'Table A' and also should show flag by matching records in 'Table B'
Table A (users)
=====================
id | name
=====================
1 | aaa
2 | bbb
3 | ccc
4 | ddd
5 | eee
Table B (users_likes)
=====================
like_by | like_to
=====================
1 | 2
1 | 3
2 | 3
4 | 1
5 | 1
if user 'aaa'(id:1) login to the system and performs a search to list all users except his details so the results will be
2 | bbb
3 | ccc
4 | ddd
5 | eee
also he needs to see a flag when listing which shows his 'like_by'
eg:
2 | bbb | (flag:TRUE)
3 | ccc | (flag:TRUE)
4 | ddd | flag:false)
5 | eee | (flag:false)
an easy solution for your problem is to use UNION and few SubQuery(although other solution may exist other than this)
SQLFiddle Demo
SELECT DISTINCT b.id, b.name,'TRUE' AS FLAG
FROM users_likes a
INNER JOIN users b
on a.like_to = b.id
WHERE like_by = 1
UNION
SELECT DISTINCT id, name,'FALSE' AS FLAG
FROM users
WHERE ID NOT IN
(
SELECT DISTINCT b.id
FROM users_likes a
INNER JOIN users b
on a.like_to = b.id
WHERE like_by = 1
)
AND id <> 1
or without using UNION and much simplier solution is the one below.
SQLFiddle Demo
SELECT a.id,
a.name,
IF(COALESCE(b.like_by, -1) = 1, 'TRUE', 'FALSE') AS `Flag`
FROM users a
LEFT JOIN users_Likes b
ON a.id = b.like_to
WHERE a.ID <> 1
GROUP BY a.id
Try this query
select
B.like_to,
BNames.name,
case when B.like_by = 1 then True else False end
from Table_A A
left outer join Table_B B on A.id = B.like_by
left outer join Table_A BNames on B.like_to = BNames.id
where B.like_to <> 1
hope it helps.
I think this is what you're after:
SELECT a.id,a.name,b.like_by IS NOT NULL
FROM users a
LEFT JOIN users_likes b ON (a.id = b.like_to)
GROUP BY a.id
This will give all items of 'a' with 1 where there is a like_to to that a and 0 where there isn't.
(You can add WHERE a.id != 1 to exclude user 1).
Edit:
Changing the third column to be true false based on user 1's likes. I originally thought it was any like.
SELECT a.id,a.username,b.like_by IS NOT NULL
FROM users a
LEFT JOIN user_likes b ON (a.id = b.like_to AND b.like_by = 1)
WHERE a.id != 1
GROUP BY a.id
http://sqlfiddle.com/#!2/ea34d/10