4

我有以下代码段:

WHERE (Person.WorkGroupId = 2 or Person.RoleId = 2)

我想要发生的事情是WorkGroupId在 Person 表上返回第一次出现的 2 。但是,如果没有 a 为 2 的人,则选择Person 表中WorkgroupId第一个出现2 的人。RoldId

谢谢

4

3 回答 3

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;
于 2013-08-13T20:35:48.343 回答
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
于 2013-08-13T20:33:37.610 回答
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代表测试编号。

于 2013-08-13T21:07:18.907 回答