这个可能有点复杂,所以我提供了一个模拟数据:
declare @SupervisorID uniqueidentifier, @SupervisorNode hierarchyid
create table #Person(
PersonID uniqueidentifier primary key,
FirstName varchar(max),
LastName varchar(max),
EmployedOn datetime,
ID int Identity(1,1) -- this is not a relevant column to the query needed and should not be included
)
create table #PersonOrg (
PersonID uniqueidentifier references #Person(PersonID),
PersonNode hierarchyid
)
create table #PersonRelationship (
PersonID uniqueidentifier references #Person(PersonID),
RelatedPersonID uniqueidentifier,
RelationshipType int --spouse is type 3
)
insert into #Person values
(newid(), 'John', 'Doe', '01/01/2013'),
(newid(), 'Jane', 'Doe', '02/01/2013'), --John Doe's wife
(newid(), 'John', 'Wayne', '01/01/2013'),
(newid(), 'Sherry', 'Wayne', '12/01/2012'), --John Wayne's wife
(newid(), 'Carl', 'Malone', '01/01/2013'),
(newid(), 'Tom', 'No Wife', '01/01/2013'),
(newid(), 'Cherry', 'Irrelevant', '01/01/2013'),
(newid(), 'Jenny', 'Earhart', '01/02/2013'), --Carl Malone's Wife
(newid(), 'Eric', 'Morales', '01/01/2013'),
(newid(), 'Sheldon', 'Marley', '01/01/2013'),
(newid(), 'Supervisor', 'One', '01/01/2013'),
(newid(), 'Supervisor', 'Two', '01/01/2013')
insert into #PersonOrg
select PersonID, '/1/' from #Person where FirstName = 'Supervisor' and LastName = 'One'
insert into #PersonOrg
select PersonID, '/2/' from #Person where FirstName = 'Supervisor' and LastName = 'Two'
INSERT INTO #PersonOrg
Select PersonID, '/1/' + CONVERT(varchar(max), ID) + '/' from #Person
WHERE PersonID not in (select PersonID from #PersonOrg)
AND ID not in (4,8)
INSERT INTO #PersonOrg
Select PersonID, '/2/' + CONVERT(varchar(max), ID) + '/' from #Person
WHERE PersonID not in (select PersonID from #PersonOrg)
ORDER BY ID
--alter table #PersonOrg drop column ID
insert into #PersonRelationship
Select PersonID, newid(), 3 from #Person p --the newid will be replaced with the actual spouse id
WHERE p.PersonID not in (select PersonID from #PersonRelationship)
AND (
(FirstName = 'John' AND LastName = 'Doe') OR
(FirstName = 'John' AND LastName = 'Wayne') OR
(FirstName = 'Carl' AND LastName = 'Malone') OR
(FirstName = 'Jane' AND LastName = 'Doe') OR
(FirstName = 'Sherry' AND LastName = 'Wayne') OR
(FirstName = 'Jenny' AND LastName = 'Earhart')
)
update #PersonRelationship set RelatedPersonID = (SELECT PersonID from #Person where FirstName = 'Jane' and LastName = 'Doe')
WHERE PersonID = (Select PersonID from #Person where FirstName = 'John' and LastName = 'Doe')
update #PersonRelationship set RelatedPersonID = (SELECT PersonID from #Person where FirstName = 'Sherry' and LastName = 'Wayne')
WHERE PersonID = (Select PersonID from #Person where FirstName = 'John' and LastName = 'Wayne')
update #PersonRelationship set RelatedPersonID = (SELECT PersonID from #Person where FirstName = 'Jenny' and LastName = 'Earhart')
WHERE PersonID = (Select PersonID from #Person where FirstName = 'Carl' and LastName = 'Malone')
--
update #PersonRelationship set RelatedPersonID = (SELECT PersonID from #Person where FirstName = 'John' and LastName = 'Doe')
WHERE PersonID = (Select PersonID from #Person where FirstName = 'Jane' and LastName = 'Doe')
update #PersonRelationship set RelatedPersonID = (SELECT PersonID from #Person where FirstName = 'John' and LastName = 'Wayne')
WHERE PersonID = (Select PersonID from #Person where FirstName = 'Sherry' and LastName = 'Wayne')
update #PersonRelationship set RelatedPersonID = (SELECT PersonID from #Person where FirstName = 'Carl' and LastName = 'Malone')
WHERE PersonID = (Select PersonID from #Person where FirstName = 'Jenny' and LastName = 'Earhart')
--alter table #Person drop column ID
set @SupervisorID = (Select PersonID from #Person where FirstName = 'Supervisor' AND LastName = 'One')
set @SupervisorNode = (SELECT PersonNode from #PersonOrg where PersonID = @SupervisorID)
---query goes here
select
p.FirstName + ' ' + p.LastName as Employee, spouse.FirstName + ' ' + spouse.LastName as Spouse, p.EmployedOn as pEmp, spouse.EmployedOn as sEmp, o.PersonNode.GetAncestor(1) as pAncestor, @SupervisorNode as Ancestor, so.PersonNode.GetAncestor(1) as sAncestor,
CASE when spouse.PersonID is not null THEN p.FirstName + ' & ' + spouse.FirstName + ' ' + p.LastName
else p.FirstName + ' ' + p.LastName END as EmployeeName
--spouse.PersonID as SpouseID,
from #Person p
left join #PersonOrg o on p.PersonID = o.PersonID
left join #PersonRelationship pr on p.PersonID = pr.PersonID
left join #Person spouse on pr.RelatedPersonID = spouse.PersonID
left join #PersonOrg so on spouse.PersonID = so.PersonID
WHERE (o.PersonNode.GetAncestor(1) = @SupervisorNode --this is a must
OR so.PersonNode.GetAncestor(1) = @SupervisorNode
)
and (p.EmployedOn < spouse.EmployedOn OR spouse.PersonID is null)
ORDER BY p.ID
drop table #PersonOrg
drop table #PersonRelationship
drop table #Person
以下是我想为夫妇指出的内容:
情侣1:
这里没有棘手的部分,因为他们都在同一个主管下
(pAncestor and sAncestor = Ancestor)
。我们刚刚获得了第一个就业人员。在这种情况下, John Doe 。
所以EmployeeName
应该是 'John&amp; Jane Doe'
情侣2:
请注意,他们有不同的祖先, Sherry Wayne 首先被用于 John Wayne 。但我们只想考虑祖先下的员工。
所以EmployeeName应该是 'John&amp; Sherry Wayne' ,因为 John 是指定主管下的empoloyee,尽管首先雇用了 Sherry 。
情侣3:
不太狡猾,他们只有不同的姓氏。我们只使用第一个使用的姓氏。 EmployeeName应为: 'Carl&amp;珍妮马龙'
正如您在我所包含的示例查询中所注意到的那样,情侣2未标记,因为它显示Sherry & John Wayne
而不是John & Sherry Wayne
。
*编辑:以下是我在脚本中包含的查询结果:
请帮帮我们。感谢。
答案 0 :(得分:1)
我不确定我完全理解你的要求。但我修改了你的查询如下(添加了一个内部CASE):
CASE when spouse.PersonID is not null
THEN CASE WHEN o.PersonNode.GetAncestor(1)= @SupervisorNode THEN p.FirstName + ' & ' + spouse.FirstName + ' ' + p.LastName
ELSE spouse.FirstName + ' & ' + p.FirstName + ' ' + p.LastName
END
else p.FirstName + ' ' + p.LastName END as EmployeeName
或者(在你的评论提供其他规格之后)这个(我只修改了WHERE条件):
select
p.FirstName + ' ' + p.LastName as Employee, spouse.FirstName + ' ' + spouse.LastName as Spouse, p.EmployedOn as pEmp, spouse.EmployedOn as sEmp
, o.PersonNode.GetAncestor(1) as pAncestor, @SupervisorNode as Ancestor, so.PersonNode.GetAncestor(1) as sAncestor,
CASE when spouse.PersonID is not null THEN p.FirstName + ' & ' + spouse.FirstName + ' ' + p.LastName
else p.FirstName + ' ' + p.LastName END as EmployeeName
--spouse.PersonID as SpouseID,
from #Person p
left join #PersonOrg o on p.PersonID = o.PersonID
left join #PersonRelationship pr on p.PersonID = pr.PersonID
left join #Person spouse on pr.RelatedPersonID = spouse.PersonID
left join #PersonOrg so on spouse.PersonID = so.PersonID
WHERE ((o.PersonNode.GetAncestor(1) = @SupervisorNode and (p.EmployedOn < spouse.EmployedOn OR spouse.PersonID is null))
)
OR ( so.PersonNode.GetAncestor(1) <> @SupervisorNode and p.EmployedOn >= spouse.EmployedOn )
ORDER BY p.ID
输出(ometted祖先列):
Employee Spouse pEmp sEmp EmployeeName
---------------------------------------- ---------------------------------------- ----------------------- ----------------------- ----------------------------------------
John Doe Jane Doe 2013-01-01 00:00:00.000 2013-01-02 00:00:00.000 John & Jane Doe
Sherry Wayne John Wayne 2012-01-12 00:00:00.000 2013-01-01 00:00:00.000 John & Sherry Wayne
Carl Malone Jenny Earhart 2013-01-01 00:00:00.000 2013-02-01 00:00:00.000 Carl & Jenny Malone
Tom No Wife NULL 2013-01-01 00:00:00.000 NULL Tom No Wife
Cherry Irrelevant NULL 2013-01-01 00:00:00.000 NULL Cherry Irrelevant
Eric Morales NULL 2013-01-01 00:00:00.000 NULL Eric Morales
Sheldon Marley NULL 2013-01-01 00:00:00.000 NULL Sheldon Marley