通过使用where子句中的术语来排序

时间:2013-12-05 22:13:02

标签: sql sql-server

我有一个简单的选择查询 -

SELECT ID, NAME 
FROM PERSONS
WHERE NAME IN ('BBB', 'AAA', 'ZZZ')
-- ORDER BY ???

我希望这个结果按照提供NAMES的顺序排序,即 结果集中的第一行应该是NAME = BBB,第二行是AAA,第三行是ZZZ。

这在SQL服务器中是否可行?如果有一个简单而简单的方法,我想知道该怎么做,比如5-6行代码。

5 个答案:

答案 0 :(得分:3)

您可以创建一个有序的分割函数:

CREATE FUNCTION [dbo].[SplitStrings_Ordered]
(
    @List       NVARCHAR(MAX),
    @Delimiter  NVARCHAR(255)
)
RETURNS TABLE
AS
    RETURN (SELECT [Index] = ROW_NUMBER() OVER (ORDER BY Number), Item 
    FROM (SELECT Number, Item = SUBSTRING(@List, Number, 
      CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number)
     FROM (SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id])
      FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2) AS n(Number)
      WHERE Number <= CONVERT(INT, LEN(@List))
      AND SUBSTRING(@Delimiter + @List, Number, LEN(@Delimiter)) = @Delimiter
    ) AS y);

然后稍微改变你的输入(一个以逗号分隔的列表而不是三个单独的字符串):

SELECT p.ID, p.NAME 
FROM dbo.PERSONS AS p
INNER JOIN dbo.SplitStrings_Ordered('BBB,AAA,ZZZ', ',') AS s
ON p.NAME = s.Item
ORDER BY s.[Index];

答案 1 :(得分:1)

您可以将名称存储在带有订单的临时表中。例如:

DECLARE @Names TABLE (
    Name VARCHAR(MAX),
    SortOrder INT
)

INSERT INTO @Names (Name, SortOrder) VALUES ('BBB', 1)
INSERT INTO @Names (Name, SortOrder) VALUES ('AAA', 2)
INSERT INTO @Names (Name, SortOrder) VALUES ('ZZZ', 3)

SELECT P.ID, P.NAME 
FROM PERSONS P
JOIN @Names N ON P.Name = N.Name
ORDER BY N.SortOrder

答案 2 :(得分:1)

使用IN谓词中的顺序无法执行此操作,但是,您可以创建一个常量表,为常量提供按值排序:

SELECT  p.ID, p.NAME 
FROM    PERSONS p
        INNER JOIN
        (   VALUES
                ('BBB', 1),
                ('AAA', 2),
                ('ZZZ', 3)
        ) t (Name, SortOrder)
            ON p.Name = t.Name
ORDER BY t.SortOrder;

另一个(在我的选项中不太吸引人)解决方案是使用CASE

SELECT  ID, NAME 
FROM    PERSONS
WHERE   NAME IN ('BBB', 'AAA', 'ZZZ')
ORDER BY CASE Name
            WHEN 'BBB' THEN 1
            WHEN 'AAA' THEN 2
            WHEN 'ZZZ' THEN 3
        END;

答案 3 :(得分:0)

SELECT ID, NAME 
FROM PERSONS
WHERE NAME IN ('BBB', 'AAA', 'ZZZ')
ORDER BY CASE 
              WHEN NAME = 'BBB' THEN 1 
              WHEN NAME = 'AAA' THEN 2
              WHEN NAME = 'ZZZ' THEN 3
           END ASC

答案 4 :(得分:0)

我认为这必须奏效:

ORDER BY CASE 
   WHEN NAME = 'BBB' THEN 0 
   WHEN NAME = 'AAA' THEN 1
   WHEN NAME = 'ZZZ' THEN 2
   ELSE 3 
   END ASC