如何创建一个包含季度的桌子和本季度没有订购的客户 - MySQL?

时间:2015-09-18 05:54:14

标签: mysql database group-by

我拥有的表基本上是Adventure Works示例数据库中的销售历史表,基本上是salesorderheader (CustomerID, OrderDate, ... )。我想找出那些每个季度都没有订购的客户,我想知道他们没有订购的季度。我可以使用UNION子句以下面的繁琐方式得到答案:

select distinct CustomerID, 1 as quarter
from salesorderheader
where CustomerID not in (select distinct CustomerID 
                         from salesorderheader
                         where quarter(OrderDate) = 1)

union 

select distinct CustomerID, 2 as quarter
from salesorderheader
where CustomerID not in (select distinct CustomerID 
                         from salesorderheader
                         where quarter(OrderDate) = 2)

union

select distinct CustomerID, 3 as quarter
from salesorderheader
where CustomerID not in (select distinct CustomerID 
                         from salesorderheader
                         where quarter(OrderDate) = 3)

union

select distinct CustomerID, 4 as quarter
from salesorderheader
where CustomerID not in (select distinct CustomerID 
                         from salesorderheader
                         where quarter(OrderDate) = 4)
order by CustomerID, quarter;

我可以得到这样的表格:

CustomerID, quarter
19, 1
19, 3
19, 4
26, 3
31, 1

我想知道是否有更好的方法可以做到这一点?

1 个答案:

答案 0 :(得分:0)

您可以使用以下查询:

SELECT t2.CustomerID, t1.`Quarter`
FROM (
  SELECT 1 AS `Quarter` UNION ALL SELECT 2 UNION ALL 
  SELECT 3 UNION ALL SELECT 4
) AS t1
CROSS JOIN (
  SELECT DISTINCT CustomerID
  FROM salesorderheader
) AS t2 
LEFT JOIN (
  SELECT CustomerID, QUARTER(OrderDate) AS `Quarter`
  FROM salesorderheader
) AS t3 ON t2.CustomerID = t3.CustomerID 
           AND t1.`Quarter` = t3.`Quarter`  
WHERE t3.`Quarter` IS NULL
ORDER BY t2.CustomerID

CROSS JOIN派生表t1t2实际上创建了一个包含所有可能的季度和客户ID组合的表。

如果我们使用原始表(即LEFT JOIN)执行此表的salesorderheader,我们可以使用t3.Quarter IS NULL谓词轻松找到缺少哪些组合。

Demo here