2014-06-04 37 views
0

你怎麼每行返回的多個列的最大數值1:MAX多列的日期?

表名[RefNumber,FirstVisitedDate,SecondVisitedDate,RecoveryDate,ActionDate]

我想要的MAXDATE(FirstVisitedDate,SecondVisitedDate,RecoveryDate,ActionDate)這些日期爲單列中的所有行,並且我希望另一個新列(Acion)依賴於Max日期列,例如:如果Max日期來自FirstVisitedDate,那麼它將是'FirstVisited',或者如果Max日期來自SecondVisitedDate,那麼它將是' SecondVisited'...

總結果喜歡:

選擇RefNumber,MAXDATE,行動從表 組由RefNumber

回答

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子句的順序決定哪一個獲勝。

+0

嗨大衛,感謝您的回覆..一切正常與您的代碼,但我不能做GROUP BY RefNumber ..可以請檢查一次..謝謝 – user3583912

+0

@ user3583912,如果有2行具有相同的'RefNumber',你如何選擇要返回的日期和操作? – David

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

蠻力的方法是不是四列如此糟糕:

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; 
+0

嗨戈登Linoff,感謝您的答覆。但我有9個日期列Maxdate ..以上只是爲了示例..謝謝 – user3583912

+0

@ user3583912。 。 。邏輯對於九列來說並不難,只是很多複製和粘貼。但它確實強調了其他數據庫中「最大()」和「最少()」函數的有用性。 –

+0

我會這樣做..你的權利是那些在Mysql中有用的功能 – user3583912

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