簡體   English   中英

查詢在一組共同但不連續的日期上進行購買的客戶

[英]Query for customers who have made purchases on a common but discontinuous set of dates

RDMS:PostgreSQL 9.5.3

我有一個以下形式的表('活動'):

customerID | date           | purchaseID
-----------------------------------------
1          | 2016-01-01     | 1
2          | 2016-01-01     | 2
3          | 2016-01-01     | 3
2          | 2016-01-02     | 4
1          | 2016-01-03     | 5
2          | 2016-01-03     | 6
3          | 2016-01-03     | 7
1          | 2016-01-04     | 8
2          | 2016-01-04     | 9
3          | 2016-01-05     | 10

從此表中,我想查找所有在與customerID 1相同的日期進行購買的客戶。客戶購買歷史記錄需要與customerID 1完全重疊,但不一定限於此 - 在日期之外的額外購買是很好,但不應該在最終結果中返回。

以上數據的結果應該是:

customerID | date           | purchaseID
-----------------------------------------
2          | 2016-01-01     | 2
2          | 2016-01-02     | 5
2          | 2016-01-03     | 8

目前,我正在通過應用程序代碼中的循環解決這個問題,然后刪除所有NULL結果,所以實際的SQL是:

SELECT customerID,
       date,
       purchaseID
FROM activity
WHERE customerID <> 1
   AND date = %date%

其中%date%是通過customerID 1購買的所有日期的迭代變量。 這不是一個優雅的解決方案,對於大量購買(數百萬)或客戶(數萬)而言極其緩慢。 歡迎大家提出意見。

謝謝閱讀 -

一種方法是使用自聯接和聚合:

select a.customerid
from activity a join 
     activity a1
     on a1.date = a.date and a1.customerid = 1
where a1.customerid <> a.customerid
group by a.customerID
having count(distinct a1.date) = (select count(distinct date) from activity where customerID = 1)

如果您想要原始記錄,可以使用:

select a.*
from activity a
where a.customerId in (select a.customerid
                       from activity a join 
                            activity a1
                            on a1.date = a.date and a1.customerid = 1
                       where a1.customerid <> a.customerid
                       group by a.customerID
                       having count(distinct a1.date) = (select count(distinct date) from activity where customerID = 1)
                      );

您可以使用“contains” @>數組運算符:

with activity (customerID, date, purchaseID) AS (
  values  (1, '2016-01-01'::date, 1), (2, '2016-01-01', 2), (3, '2016-01-01', 3),
          (2, '2016-01-02', 4), (1, '2016-01-03', 5), (2, '2016-01-03', 6),
          (3, '2016-01-03', 7), (1, '2016-01-04', 8), (2, '2016-01-04', 9),
          (3, '2016-01-05', 10))
select customerID
from activity
group by customerID
having customerID <> 1 AND
       array_agg(date) @> array(select date from activity where customerID = 1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM