MAX多列的日期?

时间:2014-06-04 23:10:57

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

如何在每行最多几列中返回1个值:

TableName [RefNumber,FirstVisitedDate,SecondVisitedDate,RecoveryDate,ActionDate]

我希望(FirstVisitedDate,SecondVisitedDate,RecoveryDate,ActionDate)的MaxDate为单列中的所有行的这些日期,我希望另一个新列(Acion)依赖于最大日期列ex:如果Max date来自FirstVisitedDate那么它将是'FirstVisited'或者如果Max date来自SecondVisitedDate那么它将是'SecondVisited'......

总结果赞:

选择RefNumber,Maxdate,Action From Table 按RefNumber分组

4 个答案:

答案 0 :(得分:1)

;WITH cte AS (
  -- Build table of date 
  SELECT [RefNumber], 
         [ActionDate]= [FirstVisitedDate], 
         [Action] = 'First Visited' 
  FROM [Table1] 
  UNION ALL
  SELECT [RefNumber], 
         [SecondVisitedDate],  
         'Second Visited' 
  FROM [Table1] 
  UNION ALL
  SELECT [RefNumber], 
         [RecoveryDate], 
         'Recover'
  FROM [Table1]
), cte2 AS (
  -- Add row_number to pull most recent to top
  SELECT  [RefNumber],
          [Action],
          [ActionDate],
          [DateRank] = 
              ROW_NUMBER() OVER (PARTITION BY RefNumber 
                                 ORDER BY [ActionDate] DESC)
  FROM [cte]
)
-- select only the most recent
SELECT * 
FROM cte2 
WHERE [DateRank] = 1

答案 1 :(得分:1)

蛮力方法并非如此糟糕,有四列:

select (case when FirstVisitedDate >= SecondVisitedDate and
                  FirstVisitedDate >= RecoveryDate and
                  FirstVisitedDate >= ActionDate
             then FirstVisitedDate
             when SecondVisitedDate >= RecoveryDate and
                  SecondVisitedDate >= ActionDate
             then SecondVisitedDate 
             when RecoveryDate >= ActionDate
             then RecoveryDate
             else ActionDate
        end),
       (case when FirstVisitedDate >= SecondVisitedDate and
                  FirstVisitedDate >= RecoveryDate and
                  FirstVisitedDate >= ActionDate
             then 'FirstVisitedDate'
             when SecondVisitedDate >= RecoveryDate and
                  SecondVisitedDate >= ActionDate
             then 'SecondVisitedDate'
             when RecoveryDate >= ActionDate
             then 'RecoveryDate'
             else 'ActionDate'
        end)     
from table t;

编辑:

group by中执行此操作只是添加聚合函数的问题:

select RefNumber,
       (case when max(FirstVisitedDate) >= max(SecondVisitedDate) and
                  max(FirstVisitedDate) >= max(RecoveryDate) and
                  max(FirstVisitedDate) >= max(ActionDate)
             then max(FirstVisitedDate
             when max(SecondVisitedDate) >= max(RecoveryDate) and
                  max(SecondVisitedDate) >= max(ActionDate)
             then max(SecondVisitedDate) 
             when max(RecoveryDate) >= max(ActionDate)
             then max(RecoveryDate)
             else max(ActionDate)
        end),
       (case when max(FirstVisitedDate) >= max(SecondVisitedDate) and
                  max(FirstVisitedDate) >= max(RecoveryDate) and
                  max(FirstVisitedDate) >= max(ActionDate)
             then 'FirstVisitedDate'
             when max(SecondVisitedDate) >= max(RecoveryDate) and
                  max(SecondVisitedDate) >= max(ActionDate)
             then 'SecondVisitedDate'
             when max(RecoveryDate) >= max(ActionDate)
             then 'RecoveryDate'
             else 'ActionDate'
        end)     
from table t
group by RefNumber;

答案 2 :(得分:1)

SELECT RecordID, MaxDate
FROM SourceTable
    CROSS APPLY (SELECT MAX(d) MaxDate 
                FROM (VALUES (date1), (date2), (date3), 
                             (date4), (date5), (date6), 
                             (date7)) AS dates(d)) md

答案 3 :(得分:0)

我写了一个自定义函数来执行此操作:

CREATE FUNCTION [dbo].[MaxOf5]
(
    @D1 DateTime,
    @D2 DateTime,
    @D3 DateTime,
    @D4 DateTime,
    @D5 DateTime
)
RETURNS DateTime
AS
BEGIN
    DECLARE @Result DateTime

    SET @Result = COALESCE(@D1, @D2, @D3, @D4, @D5)

    IF @D2 IS NOT NULL AND @D2 > @Result SET @Result = @D2
    IF @D3 IS NOT NULL AND @D3 > @Result SET @Result = @D3
    IF @D4 IS NOT NULL AND @D4 > @Result SET @Result = @D4
    IF @D5 IS NOT NULL AND @D5 > @Result SET @Result = @D5

    RETURN @Result
END

要调用此计算并计算您的Action列,这应该有效:

SELECT
    MaxDate,
    CASE WHEN MaxDate = FirstVisitedDate THEN 'FirstVisited'
       WHEN MaxDate = SecondVisitedDate THEN 'SecondVisited'
       WHEN MaxDate = RecoveryDate THEN 'Recovery'
       WHEN MaxDate = ActionDate THEN 'Action'
    END AS [Action]
FROM (
    SELECT
       RefNumber,
       dbo.MaxOf5(FirstVisitedDate, SecondVisitedDate, RecoveryDate, ActionDate) AS MaxDate,
       FirstVisitedDate, SecondVisitedDate, RecoveryDate, ActionDate
    FROM table
) AS data

请注意,您可以将多个日期与最长日期相关联。在这种情况下,WHEN子句的顺序决定哪一个胜出。