左连接,返回非匹配行,右表中的where子句,group by

时间:2012-09-01 12:47:32

标签: mysql sql

对于复杂的标题感到抱歉。

我有两张桌子,顾客和订单:

客户 - 名称可能重复,ID是唯一的:

name | cid
 a   |  1
 a   |  2
 b   |  3
 b   |  4
 c   |  5

订单 - pid是唯一的,加入cid:

pid | cid | date
 1  |  1  | 01/01/2012
 2  |  1  | 01/01/2012
 3  |  2  | 01/01/2012
 4  |  3  | 01/01/2012
 5  |  3  | 01/01/2012
 6  |  3  | 01/01/2012

所以我用这段代码来计算:

select customers.name, orders.date, count(*) as count
from customers
left JOIN orders ON customers.cid = orders.cid
where date between '01/01/2012' and '02/02/2012'
group by name,date

虽然工作正常,但是当客户的cid与订单中的cid不匹配时,并没有给我空行,例如name-c,id-5

select customers.name, orders.date, count(*) as count
from customers
left JOIN orders ON customers.cid = orders.cid
AND date between '01/01/2012' and '02/02/2012'
group by name,date

所以我改变了应用于连接的位置,它工作得很好,它给了我空行。 所以在这个例子中我会得到:

name | date       | count
 a   | 01/01/2012 | 3
 b   | null       | 1
 b   | 01/01/2012 | 3
 c   | null       | 1

但是因为名字有不同的cid,所以它给我一个空行,即使名称本身确实有订单行,这是我不想要的。

所以我正在寻找一种方法,只有当共享相同名称的任何其他cid在订单中没有任何行时,才会返回空行。

感谢您的帮助。

--- --- EDIT

我已经编辑了空行的计数,count从不返回null但是1。

的结果
select * from (select customers.name, orders.date, count(*) as count
from customers
left JOIN orders ON customers.cid = orders.cid
AND date between '01/01/2012' and '02/02/2012'
group by name,date) as t1 group by name

name | date       | count
 a   | 01/01/2012 | 3
 b   | null       | 1
 c   | null       | 1

2 个答案:

答案 0 :(得分:3)

首先,选择按(name, date)分组的日期,不包括NULL,然后使用一组不同的名称加入:

SELECT names.name, grouped.date, grouped.count
FROM ( SELECT DISTINCT name FROM customers ) as names
LEFT JOIN (
  SELECT customers.name, orders.date, COUNT(*) as count
  FROM customers
  LEFT JOIN orders ON customers.cid = orders.cid
  WHERE date BETWEEN '01/01/2012' AND '02/02/2012'
  GROUP BY name,date
) grouped
ON names.name = grouped.name

答案 1 :(得分:0)

最好的方法是根据Cid和其他参数将它们组合在一起。 因此,您将获得基于Left Outer Join的NULL值的正确输出。