问题
I know there is a lot of good questions answered on Left Joins, but I am having trouble finding something pertaining to my particular problem. I apologize for a possible repeated topic, but help would be greatly appreciated.
I have two tables that contain gift card sales. I have to verify that the amounts match. I'm looking for help writing a query that will return everything from TABLE A even if there is no matching record in TABLE B.
TABLE A
| id | business_date | am_pm | gift_cards_sold |
================================================
103 | 2011-10-06 | PM | 175.03
104 | 2011-10-06 | PM | 135.03
105 | 2011-10-06 | PM | 250.74
106 | 2011-10-06 | PM | 180.44
107 | 2011-10-06 | PM | 150.10
108 | 2011-10-06 | PM | 130.00
TABLE B
| id | business_date | am_pm | gift_cards_sold |
================================================
103 | 2011-10-06 | PM | 100.03
105 | 2011-10-06 | PM | 250.74
106 | 2011-10-06 | PM | 180.44
107 | 2011-10-06 | PM | 150.10
Here is my query so far (obviously something wrong with it)
SELECT A.id AS ID, A.gift_cards_sold AS A_SOLD, B.gift_cards_sold AS B_SOLD
FROM A
LEFT JOIN B
USING (id)
WHERE A.am_pm = 'PM'
AND A.business_date = '2011-10-06'
AND B.business_date = '2011-10-06'
GROUP BY A.id
ORDER BY A.id ASC
Here is the result:
| id | A_SOLD | B_SOLD |
========================
103 | 175.03 | 100.03
105 | 250.74 | 250.74
106 | 180.44 | 180.44
107 | 150.10 | 150.10
As you can see, there is a variance with id of 103. However, I need to have the result show every id regardless if there is a match or not. The result set is what I would expect from using an Inner Join.
回答1:
Simply move the B.business_date = '2011-10-06' condition from the WHERE to the ON clause. When you have a LEFT join, a WHERE condition about the second table's columns (except IS (NOT) NULL ones) actually cancels the LEFT JOIN, it then acts as an INNER JOIN.
SELECT A.id AS ID
, A.gift_cards_sold AS A_SOLD
, B.gift_cards_sold AS B_SOLD
FROM A
LEFT JOIN B
ON B.id = A.id
AND B.business_date = '2011-10-06'
WHERE A.am_pm = 'PM'
AND A.business_date = '2011-10-06'
ORDER BY A.id
回答2:
You should use something like this:
SELECT A.id AS ID, A.gift_cards_sold AS A_SOLD, B.gift_cards_sold AS B_SOLD
FROM A
LEFT JOIN B
USING (id)
WHERE A.am_pm = 'PM'
AND A.business_date = '2011-10-06'
AND (B.business_date = '2011-10-06' or B.business_date is null)
GROUP BY A.id
ORDER BY A.id ASC
回答3:
I'm not sure why you were using a "group by" clause - it's not needed here, and in most other databases, would be a syntax error.
I'm assuming that you only need to match the rows on id.
This should work:
select A.id AS ID, A.gift_cards_sold AS A_SOLD, B.gift_cards_sold AS B_SOLD
from A left join b on b.id = a.id
where A.business_date = '2011-10-06'
and A.am_pm = 'PM'
order by a.id
回答4:
Problem is with the where condition for B.business_date, it should also allow null
SELECT A.id AS ID, A.gift_cards_sold AS A_SOLD, B.gift_cards_sold AS B_SOLD
FROM A LEFT JOIN B ON A.id = B.id
WHERE A.am_pm = 'PM'
AND A.business_date = '2011-10-06'
AND (B.business_date = '2011-10-06' OR B.business_date is null )
ORDER BY A.id ASC
来源:https://stackoverflow.com/questions/7680078/mysql-left-join-not-producing-expected-results