在有序集中最后返回NULL值

时间:2014-10-08 13:48:49

标签: sql

我在临时表中有一组值,我想用它来填充三个新列(在下面的MAX(CASE ... END)语句中)。

但是,我发现有时第1列(或第1列和第2列)将包含NULL值,即使第3列有值。

我希望在其他值之后显示的任何NULL值,例如,Col1 = value,Col2 = value,Col3 = NULL

源代码:

 SELECT 
     mc.ID 
    ,mc.Date 
    ,max(case when sv1.row_num = 1 and mc.Date = sv1.Date then sv1.[Col] end) as Col1
    ,max(case when sv1.row_num = 2 and mc.Date = sv1.Date then sv1.[Col] end) as Col2
    ,max(case when sv1.row_num = 3 and mc.Date = sv1.Date then sv1.[Col] end) as Col3
INTO #Total7
FROM  
    #MyTable3 as mc  
     join
      (
        select 
            #MyTable3.*,
            row_number() OVER (PARTITION BY [ID] ORDER BY [Date]) as row_num
        from #MyTable3 
      )as sv1 on 
        mc.ID = sv1.ID 
GROUP BY 
    mc.ID
    ,mc.Date

SELECT * 
FROM #Total7
ORDER BY ID, Date

2 个答案:

答案 0 :(得分:0)

您的值按此顺序显示,因为NULL is always the first value returned by an ORDER BY,这就是您在ROW_NUMBER()函数中使用的对记录进行排序(确定值是否属于Col1,Col2或Col3)的内容。将您的查询更改为:

SELECT 
     mc.ID 
    ,mc.Date 
    ,max(case when sv1.row_num = 1 and mc.Date = sv1.Date then sv1.[Col] end) as Col1
    ,max(case when sv1.row_num = 2 and mc.Date = sv1.Date then sv1.[Col] end) as Col2
    ,max(case when sv1.row_num = 3 and mc.Date = sv1.Date then sv1.[Col] end) as Col3
INTO #Total7
FROM  
    #MyTable3 as mc  
     join
      (
        select 
            #MyTable3.*,
            ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY ISNULL([Date], '12/31/9999')) as row_num
        from #MyTable3 
      )as sv1 on 
        mc.ID = sv1.ID 
GROUP BY 
    mc.ID
    ,mc.Date

SELECT * 
FROM #Total7
ORDER BY ID, Date

如果ISNULL()字段为空,[Date]函数将返回远期的日期。因此,任何“真实”日期都会显示第一行数值,任何NULL日期将显示在最后。

或者,如果您不喜欢ISNULL(),则可以使用CASE声明,即

    ROW_NUMBER() OVER 
      (
        PARTITION BY [ID] 
        ORDER BY 
            CASE WHEN [Date] IS NULL THEN 1 ELSE 0 END,
            [Date]
      ) as row_num

答案 1 :(得分:0)

为您的加入查询添加日期。

     SELECT 
         mc.ID 
        ,mc.Date 
        ,max(case when sv1.row_num = 1 and mc.Date = sv1.Date then sv1.[Col] end) as Col1
        ,max(case when sv1.row_num = 2 and mc.Date = sv1.Date then sv1.[Col] end) as Col2
        ,max(case when sv1.row_num = 3 and mc.Date = sv1.Date then sv1.[Col] end) as Col3
    INTO #Total7
    FROM  
        #MyTable3 as mc  
         join
          (
            select 
                #MyTable3.*,
                row_number() OVER (PARTITION BY [ID] ORDER BY [Date]) as row_num
            from #MyTable3 
          )as sv1 on 
            mc.ID = sv1.ID 
            and mc.Date = sv1.Date
    GROUP BY 
        mc.ID
        ,mc.Date

    SELECT * 
    FROM #Total7
    ORDER BY ID, Date