Предположим, у меня есть таблица WorkItems
, в которой есть рабочие элементы, их статус и описание.Есть еще две таблицы Persons
и WorkItemPersonLinks
, в которых содержатся данные о лицах, которым назначены рабочие элементы, и данные о том, какой элемент назначен тому или иному человеку соответственно.Схема выглядит примерно так -
Create table WorkItems
(
Id int not null primary key,
Description varchar (100),
Status varchar (30),
IfValid bit not null,
)
Create table Persons
(
Id int not null primary key,
Name varchar (100),
IfValid bit not null
)
Create table WorkItemPersonLinks
(
Id int not null primary key,
WorkItemId int foreign key references WorkItems(Id),
PersonId int foreign key references Persons(Id),
IfValid bit not null
)
Вот некоторые примеры данных -
insert into workItems values
(1, 'Go Fishing', 'To do', 1),
(2, 'Play video game', 'Done', 1),
(3, 'Cook Dinner', 'In progress', 1),
(4, 'Purchase Groceries', 'Done', 1)
insert into Persons values
(1, 'Tom', 1), (2, 'Dick', 1), (3, 'Harry', 1)
insert into WorkItemPersonLinks values
(1, 1, 1, 1), (2, 2, 2, 1), (3, 3, 3, 1), (4, 4, 2, 1),
(5, 2, 1, 1), (6, 3, 2, 1), (7, 3, 1, 1), (8, 4, 3, 1)
Вот что я хочу, предположим, у меня есть входной параметр @viewOption
, который может принимать возможные значенияmy
(только мои рабочие элементы), done
(все готовые элементы), not done
(рабочие элементы с Status <> 'done'
) и all
(все рабочие элементы) и другой параметр @userId
, который может иметьЗначение int
может быть любым из таблицы Persons
.Итак, предположим, что пользователь (Том) хочет видеть только his
задач, в этом случае @viewOption = 'my'
и @userId = 1
(Идентификатор Тома в таблице Persons
.
ОБНОВЛЕНИЕ
Один рабочий элемент может быть назначен нескольким лицам, поэтому даже если для @viewOption
установлено значение my
, запрос должен возвращать данные других лиц, назначенных этому элементу (кроме пользователя), ине только его собственные данные.
Запрос, с которым мне тяжело работать, как показано ниже -
declare @viewOption varchar(10) = 'my'
declare @userId int = 1
select p.Name, wi.Description, wi.status from WorkItems wi
inner join WorkItemPersonLinks wpl on wi.Id = wpl.WorkItemId
inner join Persons p on wpl.PersonId = p.Id
where wi.IfValid = 1 and wpl.IfValid = 1 and p.IfValid = 1 and ((@viewOption = 'my' and exists(select 1 from wpl where wpl.PersonId = @userId))
or (@viewOption = 'all')
or (@viewOption = 'done' and wi.Status = 'done')
or (@viewOption = 'not done' and wi.Status <> 'done'))
Есть эта ошибка Invalid object name 'wpl
, которая, как я понимаю, возникает из-за контекстаиз условия exists
, где оно недопустимо. Я могу заставить это работать, используя операторы case
над @viewOption
, но хотел дважды проверить лучший (и более элегантный) способ сделать это, прежде чем я сделаю запрос.