ユーザー名のテーブルがあるとしましょう。
Id | Name
-----------
1 | Bobby
20 | Bob
90 | Bob
100 | Joe-Bob
630 | Bobberino
820 | Bob Junior
'Bob'の名前のn
一致のリストを返したいのですが、結果のセットには最初に完全一致が含まれ、次に同様の一致が含まれます。
私はこのようなものがうまくいくかもしれないと思いました
SELECT TOP 4 a.* FROM
(
SELECT * from Usernames WHERE Name = 'Bob'
UNION
SELECT * from Usernames WHERE Name LIKE '%Bob%'
) AS a
しかし、2つの問題があります。
(TOP 4の場合)返されるクエリを探しています
Id | Name
---------
20 | Bob
90 | Bob
(and then 2 results from the LIKE query, e.g. 1 Bobby and 100 Joe-Bob)
これは単一のクエリで可能ですか?
case
を使用して、完全一致を上に配置できます。
select top 4 *
from Usernames
where Name like '%Bob%'
order by
case when Name = 'Bob' then 1 else 2 end
または、パフォーマンスが心配で、(Name)
にインデックスがある場合:
select top 4 *
from (
select 1 as SortOrder
, *
from Usernames
where Name = 'Bob'
union all
select 2
, *
from Usernames
where Name like '%Bob%'
and Name <> 'Bob'
and 4 >
(
select count(*)
from Usernames
where Name = 'Bob'
)
) as SubqueryAlias
order by
SortOrder
元のクエリを少し変更すると、これが解決するはずです。 WHERE Name LIKE 'Bob%'
に一致するUNIONを追加して、この優先度を2にすると、'%Bob'
の優先度を3に変更すると、さらに優れた検索IMHOが得られます。
SELECT TOP 4 a.* FROM
(
SELECT *, 1 AS Priority from Usernames WHERE Name = 'Bob'
UNION
SELECT *, 2 from Usernames WHERE Name LIKE '%Bob%'
) AS a
ORDER BY Priority ASC
SET ROWCOUNT 4
SELECT * from Usernames WHERE Name = 'Bob'
UNION
SELECT * from Usernames WHERE Name LIKE '%Bob%'
SET ROWCOUNt 0
これは私のために働きます:
SELECT TOP 4 * FROM (
SELECT 1 as Rank , I, name FROM Foo WHERE Name = 'Bob'
UNION ALL
SELECT 2 as Rank,i,name FROM Foo WHERE Name LIKE '%Bob%'
) as Q1
ORDER BY Q1.Rank, Q1.I
これにより、パフォーマンスが向上します。
SELECT TOP 4 a.* FROM
(
SELECT TOP 4 *, 1 AS Sort from Usernames WHERE Name = 'Bob'
UNION ALL
SELECT TOP 4 *, 2 AS Sort from Usernames WHERE Name LIKE '%Bob%' and Name <> 'Bob'
) AS a
ORDER BY Sort
Will Aからの回答で私は一線を画しましたが、同じことを実行して「FOR XML PATH」を組み込む場合は、少し異なる方法で記述する必要があるという簡単なメモを追加したいと思います。
私はXML属性を指定していたので、次のようなものがありました。
SELECT Field_1 as [@attr_1]
あなたがしなければならないことは、サブクエリの「@」記号を削除してから、外部クエリでそれらを追加し直すことです。このような:
SELECT top 1 a.SupervisorName as [@SupervisorName]
FROM
(
SELECT (FirstNames + ' ' + LastName) AS [SupervisorName],1 as OrderingVal
FROM ExamSupervisor SupervisorTable1
UNION ALL
SELECT (FirstNames + ' ' + LastName) AS [SupervisorName],2 as OrderingVal
FROM ExamSupervisor SupervisorTable2
) as a
ORDER BY a.OrderingVal ASC
FOR XML PATH('Supervisor')
これは私の最終的なクエリの縮小版であるため、実際には意味がありませんが、アイデアを得る必要があります。