2015-10-28 5 views
1

у меня есть человек таблицазапросов падать обратно на разные колонки

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, мне нужно будет подобрать следующего человека

Для примера :, если я предоставляю ввод, HireDate: 06/02/1988, HireOrder: 0, AltOrder: 0, возвращаемое значение ожидаемый «Том», потому что он следующего человека после предоставленного ввода.

Для примера :, если я предоставляю вход, HireDate: 05/07/2016, HireOrder: 0, AltOrder: 0, ожидаемое значение возвращает «Фил», потому что он является следующим человеком после предоставленного ввода. Хотя Фил и Крис имеют одинаковые даты, их HireOrder имеет преимущество в этом случае. Если у них также есть тот же HireOrder, AltOrder будет на картинке, чтобы определить следующего человека

Другой пример: если я предоставляю ввод, HireDate: 01/04/2011, HireOrder: 1, AltOrder: 0, ожидается ожидаемое значение «Крис», потому что она является следующим человеком после предоставленного ввода. Здесь определяется порядок найма.

Если я предоставляю, HireDate: 01/23/2012, HireOrder: 0, AltOrder: 0, так как после этого нет человека, я должен был бы выбрать первого человека в списке - в данном случае Роба.

Я могу написать некоторую бизнес-логику в интерфейсе, но я подумал, что было бы хорошо, если бы я мог переместить это в хранимую процедуру, которая может вернуть мне PersonID для оптимальной производительности.

Я пробовал писать различные условия, но не смог выполнить запрос, который отвечает всем моим требованиям. Любые указатели в правильном направлении были бы полезны для меня. Спасибо

Примечание: Я даже прекрасно, если мое последнее условие не выполнено (возврат первого лица в список, если никто не доступен после предоставленного ввода).

+2

Имея PersonID не является первичным ключом таблицы Person является cnofusing. Все ваши идентификаторы - 1, это то, что вы имели в виду? Кажется, вы представляете, что список имеет неотъемлемый порядок. Таблицы не имеют встроенного порядка в SQL. Если вам нужен заказ, вам нужно сохранить столбец, указывающий этот порядок. – Laurence

+0

Мое копирование/вставка ошибка; измененные идентификаторы; они уникальны – techspider

ответ

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; 
+0

это работает, но не уверен, если он эффективен с точки зрения времени выполнения – techspider

+0

скобки должны быть добавлены для лучшей ясности – techspider

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