我有个人表
CREATE TABLE Person
(
PersonID INT
Name varchar(50),
HireDate datetime,
HireOrder int,
AltOrder int
)
假设我有这样的数据
INSERT INTO Person VALUES(1, 'Rob', '06/02/1988', 0, 0)
INSERT INTO Person VALUES(2, 'Tom', '05/07/2016', 0, 0)
INSERT INTO Person VALUES(3, 'Phil', '01/04/2011', 1, 0)
INSERT INTO Person VALUES(4, 'Cris', '01/04/2011', 2, 0)
INSERT INTO Person VALUES(5, 'Jen', '01/04/2011', 3, 0)
INSERT INTO Person VALUES(6, 'Bill', '01/05/2011', 0, 0)
INSERT INTO Person VALUES(7, 'Ray', '01/23/2012', 0, 0)
我试图简化我的要求...提供HireDate,HireOrder和AltOrder的输入,我需要能够接收下一个人
对于ex:,如果我提供输入,HireDate:06/02/1988,HireOrder:0,AltOrder:0,预期的返回值是" Tom"因为他是提供输入后的下一个人。
对于ex:,如果我提供输入,HireDate:05/07/2016,HireOrder:0,AltOrder:0,预期的返回值是" Phil"因为他是提供输入后的下一个人。尽管Phil和Cris有相同的日期,但他们的HireOrder在这种情况下优先。如果他们也有相同的HireOrder,AltOrder将会出现以确定下一个人
另一个例子:如果我提供输入,HireDate:01/04/2011,HireOrder:1,AltOrder:0,预期的返回值为" Cris"因为她是提供输入后的下一个人。这里的出租人决定。
如果我提供,HireDate:01/23/2012,HireOrder:0,AltOrder:0,因为此后没有人,我应该能够选择名单上的第一个人 - 在这种情况下Rob。< / p>
我可以在前端编写一些业务逻辑,但我认为这样做会很好,如果我可以将它移动到一个存储过程,它可以返回PersonID以获得最佳性能。
我曾尝试编写各种条件,但无法在此处实现满足我所有要求的查询。任何正确方向的指针对我都有帮助。感谢
注意:如果我的最后一个条件不满足,我甚至会很好(如果在提供的输入后没有人可用,则返回列表中的第一个人)。
答案 0 :(得分:1)
这是一个带有相当复杂的where
子句的方法:
select top 1 p.*
from person p
where (p.hiredate > @hiredate) or
(p.hiredate = @hiredate and p.hireorder > @hireorder) or
(p.hiredate = @hiredate and p.hireorder = @hireorder and p.altorder > @altorder)
order by hiredate, hireorder, altorder;
答案 1 :(得分:1)
我同意你的PersonID令人困惑,因为它对每个人来说都是相同的价值,而你认为它应该是主键。如果要将一个人的姓名输入存储过程并返回列表中的下一个人,这应该有效:
declare @SelectedPersonID int -- this would be a parameter in your stored procedure
;WITH CTE AS (
select *
,ROW_NUMBER() OVER (ORDER BY PersonID,HireOrder,AltOrder) AS RN
from Person)
,CTE2 AS (select A.PersonID AS SelectedPersonID,B.*
from CTE A left join CTE B on A.RN + 1 = B.RN)
select PersonID from CTE2 where SelectedPersonID = @SelectedPersonID