结合考虑人格等级祖先的夫妇的名字

时间:2017-04-19 09:52:46

标签: sql sql-server tsql

这个可能有点复杂,所以我提供了一个模拟数据:

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

请考虑以下图片: test

以下是我想为夫妇指出的内容:

情侣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

*编辑:以下是我在脚本中包含的查询结果:

result

请帮帮我们。感谢。

1 个答案:

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