首先,这不是我同名的其他问题的重复,我只是想不出这个更好的名字!
我有一个名为Player的SQL表,另一个名为Unit。
所以它可能是(自上而下)......
我的问题是,如果我获得了玩家的PlayerID(该表的PK),那么获得特定团队的最佳方式是什么?
请参阅我的SQLFiddle获取数据,结构和查询:http://sqlfiddle.com/#!3/78965/3
凭借我的数据(来自小提琴),我希望能够让每个玩家都获得“TeamB”,但是“Player4”的顶级单位应该是“TeamC”。为了做到这一点,我要传递的是PlayerID和“TeamB”的ID。所以我说“让所有玩家和顶级单位在TeamB下,然后过滤掉所有玩家除了玩家4。”
编辑:我认为上面的段落应该是: 使用我的数据(来自小提琴),我希望能够建立一个顶级的团队在“TeamB”下面。对于“TeamB”下面的每个顶级球队,我都希望建立所有参加或低于该球队的球员。然后,我希望能够将玩家列表限制为一个或多个特定玩家。
正如你在SQLFiddle中看到的那样,我为每个玩家找回了多行,我确信它是一个快速解决方案,但我无法弄明白......这就是我在小提琴中的目的,但是它,嗯,有点繁琐...... :)。
编辑:更多信息:
好的,所以如果想象这是一个存储过程。
我希望返回的数据看起来像
Player3, TeamC
只返回Player3,因为它是唯一一个作为TeamB(ID 2)后代的玩家,并返回TeamC,因为它是Player3所属的最高级别单元(低于UnitID 2)。
如果我改为通过:
我希望
Player1, Team2
Player2, Team2
答案 0 :(得分:2)
with UnitCTE as (
select UnitID,
Designation,
ParentUnitID as ParentUnitID,
cast(null as varchar(50)) as ParentUnitDesignation,
UnitID TopUnitID,
Designation TopUnitDesignation,
1 as TeamLevel
from Unit
where ParentUnitID is null
union all
select t.UnitID,
t.Designation,
c.UnitID,
c.Designation,
c.TopUnitID,
c.TopUnitDesignation,
TeamLevel+1 as TeamLevel
from Unit t
join UnitCTE c
on t.ParentUnitID = c.UnitID
--WHERE t.UnitID = 1
),
x AS (
select Player.PlayerID,
pDesignation = Player.Designation, t1.*,
rn = ROW_NUMBER() OVER (PARTITION BY Player.PlayerID ORDER BY Player.Designation)
from Player
join UnitCTE t1
on Player.UnitID = t1.UnitID
join UnitCTE t2
on t1.TopUnitID = t2.TopUnitID
and t2.TeamLevel=2
)
SELECT * FROM x
WHERE rn = 1
ORDER BY TeamLevel
答案 1 :(得分:2)
此答案已完全重写。原件在所有情况下都不起作用
我必须更改CTE以表示每个单元的完整单元层次结构作为可能的根(顶部单元)。它允许每个单元有多个子项的真正层次结构。
我扩展了此SQL Fiddle中的示例数据,以便将一个玩家分配给单元11和12.它正确地为单元1下某个级别的单元播放的3个玩家中的每个玩家返回正确的行。
“root”单元ID和玩家ID列表位于底部最外面的WHERE子句中,可以根据需要轻松更改ID。
with UnitCTE as (
select u.UnitID,
u.Designation UnitDesignation,
u.ParentUnitID as ParentUnitID,
p.Designation as ParentUnitDesignation,
u.UnitID TopUnitID,
u.Designation TopUnitDesignation,
1 as TeamLevel
from Unit u
left outer join Unit p
on u.ParentUnitId = p.UnitID
union all
select t.UnitID,
t.Designation UnitDesignation,
c.UnitID as ParentUnitID,
c.UnitDesignation as ParentUnitDesignation,
c.TopUnitID,
c.TopUnitDesignation,
TeamLevel+1 as TeamLevel
from Unit t
join UnitCTE c
on t.ParentUnitID = c.UnitID
)
select p.PlayerID,
p.Designation,
t1.*
from UnitCTE t1
join UnitCTE t2
on t2.TopUnitID = t1.UnitID
and t2.TopUnitID = t1.TopUnitID
join Player p
on p.UnitID = t2.UnitID
where t1.ParentUnitID = 1
and playerID in (1,2,3,4,5,6)
这是一个稍微优化的版本,其中包含嵌入在CTE中的单元ID标准。 CTE仅计算以父母ID为所选单位ID的单位为基础的层次结构(在本例中为1)
with UnitCTE as (
select u.UnitID,
u.Designation UnitDesignation,
u.ParentUnitID as ParentUnitID,
p.Designation as ParentUnitDesignation,
u.UnitID TopUnitID,
u.Designation TopUnitDesignation,
1 as TeamLevel
from Unit u
left outer join Unit p
on u.ParentUnitId = p.UnitID
where u.ParentUnitID = 1
union all
select t.UnitID,
t.Designation UnitDesignation,
c.UnitID as ParentUnitID,
c.UnitDesignation as ParentUnitDesignation,
c.TopUnitID,
c.TopUnitDesignation,
TeamLevel+1 as TeamLevel
from Unit t
join UnitCTE c
on t.ParentUnitID = c.UnitID
)
select p.PlayerID,
p.Designation,
t1.*
from UnitCTE t1
join UnitCTE t2
on t2.TopUnitID = t1.UnitID
join Player p
on p.UnitID = t2.UnitID
where playerID in (1,2,3,4,5,6)
以下是我的原始答案。 只有在单位层次结构被限制为每个单元只允许一个子节点时才有效。问题中的SQL Fiddle示例有3个子单元用于单元1,因此如果针对单元1运行,则错误地为玩家3,5和6返回多行
以下是展示问题的SQL Fiddle。
with UnitCTE as
select UnitID,
Designation UnitDesignation,
ParentUnitID as ParentUnitID,
cast(null as varchar(50)) as ParentUnitDesignation,
UnitID TopUnitID,
Designation TopUnitDesignation,
1 as TeamLevel
from Unit
where ParentUnitID is null
union all
select t.UnitID,
t.Designation UnitDesignation,
c.UnitID,
c.UnitDesignation,
c.TopUnitID,
c.TopUnitDesignation,
TeamLevel+1 as TeamLevel
from Unit t
join UnitCTE c
on t.ParentUnitID = c.UnitID
)
select p.PlayerID,
p.Designation,
t2.*
from Player p
join UnitCTE t1
on p.UnitID = t1.UnitID
join UnitCTE t2
on t2.TopUnitID = t1.TopUnitID
and t1.TeamLevel >= t2.TeamLevel
join UnitCTE t3
on t3.TopUnitID = t1.TopUnitID
and t2.TeamLevel = t3.TeamLevel+1
where t3.UnitID = 2
and playerID in (1,2,3,4)