2013-03-02 73 views
3
SELECT Code, Value FROM dbo.Sample 

輸出:添加ROWNUMBER根據提供的值序列

Code  Value 
Alpha Pig 
Beta  Horse 
Charlie Dog 
Delta Cat 
Echo  Fish 

我想通過指定代碼列表基於在中指定的順序上添加一個順序列和排序列表條款。

SELECT Code, Value FROM dbo.Sample 
WHERE Code in ('Beta', 'Echo', 'Alpha') 

我可以在頂部聲明一個變量來指定代碼,如果更容易。

的關鍵是,我想根據我在指定的順序上添加行號

輸出:

Row Code Value 
    1 Beta Horse 
    2 Echo Fish 
    3 Alpha Pig 

編輯:我意識到以後,我的代碼是所有這些都是固定的長度,這對於如何完成它們有很大的不同。我下面標記爲正確的答案,但我的解決方法是使用逗號分隔值的字符串:

DECLARE @CodeList TABLE (Seq int, Code nchar(3)) 
DECLARE @CodeSequence varchar(255) 
DECLARE @ThisCode char(3) 
DECLARE @Codes int 
SET @Codes = 0 

-- string of comma-separated codes 
SET @CodeSequence = 'ZZZ,ABC,FGH,YYY,BBB,CCC' 

----loop through and create index and populate @CodeList 
WHILE @Codes*4 < LEN(@CodeSequence) 
BEGIN 
    SET @ThisCode = SUBSTRING(@CodeSequence,@Codes*4+1,3) 
    SET @Codes = @Codes + 1 
    INSERT @CodeList (Seq, Code) VALUES (@Codes, @ThisCode) 
END 

SELECT Seq, Code from @CodeList 
+1

是選擇不一定會產生那些值訂單w只要單詞列表中的單詞沒有任何子匹配,就沒有ORDER BY – 2013-03-02 01:20:01

回答

4

這裏是唯一的2種方式我見過的準確工作:

第一種使用CHARINDEX(類似於Gordon的,但我認爲在WHERE語句中使用IN更準確):

SELECT * 
FROM Sample 
WHERE Code IN ('Beta','Echo','Alpha') 
ORDER BY CHARINDEX(Code+',','Beta,Echo,Alpha,') 

使用代碼連接逗號應確保子匹配不會影響結果。

或者,你可以使用一個CASE聲明:

SELECT * 
FROM Sample 
WHERE Code in ('Beta','Echo','Alpha') 
ORDER BY CASE 
    WHEN Code = 'Beta' THEN 1 
    WHEN Code = 'Echo' THEN 2 
    WHEN Code = 'Alpha' THEN 3 
END 

SQL Fiddle Demo

Updated Demo與子匹配。

+1

+1 CHARINDEX()的酷訣竅 – 2013-03-02 12:09:53

+0

我應該指定代碼字段都是3個字符並且是唯一的,因爲我可以看到它如何更改結果。也許有更短的做法呢? – kevro 2013-03-04 16:21:20

0

我可能會嘗試做到這一點使用字符串函數:

declare @list varchar(8000) = 'Beta,Echo,Alpha'; 

with Sample as (
    select 'Alpha' as Code, 'Pig' as Value union all 
    select 'Beta', 'Horse' union all 
    select 'Charlie', 'Dog' union all 
    select 'Delta', 'Cat' union all 
    select 'Echo', 'Fish' 
) 
select * from Sample 
where charindex(Code, @list) > 0 
order by charindex(Code, @list) 

如果你是擔心submatches,只是做「分隔符」的把戲:

where @list like '%,'+Code+',%' 
+1

的作用。例如將無法'測試版,回聲,betabeta,阿爾法',但一個聰明的技術。 – 2013-03-02 01:26:10

+0

是的,這非常聰明,應該假設@M​​itchWheat沒有提到可能的子匹配。工作很好。 – gmm 2013-03-02 01:36:46

2

這是任何長度代碼列表的解決方案。 使用自增字段和代碼創建表格。按給定順序插入。加入表格並點擊...

一些細節。請閱讀this。你會發現有函數,從字符串自動遞增字段(用逗號分隔)創建表,即

mysql> call insertEngineer('dinusha,nuwan,nirosh'); 
Query OK, 1 row affected (0.12 sec) 

mysql> select * from engineer; 
+----+----------+ 
| ID | NAME  | 
+----+----------+ 
| 1 | dinusha | 
| 2 | nuwan | 
| 3 | nirosh | 
+----+----------+ 

下一頁加入您的樣品與上述結果表。 GL

+0

我喜歡這個想法,但也許你可以提供示例代碼,包括動態填充臨時表或表變量,以便順序可以變化。 – gmm 2013-03-02 02:07:02

+0

我要試試這個。我喜歡指定數據字段的簡單性,因爲我計劃在測試期間更改字段和順序。謝謝。我想我會修改這個函數來假定一個逗號分隔符來簡化它。 – kevro 2013-03-04 16:18:44

+0

你在Microsoft SQL 2008上試過這個嗎? – kevro 2013-03-04 16:30:58

0

只是對上面做了什麼以包括rownumbers以及改變了一點點。

SELECT CASE 
      WHEN Code = 'BetaBeta' THEN 1 
      WHEN Code = 'Beta' THEN 2 
      WHEN Code = 'Alpha' THEN 3 
     END CodeOrder, 
     * 
FROM Sample 
WHERE Code in ('BetaBeta','Beta','Alpha') 
ORDER BY CodeOrder 

SQL Fiddle Demo

2

您也可以使用值如表源

SELECT Row, Code, Value 
FROM [Sample] s JOIN (  
         SELECT ROW_NUMBER() OVER(ORDER BY(SELECT 1)) AS Row, Match 
         FROM (VALUES ('Beta'), 
            ('Echo'), 
            ('Alpha')) 
         x (Match)        
        ) o ON s.Code = o.Match 
ORDER BY Row 

演示上SQLFiddle

+0

'ORDER BY(SELECT 1)'可以被'ORDER BY 1'(或甚至更好的'ORDER BY 42')代替 – 2013-03-02 12:18:30

+0

@ a_horse_with_no_name thx,但是當我被ORDER BY 1替換時,這給我錯誤5308:窗口函數做不支持整數索引作爲ORDER BY子句表達式。 – 2013-03-02 12:27:51

+0

有趣。我不知道SQL Server不支持這一點(聽起來像是一個bug,因爲SQL標準不允許在該位置按位置列引用)。顯然按常量排序是不允許的('null by null'也不被接受)。 – 2013-03-02 12:33:51