2009-06-03 51 views
3

我們正在改寫我們的CMS的時刻,我們希望我們的客戶能夠使用一個「位置」欄重新排序表格中的內容。所以,如果他們將一個項目標記爲位置1,則它位於頂部,然後位於其下方的位置2等。秩序與空白字段的整數底部

問題是我們不希望他們每次都必須填寫位置,只有在他們想重新排列一些東西,所以位置字段通常是空白的。所以,你可能有以下...

汽車 - 1

自行車 - 2

計算機

這會導致一個問題,因爲如果你使用以下SQL ...

SELECT ProductName FROM Products ORDER BY Position DESC; 

所有的空白部分都是頂部,而不是底部。

可以使用SQL語句將它們置於正確的順序嗎?

+0

David B有正確的答案,按兩個表達式排序。第一個表達式有幾種選擇,「技巧」是將所有非NULL值分組在一起。如果「位置」是數字,則可以輕鬆地爲所有非NULL值生成0,以將它們組合在一起... ORDER BY位置 - 位置DESC,位置DESC – spencer7593 2009-06-03 15:51:55

回答

15
SELECT ProductName 
FROM Products 
ORDER BY 
    CASE WHEN Position is null THEN 1 ELSE 0 END, 
    Position 

如果你想通過位置降序訂購,同時保持空在底部,這將做到這一點:

ORDER BY 
    CASE WHEN Position is null THEN 1 ELSE 0 END, 
    Position desc 

如果你想一致的排序(您可能會分頁),然後加上產品名稱或ProductID最終打破未定位產品之間的所有關係。

ORDER BY 
    CASE WHEN Position is null THEN 1 ELSE 0 END, 
    Position, 
    ProductID 
+0

+1 @David:我認爲這是正確的答案(按兩個表達式排序而不是1)。我唯一看到的是你錯過了DESC關鍵字(來自OP問題)。 – spencer7593 2009-06-03 15:43:47

+0

@David:你沒有錯過DESC關鍵字,我錯了。 (我不能編輯我以前的評論(D'Oh!))我在OP問題中得到了DESC關鍵字的示例SQL,但這不是OP所需要的。如果我絕對堅持使用DESC關鍵字(和I除了我可能喜歡的算術表達式和不必要的湮沒)... ORDER BY位置 - 位置DESC,-1 *位置DESC – spencer7593 2009-06-03 15:58:49

+0

應該有一個圓形的紅色小按鈕,其中有一個x可讓您刪除你自己的意見 – 2009-06-03 16:15:47

2
SELECT ProductName 
FROM Products 
ORDER BY 
     COALESCE(position, (SELECT MAX(position) + 1 FROM Products)) 

或者,你可以使用:

SELECT * 
FROM (
     SELECT ProductName 
     FROM Products 
     WHERE position IS NOT NULL 
     ORDER BY 
       position 
     ) q 
UNION ALL 
SELECT ProductName 
FROM Products 
WHERE position IS NULL 

這將是更有效的,因爲第一子查詢將使用指數position的順序是有一個。

+0

他想按順序排序,而不是描述順序。它應該是(從產品中選擇max(位置)+1),ProductName應該是按標準排列的第二個順序。 – Eric 2009-06-03 13:12:13

0

這應該爲你做這項工作。

CREATE TABLE [dbo].[Test](
    [Position] [int] NULL, 
    [Title] [varchar](15) NULL 
) 
GO 

INSERT INTO Test Values(1, 'P1') 
INSERT INTO Test Values(2, 'P2') 
INSERT INTO Test Values(NULL, 'P3') 
INSERT INTO Test Values(NULL, 'P4') 
INSERT INTO Test Values(NULL, 'P5') 
GO 

SELECT Title + ' - ' + CASE 
    WHEN POSITION IS NULL THEN '' 
    ELSE CAST(Position AS CHAR(3)) 
    END 
FROM Test 
ORDER BY CASE WHEN Position is null THEN 1 ELSE 0 END 
0

只用在必要的時候空值

,你可以很容易地避免使用空值,並將得到的排序問題,通過默認「未設置」行到整數最大值:

  • UPDATE產品SET位置= 2147483647 WHERE位置IS NULL
  • 將列設置爲NOT NULL,添加默認值2147483647
  • 使用ORDER BY按預期在您的應用程序或在您的負載查詢
  • ,抑制2147483647

這裏的任何數值的顯示是一個樣本負載:

SELECT 
    ProductName 
     ,CASE 
      WHEN Position=2147483647 THEN NULL --or cast this as a varchar and use 'N/A' 
      ELSE Position 
     END 
    FROM ... 

如果你必須使用空值,這樣做:

SELECT 
    ProductName 
     ,Position 
    FROM Test 
    ORDER BY COALESCE(Position,2147483647)