这是对 Sql Server 2008 R2 的改进答案,希望您可以适应 MySQL。它将递归到任何深度。您以包含 tuple 列(例如 '1' 或 '1-2' 或 '1-2-3')、number (元组中所有 ids 的数值之和)的表结束) 和lvl 中的级别。然后,您可以选择具有最低级别的行。
我喜欢短名称以避免粗手指错误,所以使用pri 表示primary 和sec 表示secondary。
create table #summary ( tuple varchar(max), sec int, number int, lvl int )
delete #summary
insert #summary( tuple, sec, number, lvl )
select cast(p.pri as varchar(max)) + '-' + cast(p.sec as varchar(max)) as tuple,
p.sec, m1.number + m2.number as number, 1 as lvl
from t1_pivot p
inner join t1_main m1 on m1.id = p.pri
inner join t1_main m2 on m2.id = p.sec
declare @rows int = 1, @lvl int = 1
while @rows > 0 begin
insert #summary( tuple, sec, number, lvl )
select s.tuple + '-' + cast(p.sec as varchar(max)) as tuple,
p.sec, s.number + m.number as number, s.lvl + 1 as lvl
from #summary s
inner join t1_pivot p on p.pri = s.sec
inner join t1_main m on m.id = p.sec
where s.lvl = @lvl
set @rows = @@rowcount
print @rows
set @lvl = @lvl + 1
end
select * from (
select * from #summary
union select cast(id as varchar(max)) as tuple, 0 as sec, number, 0 as lvl from t1_main
) x
where x.number > 10
order by lvl, tuple
这是结果集。忽略sec - 只有在构建结果集时才需要它。
tuple sec number lvl
1-2-3 3 12 2
2-3-4 4 12 2
1-2-3-4 4 17 3
最初我使用 Sql Server 公用表表达式 (CTE),然后将其调整为在更通用的循环中运行(如上)。附上这段代码是为了感兴趣,因为我发现它很容易玩。
with summary as (
select cast(p.pri as varchar(max)) + '-' + cast(p.sec as varchar(max)) as tuple,
p.sec, m1.number + m2.number as number, 1 as lvl
from t1_pivot p
inner join t1_main m1 on m1.id = p.pri
inner join t1_main m2 on m2.id = p.sec
union all
select s.tuple + '-' + cast(p.sec as varchar(max)) as tuple,
p.sec, s.number + m.number as number, lvl + 1 as lvl
from summary s
inner join t1_pivot p on p.pri = s.sec
inner join t1_main m on m.id = p.sec
)
select * from (
select * from summary
union select cast(id as varchar(max)) as tuple, 0 as sec, number, 0 as lvl from t1_main
) x
where x.number > 10
order by lvl, tuple