2017-07-19 70 views
1

我有這樣的SQL Server表:如何在SQL Server中以預定義的順序獲取行?

MenuID MenuName   MenuColor 
--------------------------------------- 
10   Daily Tickets  Gray 
15   Kids Ticket  Dark Pink 
20   Group Discount Dark Ash 
11   Discount ticket Brown 
17   Referral Ticket Beige 
22   Frequent visitor Musturd 
27   Annual Pass  sky blue 
25   Kids Pass   Pink 
24   free Ticket  Yellow 

這個表有很多記錄和多個列太..

期望的結果 - 前四個菜單應以預先定義的順序排序(其中我在試用查詢提到)和剩餘應在MENUNAME列排序ASC

所需的結果集:

MenuID MenuName   MenuColor 
--------------------------------------- 
10   Daily Tickets  Gray 
27   Annual Pass  sky blue 
22   Frequent visitor Musturd 
20   Group Discount Dark Ash 
11   Discount ticket Brown 
24   free Ticket  Yellow 
25   Kids Pass   Pink 
15   Kids Ticket  Dark Pink 
17   Referral Ticket Beige 

這是我爲此嘗試的查詢:

SELECT * 
FROM tMenus m 
ORDER BY 
    (CASE m.MenuName 
     WHEN 'Daily Tickets' THEN 1 
     WHEN 'Annual Pass' THEN 2 
     WHEN 'Frequent visitor' THEN 3 
     WHEN 'Group Discount' THEN 4 
     END), m.MenuName ASC; 

但是,這並沒有返回我想要的結果。請糾正我錯在哪裏。

感謝

+2

爲什麼不簡單地添加一個「Dis playOrder「列到表中? –

+0

你的意思是優先嗎?哪一個更推薦解決方案?我需要爲每一行定義優先權? – Lina

+1

我的首選是添加列並設置每一行的值。 1)它使排序正確的一個非常簡單的任務。 2)它有助於在多個查詢中提供一致性(無需繼續反覆查看案例表達式,並且可能將其搞砸)。 3)在查看這些值時,告訴未來發展組織有一個排序偏好。 4)它可以被索引,從而可以消除查詢計劃中的排序操作。 –

回答

4

也許你只需要一個else

ORDER BY (CASE m.MenuName 
      WHEN 'Daily Tickets' THEN 1 
      WHEN 'Annual Pass' THEN 2 
      WHEN 'Frequent visitor' THEN 3 
      WHEN 'Group Discount' THEN 4 
      ELSE 5 
      END) , m.MenuName ASC; 
+0

什麼是5?下一個訂單號? – Lina

+1

「else 5」表示MenuName與任何東西都不匹配.... – granadaCoder

+0

找到了你。有效!!!謝謝 – Lina

1

添加 「DisplayOrder」,以實際的表...

IF OBJECT_ID('tempdb..#Menue', 'U') IS NOT NULL 
DROP TABLE #Menue; 

CREATE TABLE #Menue (
    MenuID INT NOT NULL PRIMARY KEY, 
    MenuName VARCHAR(30) NOT NULL, 
    MenuColor VARCHAR(10) NOT NULL, 
    DisplayOrder INT NOT NULL 
    ); 

INSERT #Menue(MenuID, MenuName, MenuColor, DisplayOrder) VALUES 
    (10,'Daily Tickets', 'Gray', 100), 
    (15,'Kids Ticket', 'Dark Pink', 800), 
    (20,'Group Discount', 'Dark Ash', 400), 
    (11,'Discount ticket', 'Brown', 500), 
    (17,'Referral Ticket', 'Beige', 900), 
    (22,'Frequent visitor', 'Musturd', 300), 
    (27,'Annual Pass', 'sky blue', 200), 
    (25,'Kids Pass', 'Pink', 700), 
    (24,'free Ticket', 'Yellow', 600); 
    -- Note: I'm leaving gaps in the DisplayOrder values. 
    -- This makes it easy to add new values and set their 
    -- values w/o having to adjust existing values. 

SELECT 
    m.MenuID, 
    m.MenuName, 
    m.MenuColor 
FROM 
    #Menue m 
ORDER BY 
    m.DisplayOrder; 

編輯答案...

IF OBJECT_ID('tempdb..#MenueDisplayOrder', 'U') IS NOT NULL 
DROP TABLE #MenueDisplayOrder; 

CREATE TABLE #MenueDisplayOrder (
    MenueID INT NOT NULL, --add FK to Menues table 
    DisplayTypeID INT NOT NULL, --add FK to available Types table 
    DisplayOrder INT NOT NULL 
    PRIMARY KEY CLUSTERED (DisplayTypeID, MenueID) 
    ); 

    INSERT #MenueDisplayOrder (MenueID, DisplayTypeID, DisplayOrder) VALUES 
    (10, 1, 100), (11, 1, 500), (15, 1, 800), (17, 1, 900), (20, 1, 400), 
    (22, 1, 300), (24, 1, 600), (25, 1, 700), (27, 1, 200), 
    (27, 2, 100), (25, 2, 500), (24, 2, 800), (20, 2, 900), (17, 2, 400), 
    (22, 2, 300), (15, 2, 600), (11, 2, 700), (10, 2, 200), 
    (15, 3, 100), (11, 3, 500), (10, 3, 800), (22, 3, 900), (24, 3, 400), 
    (17, 3, 300), (20, 3, 600), (27, 3, 700), (25, 3, 200); 

SELECT 
    m.MenuID, 
    m.MenuName, 
    m.MenuColor 
FROM 
    #Menue m 
    JOIN #MenueDisplayOrder mdo 
     ON m.MenuID = mdo.MenueID 
WHERE 
    mdo.DisplayTypeID = 2 -- alter this value to change the display order. 
ORDER BY 
    mdo.DisplayOrder; 
+0

感謝您爲此付出努力。我有一個疑問,如果我的非預定義組的訂單總是不斷變化,說Asc,說明或命令在其他一些列,如'MenuColor'? – Lina

+1

大家最喜歡的答案,「它取決於」......如果是我,我必須根據不同的用例維護幾種不同的類型,我很可能會創建一個帶有「DisplayType」列的單獨DisplayOrder表。我會用另一個例子更新我的答案... –

+0

Got you ...謝謝。 – Lina