如何根据Case条件和MAX Date获取数据

时间:2016-06-15 10:18:32

标签: sql sql-server sql-server-2008 tsql sql-server-2012

我有一些数据:

Declare @table table (RID VARCHAR(10),
                      CommType INT,
                      CommunicationType INT,
                      VALUE VARCHAR(20),
                      lastDate Datetime)

INSERT INTO @table (RID, CommType, CommunicationType, VALUE, lastDate) 
VALUES 
('00WAAS', 3, 0, 'mohan@gmail', '2012-06-15 15:23:49.653'),
('00WAAS', 3, 1, 'manasa@gmail', '2015-08-15 15:23:49.653'),
('00WAAS', 3, 2, 'mother@gmail', '2014-09-15 15:23:49.653'),
('00WAAS', 3, 2, 'father@gmail', '2016-01-15 15:23:49.653'),
('00WAAS', 3, 0, 'hello@gmail', '2013-01-15 15:23:49.653')

我的查询:

SELECT 
    TT.RID,
    COALESCE(Homemail, BusinessMail, OtherMail) Mail  
FROM 
    (SELECT
         RID, MAX(Homemail) Homemail,
         MAX(BusinessMail) BusinessMail,
         MAX(OtherMail) OtherMail 
     FROM 
         (SELECT
              RID, 
              CASE 
                 WHEN CommType = 3 AND CommunicationType = 0 THEN VALUE 
              END AS Homemail,
              CASE 
                 WHEN CommType = 3 AND CommunicationType = 1 THEN VALUE 
              END AS BusinessMail,
              CASE 
                 WHEN CommType = 3 AND CommunicationType = 2 THEN VALUE 
              END AS OtherMail,
              lastDate
          FROM
              @table) T
      GROUP BY RID) TT

我期待的是什么

这里我需要获得结果CommType = 3 and CommunicationType = 0然后根据最新日期和数据不可用的相关值 CommType = 3且CommunicationType = 0

然后我需要获取CommunicationType = 1的数据 基于最新日期的相关值,如果没有数据 CommunicationType = 1

然后CommunicationType = 2,基于该CommunicationTypes的最新日期。

这里我尝试了Case condition,MAX和Coalesce

如果在CommunicationType = 0中存在组合数据,则根据最新日期获取CommunicationType = 0

如果CommunicationType = 0中不存在组合数据,则根据最新日期

获取CommunicationType = 1

如果CommunicationType = 1中不存在组合数据,则根据最新日期

获取CommunicationType = 2

2 个答案:

答案 0 :(得分:0)

如果我理解正确,请使用ROW_NUMBER()

SELECT tt.RID,COALESCE(tt.Homemail,tt.businessMail,tt.OtherMail) 
FROM(
    select s.RID,
        MAX(CASE WHEN s.CommType = 3 AND s.CommunicationType = 0 THEN s.VALUE END) AS Homemail,
        MAX(CASE WHEN s.CommType = 3 AND s.CommunicationType = 1 THEN s.VALUE END) AS BusinessMail,
        MAX(CASE WHEN s.CommType = 3 AND s.CommunicationType = 2 THEN s.VALUE END) AS OtherMail
     from (SELECT t.*,ROW_NUMBER() OVER(PARTITION BY t.rid,t.communicationType ORDER BY t.lastDate DESC)
           FROM @table t
           WHERE t.commType = 3) s
    WHERE s.rnk = 1
    GROUP BY s.rid) tt

答案 1 :(得分:0)

我不完全确定我已理解这一要求。但我想你想要:

  1. 为每个RID返回一条记录。
  2. 返回的记录的CommType应为3。
  3. 如果有多个CommType 3的记录,您希望记录的CommunicationType最低。
  4. 如果还有多条记录,您希望使用最新的记录lastDate
  5. 此查询使用windowed function ROW_NUMBER对子查询中的可用记录进行排名。 PARTITION BY确保每个RID都是单独排名的。外部查询返回排名为1的所有记录。

    <强>查询

    SELECT
        r.*
    FROM
        (           
            /* For each RID We want the lowest communication type with 
             * the most recent last date.
             */
            SELECT
                ROW_NUMBER() OVER (PARTITION BY RID ORDER BY CommunicationType, lastDate DESC) AS rn,
                *
            FROM
                @table
            WHERE
                CommType = 3
        ) AS r
    WHERE
        r.rn = 1
    ;
    

    后续步骤

    这个查询还可以,但可能更好。例如,如果两个记录匹配CommTypeCommunicationTypelastDate,会发生什么?阅读ROW_NUMBERRANKDENSE_RANKNTILE之间的差异将有助于您在此处找出您的选择。