T-SQL联合(不同的,不是全部)和具有优先级的Order by

T-SQL联合(不同的,不是全部)和具有优先级的Order by,sql,sql-server,tsql,sql-order-by,union,Sql,Sql Server,Tsql,Sql Order By,Union,假设我有一个带有3个值的标签表(Id int和Name nvarchar(100)): 1 Software 2 Hardware 3 Warehouse 现在我想用关键字进行查询,并将以关键字开头的查询优先于包含关键字的查询。因此,首先我写下这个查询: SELECT 0 AS SortCol, * FROM Tag T WHERE CHARINDEX(@keyword, T.Name) = 1 UNION SELECT 1 AS SortCol, * FROM Tag T WHERE T

假设我有一个带有3个值的
标签
表(
Id int
Name nvarchar(100)
):

1 Software
2 Hardware
3 Warehouse
现在我想用关键字进行查询,并将以关键字开头的查询优先于包含关键字的查询。因此,首先我写下这个查询:

SELECT 0 AS SortCol, * 
FROM Tag T
WHERE CHARINDEX(@keyword, T.Name) = 1
UNION
SELECT 1 AS SortCol, * 
FROM Tag T
WHERE T.Name LIKE ('%' + @keyword + '%')
ORDER BY SortCol, Name;
但是,这不起作用,因为
SortCol
列不再区分它们(因为
Warehouse
值在这两个字段中都是正确的,所以出现了两次)

这时我想我需要手动调用
DISTINCT
,方法是去掉该列:

SELECT DISTINCT T2.Id, T2.Name
FROM
    (SELECT 0 AS SortCol, * 
     FROM Tag T
     WHERE CHARINDEX(@keyword, T.Name) = 1
     UNION
     SELECT 1 AS SortCol, * 
     FROM Tag T
     WHERE T.Name LIKE ('%' + @keyword + '%')
     ORDER BY SortCol, T.Name) AS T2;
但是,这不起作用,因为我遇到以下错误:

ORDER BY子句在视图、内联函数、派生表、子查询和公共表表达式中无效,除非还指定了TOP、OFFSET或FOR XML


我错过了什么?如何在这两种语句中使用
UNION
ORDER BY

SELECT *
FROM   Tag T
WHERE  T.Name LIKE '%' + @keyword + '%'
ORDER  BY CASE WHEN T.Name LIKE @keyword + '%' THEN 0 ELSE 1 END,
          Name; 

您不需要可以使用的
UNION

SELECT *
FROM   Tag T
WHERE  T.Name LIKE '%' + @keyword + '%'
ORDER  BY CASE WHEN T.Name LIKE @keyword + '%' THEN 0 ELSE 1 END,
          Name; 

如果出于某种原因您需要此
SortCol
列,则可以:

DECLARE @keyword NVARCHAR(MAX) = N'ware';

WITH cte AS (
  SELECT *, ROW_NUMBER() OVER(PARTITION BY Name ORDER BY Name) rn
  FROM (
    SELECT 0 AS SortCol, * 
    FROM Tag T
    WHERE CHARINDEX(@keyword, T.Name) = 1
    UNION
    SELECT 1 AS SortCol, * 
    FROM Tag T
    WHERE T.Name LIKE ('%' + @keyword + '%')) s
)
SELECT SortCol, Id, name
FROM cte
WHERE rn = 1
ORDER BY SortCol, Name;

如果出于某种原因您需要此
SortCol
列,则可以:

DECLARE @keyword NVARCHAR(MAX) = N'ware';

WITH cte AS (
  SELECT *, ROW_NUMBER() OVER(PARTITION BY Name ORDER BY Name) rn
  FROM (
    SELECT 0 AS SortCol, * 
    FROM Tag T
    WHERE CHARINDEX(@keyword, T.Name) = 1
    UNION
    SELECT 1 AS SortCol, * 
    FROM Tag T
    WHERE T.Name LIKE ('%' + @keyword + '%')) s
)
SELECT SortCol, Id, name
FROM cte
WHERE rn = 1
ORDER BY SortCol, Name;

直接在ORDER BY子句中放入一个大小写,如:

SELECT
    *
FROM Tag
WHERE name like ( '%' + @keyword + '%' ) 
ORDER BY
    CASE 
        WHEN CHARINDEX(@keyword, T.Name) = 1 THEN 0
        ELSE 1
    END,
    names 

直接在ORDER BY子句中放入一个案例,如:

SELECT
    *
FROM Tag
WHERE name like ( '%' + @keyword + '%' ) 
ORDER BY
    CASE 
        WHEN CHARINDEX(@keyword, T.Name) = 1 THEN 0
        ELSE 1
    END,
    names 

是的,这就是我需要回答这个问题的情况。当CHARINDEX(@keyword,T.Name)=1,然后0,否则1时,正确的ORDER BY语句应该是
大小写-为什么你认为这比我的更正确
T.Name如@keyword+'%'
没有前导通配符对不起,我的错,没有注意到那里缺少的
%
。令人惊叹的是的,这就是我需要回答这个问题的情况。当CHARINDEX(@keyword,T.Name)=1,然后0,否则1时,正确的ORDER BY语句应该是
大小写-为什么你认为这比我的更正确
T.Name如@keyword+'%'
没有前导通配符对不起,我的错,没有注意到那里缺少的
%
。令人惊叹的谢谢,虽然对于这个特定的案例我不需要它,但我将来可能需要它。谢谢,虽然对于这个特定的案例我不需要它,但我将来可能需要它。