让JOIN和WHERE一起工作

时间:2012-03-26 07:52:32

标签: mysql

好的,我有一个包含以下信息和查询的示例表。 首先是数据,最后是问题。

这是SQL Dump: http://pastie.org/private/o7zzajdpm6lzcbqrjolgg

或者您可以使用下面包含的视频:

购买表

|  id   |   brand   |    date     |

    1        b1       2000-01-01 
    2        b1       2000-01-03 
    3        b2       2000-01-04
    4        b3       2000-01-08
    5        b4       2000-01-14

业主表

id | firstname | lastname | purchaseid | itemCoupon | itemReturned | Accessories
 1     Jane        Doe          1           yes           no               4
 2     Jane        Doe          2           yes           no               2 
 3     Jane        Doe          3           no            no               1
 4     Jane        Doe          4           no            no               3
 5     Jane        Doe          5           no            yes              6

查询

SELECT brand, COALESCE( SUM( inTime.Accessories ) , 0 ) AS acessory_sum
FROM purchases
INNER JOIN owners AS person ON person.purchaseid = purchases.id
AND person.firstname =  'Jane'
AND person.lastname =  'Doe'
LEFT JOIN owners AS inTime ON person.id = inTime.id
AND purchases.date
BETWEEN DATE(  '2000-01-01' ) 
AND DATE(  '2000-01-05' ) 
GROUP BY purchases.brand

这给出了以下预期结果:

| brand | accessory_sum
   b1          6
   b2          1
   b3          0
   b4          0

问题

现在,我想添加查询:

WHERE itemCoupon = 'yes' OR itemReturned = 'yes'

但是这会覆盖最后一次加入,当我在上面进行相同的搜索时,我得到:

| brand | accessory_sum
   b1          6
   b2          1

同样,我仍然希望它使用No results found2000-01-042000-01-08返回WHERE itemCoupon = 'yes' OR itemReturned = 'yes'。如果我尝试以另一种方式进行操作,删除WHERE会让所有品牌都为零。

基本上我想保持WHERE的行为方式,但也要保留我在预期输出的第一个例子中描述的格式。

就像现在一样,使用WHERE会破坏上一个LEFT JOINCOALESCE一起使用的方式,该方式用零填充剩余的brand行。

2 个答案:

答案 0 :(得分:0)

执行JOIN时的ON子句与WHERE子句类似。因此,不要尝试使用WHERE,只需在查询中添加另一个AND(并且不要忘记在OR子句中使用括号):

SELECT brand, 
COALESCE(SUM(Time.purchasedAccessories),0) as acessory_sum
FROM purchases 
INNER JOIN owners AS person 
ON person.purchaseid = purchases.id 
AND person.firstname = 'Jane' 
AND person.lastname = 'Doe'

AND (person.itemCoupon = 'yes' OR person.itemReturned = 'yes')

LEFT JOIN owners AS inTime 
ON person.id= inTime.id 
AND purchases.date 
BETWEEN purchases.date 
DATE( '2000-01-01' )
AND 
DATE( '2000-01-05' ) 
GROUP BY purchases.brand

答案 1 :(得分:0)

您的WHERE将外部联接转换为内部联接。

您需要将附加条件移至LEFT JOIN条件:

LEFT JOIN owners as inTime 
       ON person.id = inTime.id 
      AND purchases.date between purchases.date DATE ('2000-01-01') and DATE ('2000-01-05')
      AND (inTime.itemCoupon = 'yes' or inTime.itemReturned = 'yes')