我有以下代码段:
WHERE (Person.WorkGroupId = 2 or Person.RoleId = 2)
我想要发生的是在Person表上返回第一次出现WorkGroupId
为2的情况。但是,如果没有WorkgroupId
为2的人,则在Person表中选择RoldId
为2的第一个匹配项。
由于
答案 0 :(得分:12)
SELECT TOP (1) * FROM
(
SELECT TOP (1) *, o = 1
FROM Person
WHERE WorkGroupId = 2
UNION ALL
SELECT TOP (1) *, o = 2
FROM Person
AND RoleId = 2
) AS x ORDER BY o;
答案 1 :(得分:7)
如果你只使用它,你会得到多条记录。
我会这样做: (有问题的表只扫描一次)
Select top 1 *
From dbo.SomeTable
where WorkGroupId=2 or RoleId=2
Order by case
when WorkGroupId=2 then 1
when RoleId=2 then 2
end
答案 2 :(得分:3)
CREATE TABLE dbo.Person(
PersonID INT IDENTITY(1,1) PRIMARY KEY,
FullName NVARCHAR(100) NOT NULL,
Col1 INT NOT NULL,
WorkGroupId TINYINT NOT NULL,
RoleId TINYINT NOT NULL,
[Priority] AS CONVERT(TINYINT,
CASE
WHEN WorkGroupId=2 THEN 1 -- Priority 1
WHEN RoleId=2 THEN 2 -- Priority 2
ELSE 3 -- Priority 3
END)
);
GO
-- http://technet.microsoft.com/en-us/library/ms189292.aspx
SET NUMERIC_ROUNDABORT OFF;
SET ANSI_NULLS ON;
SET ANSI_PADDING ON;
SET ANSI_WARNINGS ON;
SET ARITHABORT ON;
SET CONCAT_NULL_YIELDS_NULL ON;
SET QUOTED_IDENTIFIER ON;
GO
CREATE INDEX IX_Person_Col1_Priority
ON dbo.Person (Col1,[Priority])
INCLUDE (FullName);
GO
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'A' ,1,1,1);
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'BB' ,1,0,1);
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'CCC' ,1,2,1); -- <--
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'DDDD',1,0,0);
GO
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'X' ,2,1,1);
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'YY' ,2,1,2); -- <--
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'ZZZ',2,1,3);
GO
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'?' ,3,1,1);
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'!!' ,3,2,1); -- <--
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'%%%' ,3,1,2);
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'&&&&',3,1,3);
GO
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'-' ,4,1,1); -- No result
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'--' ,4,1,1); -- No result
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'---' ,4,1,1); -- No result
INSERT dbo.Person (FullName,Col1,WorkGroupId,RoleId) VALUES (N'----',4,1,1); -- No result
GO
SELECT *
FROM(
SELECT p.PersonID,p.FullName,
-- If you have many persons with the same priority then you should use DENSE_RANK
ROW_NUMBER() OVER (ORDER BY p.[Priority]) AS Rnk
FROM dbo.Person p
WHERE p.Col1=1
AND p.[Priority] IN (1,2)
) x
WHERE x.Rnk=1;
SELECT *
FROM(
SELECT p.PersonID,p.FullName,
-- If you have many persons with the same priority then you should use DENSE_RANK
ROW_NUMBER() OVER (ORDER BY p.[Priority]) AS Rnk
FROM dbo.Person p
WHERE p.Col1=2
AND p.[Priority] IN (1,2)
) x
WHERE x.Rnk=1;
SELECT *
FROM(
SELECT p.PersonID,p.FullName,
-- If you have many persons with the same priority then you should use DENSE_RANK
ROW_NUMBER() OVER (ORDER BY p.[Priority]) AS Rnk
FROM dbo.Person p
WHERE p.Col1=3
AND p.[Priority] IN (1,2)
) x
WHERE x.Rnk=1;
SELECT *
FROM(
SELECT p.PersonID,p.FullName,
-- If you have many persons with the same priority then you should use DENSE_RANK
ROW_NUMBER() OVER (ORDER BY p.[Priority]) AS Rnk
FROM dbo.Person p
WHERE p.Col1=4
AND p.[Priority] IN (1,2)
) x
WHERE x.Rnk=1;
结果:
PersonID FullName Rnk
-------- -------- ---
3 CCC 1
PersonID FullName Rnk
-------- -------- ---
6 YY 1
PersonID FullName Rnk
-------- -------- ---
9 !! 1
PersonID FullName Rnk
-------- -------- ---
最后四个陈述的执行计划是:
注意:Col1
代表测试编号。