根据MIN和MAX选择值(日期)

时间:2018-03-18 21:40:16

标签: sql sql-server tsql greatest-n-per-group

我正在尝试查询与最近和客户注册最早日期相关的频道类型(邮件,电子市场或网站)。

现在我的查询读取

SELECT CustomerID, MIN(DateAttempt) AS EarliestAttempt, MAX(DateAttempt) AS MostRecentAttempt
FROM EnrollmentAttempt
GROUP BY CustomerID;

它给了我一张显示的表格;

CustomerID                      MostRecentAttempt   EarliestAttempt
094B7C82-12DC-4797-905C-9041752E0975    2018-03-04  2017-12-15
1C1C0DC7-C4D2-4C1B-A9DE-79865700B444    2017-03-09  2017-03-09
60186ED6-DDAF-4D14-BEBB-45AF9CBF0F07    2018-02-12  2015-05-09
A2A1657E-9C79-44E6-98DB-277269965579    2018-03-15  2017-05-01
FE344C8F-8B7A-4FCB-9129-C20127627345    2018-01-04  2016-05-03

我需要在此表中增加2列,在MAX(DateAttempt)上注册的频道类型,以及在MIN(DateAttempt)上注册的频道类型。

表EnrollmentAttempt位于下方;;

Channel       DateAttempt          CustomerID
mail          2017-05-01       A2A1657E-9C79-44E6-98DB-277269965579
mail          2018-02-01       A2A1657E-9C79-44E6-98DB-277269965579
web        2018-03-15      A2A1657E-9C79-44E6-98DB-277269965579
telemarketing   2017-11-02    60186ED6-DDAF-4D14-BEBB-45AF9CBF0F07
web         2018-02-12    60186ED6-DDAF-4D14-BEBB-45AF9CBF0F07
mail           2015-05-09      60186ED6-DDAF-4D14-BEBB-45AF9CBF0F07
telemarketing   2017-03-09     1C1C0DC7-C4D2-4C1B-A9DE-79865700B444
mail            2018-03-04  094B7C82-12DC-4797-905C-9041752E0975
web           2017-12-15    094B7C82-12DC-4797-905C-9041752E0975
telemarketing   2016-05-03  FE344C8F-8B7A-4FCB-9129-C20127627345
mail             2018-01-04 FE344C8F-8B7A-4FCB-9129-C20127627345

3 个答案:

答案 0 :(得分:0)

WITH mx AS (
    SELECT CustomerID, DateAttempt, Channel,
        ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY DateAttempt DESC) AS rn
    FROM EnrollmentAttempt
), mn AS (
    SELECT CustomerID, DateAttempt, Channel,
        ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY DateAttempt) AS rn
    FROM EnrollmentAttempt
)
SELECT *
FROM mx INNER JOIN mn ON mn.CustomerID = mx.CustomerID
WHERE mx.rn = 1 AND mn.rn = 1;

这确实是每组最大的问题。诀窍是你需要做两次并结合结果。

我把两个答案放在一起供你测试。请注意,如果每个日期可能多次尝试,则子查询方法将中断。虽然row_number()方法不会出错,但您获得的结果将是任意的。将通道添加到排序列列表中可能会让您在一天内两次尝试修复该行为,但这不足以处理第三次或更多次尝试。

http://rextester.com/edit/XENM75924

答案 1 :(得分:0)

我不确定这是最好的方法,但它会起作用:

SELECT CustomerID, 
       MIN(DateAttempt) AS EarliestAttempt, 
       MAX(DateAttempt) AS MostRecentAttempt,
       (SELECT Channel FROM EnrollmentAttempt WHERE CustomerID = E.CustomerID AND DateAttempt = (SELECT MIN(DateAttempt) 
                            FROM EnrollmentAttempt 
                            WHERE  CustomerID = E.CustomerID)
       ) AS ChannelMin,
       (SELECT Channel FROM EnrollmentAttempt WHERE CustomerID = E.CustomerID AND DateAttempt = (SELECT MAX(DateAttempt) 
                            FROM EnrollmentAttempt 
                            WHERE  CustomerID = E.CustomerID)
       ) AS ChannelMax
FROM EnrollmentAttempt E
GROUP BY CustomerID;

Fiddle

答案 2 :(得分:0)

我会使用CROSS APPLY来执行此操作,我假设您有一个Customer表。如果不这样做,您仍然可以使用该解决方案,您只需修改即可使用GROUP BYUNIQUE

SELECT c.CustomerID, min.Channel, min.DateAttempt, max.Channel, max.DateAttempt
FROM Customer c
CROSS APPLY (SELECT TOP 1 *
             FROM EnrollmentAttempt
             WHERE CustomerID = c.CustomerID
             ORDER BY DateAttempt ASC) min
CROSS APPLY (SELECT TOP 1 *
             FROM EnrollmentAttempt
             WHERE CustomerID = c.CustomerID
             ORDER BY DateAttempt DESC) max