构造针对以下要求的T-SQL查询

时间:2013-04-04 05:21:58

标签: tsql sql-server-2005

ID   Date1   T1   Date2   T2   Date3   T3   Date4   T4
1   DT11     Y    ----------NULL-----------------------  
2   DT11     N    DT22    Y    ----------NULL----------  
3   DT31     N    DT32    Y    DT33    Y    --NULL-----  
4   ----NULL---   DT42    Y    ---NULL---   DT44    Y
5   DT51     Y    ---NULL--    DT53    Y    --NULL-----  

我有一个Table1表格,上面有结构。

要求:

  1. 检查(T1-T5)中哪一个有“Y”
  2. 如果有多个'Y',请比较日期以获取最近的日期
  3. 使用最新日期的日期字段名称或部分名称在新字段中设置值。
  4. 所以,o / p应该是

    ID  Most-recent-Date-Flag
    ---------------------------------------------------    
    1  "Date1 or T1"  -> Since all others are null
    2  "Date2 or T2"  -> T2 has 'Y'
    3  "Date3 or T3"  -> one 'N' and multiple 'Y', DT33 is most recent
    4  "Date4 or T4"  -> multiple 'Y', DT44 is most recent
    5  "Date5 or T5"  -> multiple 'Y', DT53 is most recent
    

    我已设法创建查询以比较日期。它如下:

        SELECT [ID]
        , MAX(UNPIVOT_DATE) AS MOST_RECENT_DATE
        FROM 
        (
        SELECT
        [ID]
        ,[Date1]
        ,[Date2]
        ,[Date3]
        ,[Date4]
        FROM TABLE1
        )SRC_TABLE
        UNPIVOT
        (
        UNPIVOT_DATE
        FOR DATES IN
        (
        [Date1]
        ,[Date2]
        ,[Date3]
        ,[Date4]
        )
        )UNPIVOT_TABLE
        GROUP BY [ID]
    

    我被困在我检查(T1-T4)字段中的'Y'并获得比较后最近日期的列名称的位置。

    希望这个解释有所帮助!

    2013年8月4日
    非常感谢@MarcinJuraszek。有用!!无论如何我还可以传递字段的列名(T1-T4)吗?我尝试了以下操作,但没有用。

    SELECT t.[ID]
    ,MAX(t.Date) as MOST_RECENT_DATE
    --,t.Column_Name 
    FROM
    (
        SELECT [ID]
        ,[Date1] as Date
        ,[T1] as T
    --  ,COL_NAME(OBJECT_ID('Table1'), 2) AS Column_Name 
        FROM Table1
    UNION ALL
        SELECT [ID]
        ,[Date2] as Date 
        ,[T2] as T 
    --    ,COL_NAME(OBJECT_ID('Table1'), 4) AS Column_Name
        FROM Table1
      UNION ALL
        SELECT [ID] 
        ,[Date3] as Date
        ,[T3] as T 
    --    ,COL_NAME(OBJECT_ID('Table1'), 6) AS Column_Name
        FROM Table1
      UNION ALL 
        SELECT [ID]
        ,[Date4] as Date
        ,[T4] as T 
    --    ,COL_NAME(OBJECT_ID('Table1'), 8) AS Column_Name 
        FROM Table1
    ) t
    WHERE t.T = 'Y'
    GROUP BY t.[ID]
    --, t.Column_Name
    ORDER by [ID]
    

3 个答案:

答案 0 :(得分:0)

怎么样:

SELECT t.ID, MAX(t.Date) FROM
  (SELECT ID, Date1 as Date, T1 as T FROM Test
  UNION ALL
    SELECT ID, Date2 as Date, T2 as T FROM Test
  UNION ALL
    SELECT ID, Date3 as Date, T3 as T FROM Test
  UNION ALL 
    SELECT ID, Date4 as Date, T4 as T FROM Test) t
WHERE t.T = 'Y'
GROUP BY t.ID

<强> Simple Demo

答案 1 :(得分:0)

除了GROUP BY + MAX()之外,您还可以使用CROSS APPLY (SELECT TOP 1)。这样您就可以返回其他数据以及最大日期:

SELECT
  t.*,
  x.Date,
  x.FlagName
FROM TABLE1 AS t
CROSS APPLY (
  SELECT TOP 1
    Date,
    FlagName
  FROM (
    SELECT Date1, T1, 'T1' UNION ALL
    SELECT Date2, T2, 'T2' UNION ALL
    SELECT Date3, T3, 'T3' UNION ALL
    SELECT Date4, T4, 'T4' UNION ALL
    SELECT Date5, T5, 'T5'
  ) AS s (Date, T, FlagName)
  WHERE T = 'Y'
  ORDER BY Date
) AS x
;

答案 2 :(得分:0)

我最终得到了以下查询(偶然)并且它起作用.....

  1. 我创建了一个视图,如下所示

    创建视图View_Test为 选择 [ID], 当[T1] ='Y'然后[D1]的情况下,空的结尾为[D1], 当[T2] ='Y'然后[D2]的情况下,null结束为[D2], 当[T3] ='Y'然后[D3]的情况下,null结束为[D3], [T4] ='Y'然后[D4]的情况,否则为[D4] 来自测试

  2. 然后我在一个univot查询中使用了视图,如下所示

    select [ID], max(DATE_FIELD) as most_recent_date, max(Flag) as most_recent_flag
    from View_Test
    unpivot (
    DATE_FIELD for Flag in 
    (
    [D1]
    , [D2]
    , [D3]
    ,[D4]
    )
    ) as DATE_Unpivoted
    group by [ID]
    ORDER BY [ID]
    

    当我执行上述查询时,“max(flag)”为我提供了具有最新日期的日期字段的名称。我仍然不知道它是如何工作的。关于“旗帜”的那一点对我来说仍然是不可理解的。但我偶然把它留在了查询中...从我尝试过但不起作用的其他查询中复制并粘贴:)

    有人可以开导吗? :)