选择n次订购的特定商品

时间:2014-04-11 07:12:52

标签: mysql sql

我有两张桌子,一张发票,另一张是我需要在一个日期范围内选择特定客户n次订购的产品的详细信息

部分表格看起来像这样

发票

invid | custid | invdate
----------------------------
101   | 11     | 2014-2-10
102   | 22     | 2014-2-15
103   | 22     | 2014-3-01
104   | 11     | 2014-3-14

详情

invid | item     
------------
101   | bread   
102   | bread  
103   | chips
104   | chips
102   | bread   
103   | bread  
104   | chips
101   | bread

从上面的代码中,我需要选择说明在2014-2-102014-3-09中订购相同商品2次或更多次的所有客户,不包括购买同一商品的客户周2014-3-102014-3-14

例如

如果客户在date1和date2之间订购bread两次,并且没有在date3和date4之间订购相同的bread那么它应该在输出中

和预期输出的日期应为

custid  | item  | item_count
22      | bread | 2

custid 11不适合列表,因为他们也在2014-3-102014-3-14的一周内购买了,但是他们没有在过去的日期购买相同的商品

这是我试过的

SELECT 
i.custid, d.ITEM,COUNT(d.ITEM) as orders
From `details` d 
LEFT JOIN `invoices` i on i.invid= d.invid 
WHERE 
i.invdate >= '2014-2-10' AND 
i.invdate <= '2014-3-14' AND 
i.custid NOT IN 
(SELECT custid FROM `invoices` WHERE invdate >= '2014-3-10') 
Group By i.invid, d.ITEM 
HAVING COUNT(d.ITEM) >= 2

当我再次运行全表时,我得到1项而不是6项。我通过许多函数手动使用excel来确保,在这种情况下没有

2 个答案:

答案 0 :(得分:4)

典型的MySQL错误。你错误地用invid而不是custid分组。

SELECT 
i.custid, d.ITEM, COUNT(d.ITEM) as orders
From `details` d 
LEFT JOIN `invoices` i on i.invid= d.invid 
WHERE 
i.invdate >= '2014-2-10' AND 
i.invdate <= '2014-3-14' AND 
i.custid NOT IN 
(SELECT custid FROM `invoices` WHERE invdate >= '2014-3-10') 
Group By i.custid, d.ITEM 
HAVING COUNT(d.ITEM) >= 2;

编辑:好的,这是仔细看看它。

  • 如上所述纠正GROUP BY。
  • 您是外部联合发票,但如果没有发票记录,则应该没有详细记录。将其更改为INNER JOIN。
  • 你混淆了约会。购买日期应在2014-2-10和之间。和&#39; 2014-3-09&#39;并且不得介于2014-3-10&#39;到&#39; 2014-3-14&#39;
  • 然后:你不想排除在后一周购买东西的顾客。您想要排除当时发生的客户项目组合。

我的建议:从两个日期范围中选择,然后检查客户项目组合的所有macthes是否在所需的周内且仍然至少有两个:

select 
  i.custid, 
  d.item,
  count(d.item) as orders
from invoices i
inner join details d on d.invid = i.invid
where i.invdate between '2014-2-10' and '2014-3-09' 
   or i.invdate between '2014-3-10' and '2014-3-14'
group by i.custid, d.item 
having count(*) >= 2 and max(i.invdate) between '2014-2-10' and '2014-3-09;

答案 1 :(得分:2)

SELECT    i1.custid, d1.ITEM, COUNT(*) orders
FROM      (invoices i1 JOIN details d1 USING (invid))
LEFT JOIN (invoices i2 JOIN details d2 USING (invid))
       ON i2.custid = i1.custid
      AND d2.ITEM   = d1.ITEM
      AND i2.invdate BETWEEN '2014-03-10' AND '2014-03-14'
WHERE     i1.invdate BETWEEN '2014-02-10' AND '2014-03-09'
      AND i2.custid IS NULL
GROUP BY  i1.custid, d1.ITEM
HAVING    orders >= 2

sqlfiddle上查看。