T-SQL Union (различается, не все) и Order by с приоритетом - PullRequest
0 голосов
/ 20 декабря 2018

Предположим, у меня есть таблица Tag (Id int и Name nvarchar(100)) с 3 значениями:

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 появляется дважды, потому что оно верно в обоих случаях).

enter image description here

Вот тогда я думаю, что мне нужно вручную вызвать 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 в обоих утверждениях?

Ответы [ 3 ]

0 голосов
/ 20 декабря 2018

Если по какой-то причине вам нужен этот столбец 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;

db <> fiddle demo

0 голосов
/ 20 декабря 2018

Просто поместите CASE непосредственно в предложение ORDER BY, например:

SELECT
    *
FROM Tag
WHERE name like ( '%' + @keyword + '%' ) 
ORDER BY
    CASE 
        WHEN CHARINDEX(@keyword, T.Name) = 1 THEN 0
        ELSE 1
    END,
    names 
0 голосов
/ 20 декабря 2018

Вам не нужны UNION, которые вы можете использовать

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