2011-03-07 50 views
5

我有一個要求,根據一個整數輸入到一個參數列中排列一個結果集。在一個CASE中按順序排列和不同類型

問題是,我需要爲OrderBy使用CASE,並且它似乎代碼接受case列中的第一個'TYPE'...任何其他類型都會失敗。

我的代碼是這樣的:

WITH error_table AS 
( 
    SELECT Row_Number() OVER 
    (ORDER BY 
     CASE @orderBy 
      WHEN 1 THEN received_date -- Last Rx'd message 
      WHEN 2 THEN message_id -- Message Id 
      WHEN 3 THEN zibmat.short_name -- Message action type 
      WHEN 4 THEN error_action.short_name -- Status type 
      WHEN 5 THEN ime.[allocated_date] -- Allocated Date 
      ELSE received_date 
    END) AS RowNumber 

    ,ime.[ijis_message_error_id] 
     ,ime.[message_id] 
     ,ime.[message_version] 

所以,當排序依據是1,它的工作原理。它按rx_date排序......但是當我發送它爲2時,它會因數據時間轉換錯誤而失敗。

它看起來像所有的類型必須是相同的...

發送5正常工作,因爲這是一個日期時間太長。

有沒有辦法解決這個問題?

+0

「有什麼辦法我可以解決這個問題嗎? 「 - 是的:讓他們都是相同的數據類型 – 2011-03-07 00:44:44

+0

@理查又名cyberkiwi:我意識到這一點。我沒有具體說明任何事情:大概會有適當的填充。我以前用下面的方法解決了這個問題... – 2011-03-07 00:48:29

回答

7

CASE語句必須解析爲只有一種數據類型。這與您知道@orderby將只選擇一個分支並且它將是特定數據類型無關。

你可以使用這樣的東西,這將是笨重的,但將工作。

ORDER BY 
CASE @orderBy WHEN 1 THEN received_date -- Last Rx'd message 
WHEN 2 THEN 0 
WHEN 3 THEN 0 
WHEN 4 THEN 0 
WHEN 5 THEN ime.[allocated_date] -- Allocated Date 
ELSE received_date END, 
CASE @orderBy WHEN 1 THEN 0 
WHEN 2 THEN message_id -- Message Id 
WHEN 3 THEN 0 
WHEN 4 THEN 0 
WHEN 5 THEN 0 
ELSE 0 END, 
CASE @orderBy WHEN 1 THEN '' 
WHEN 2 THEN '' 
WHEN 3 THEN zibmat.short_name -- Message action type 
WHEN 4 THEN error_action.short_name -- Status type 
WHEN 5 THEN '' 
ELSE '' END 
+0

+1:另一種方法是動態SQL,用於動態ORDER BY子句。 – 2011-03-07 00:47:28

+0

+1。這是我以前實施的方式。 – 2011-03-07 00:52:26

+0

這真的很好,謝謝。儘管如此,我明白,如果我們有1個選擇(日期時間類型),它是做什麼的,它是通過recieved_date,0,0,0,絕對排序?如果我們傳入3,它將按0,0,zibmat.short_name,0排序? – Craig 2011-03-07 01:33:15

4

這也似乎工作。

ORDER BY 
     CASE @orderBy 
      WHEN 1 THEN CAST(received_date AS SQL_VARIANT) -- Last Rx'd message 
      WHEN 2 THEN message_id -- Message Id 
      WHEN 3 THEN zibmat.short_name -- Message action type 
      WHEN 4 THEN error_action.short_name -- Status type 
      WHEN 5 THEN ime.[allocated_date] -- Allocated Date 
      ELSE received_date 
    END 

測試用例(intstringdate

DECLARE @P INT = Datepart(SECOND, Getdate())%3; 

SELECT 'Sorting By ' + CASE @P 
      WHEN 1 THEN 'modify_date' 
      WHEN 2 THEN 'object_id' 
      ELSE 'name' 
      END 

SELECT object_id, 
     name, 
     modify_date 
FROM sys.objects 
ORDER BY CASE @P 
      WHEN 1 THEN CAST(modify_date AS SQL_VARIANT) 
      WHEN 2 THEN object_id 
      ELSE name 
      END 
1

我認爲下面一個會更清潔的選項(類似於RichardTheKiwi的做法)

WITH error_table AS 
( 
    SELECT ROW_NUMBER() OVER 
      (
      ORDER BY 
       CASE WHEN @orderBy = 1 THEN received_date END, 
       CASE WHEN @orderBy = 2 THEN message_id END , 
       CASE WHEN @orderBy = 3 THEN zibmat.short_name END, 
       CASE WHEN @orderBy =4 THEN error_action.short_name END, 
       CASE WHEN @orderBy =5 THEN ime.[allocated_date] END 
      ) AS RowNumber 

    ,ime.[ijis_message_error_id] 
    ,ime.[message_id] 
    --..other columns... 
    -- FROM YOURTABLE 
) 
+0

格式化您的代碼 – NoNaMe 2013-01-23 04:52:40

+0

這應該是被接受的... – 2017-06-13 09:45:51