查询以回退到不同的列

时间:2015-10-28 14:41:43

标签: sql sql-server sql-server-2008

我有个人表

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以获得最佳性能。

我曾尝试编写各种条件,但无法在此处实现满足我所有要求的查询。任何正确方向的指针对我都有帮助。感谢

注意:如果我的最后一个条件不满足,我甚至会很好(如果在提供的输入后没有人可用,则返回列表中的第一个人)。

2 个答案:

答案 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