[英]Find the minimum iterations in a loop - BigQuery
我试图在 BigQuery SQL 中建立一个代码来找到覆盖所有项目所需的最小迭代。
详细来说,假设我有一个包含 3 列的表格:站点、路由器、PC。
每个站点都有多个路由器连接到不同的 PC。 我想找到覆盖该站点中所有 PC 的每个站点所需的最少路由器。 例如:在站点 XI 中,有 5 个不同的路由器连接到 9 台 PC,但我只能保留 3 个路由器来全面覆盖 PC。 路由器 AAA、BBB、DDD 可以看到所有 9 台 PC。 我可以丢弃路由器 CCC 和 EEE,但我仍然可以完全覆盖所有 PC。
原始数据:
with pop as (
select 'X' as site,'AAA' as router, 1 as pc union all
select 'X' as site,'AAA' as router, 2 as pc union all
select 'X' as site,'AAA' as router, 3 as pc union all
select 'X' as site,'AAA' as router, 4 as pc union all
select 'X' as site,'AAA' as router, 5 as pc union all
select 'X' as site,'BBB' as router, 4 as pc union all
select 'X' as site,'BBB' as router, 6 as pc union all
select 'X' as site,'BBB' as router, 7 as pc union all
select 'X' as site,'CCC' as router, 2 as pc union all
select 'X' as site,'CCC' as router, 4 as pc union all
select 'X' as site,'CCC' as router, 7 as pc union all
select 'X' as site,'DDD' as router, 1 as pc union all
select 'X' as site,'DDD' as router, 8 as pc union all
select 'X' as site,'DDD' as router, 9 as pc union all
select 'X' as site,'EEE' as router, 5 as pc union all
select 'X' as site,'EEE' as router, 6 as pc union all
select 'Y' as site,'FFF' as router, 1 as pc union all
select 'Y' as site,'GGG' as router, 2 as pc union all
select 'Y' as site,'HHH' as router, 1 as pc union all
select 'Y' as site,'HHH' as router, 2 as pc union all
select 'Y' as site,'HHH' as router, 3 as pc
)
select *
from pop
预期结果:
先感谢您!
我们可以使用“数字表”来枚举所有组合(将路由器表示为 integer 值中的 1 位并使用按位 AND 函数):
with MyTbl as (
select *
from (
values
('X','AAA',1) ,('X','AAA',2) ,('X','AAA',3) ,('X','AAA',4) ,('X','AAA',5) ,('X','BBB',4)
,('X','BBB',6) ,('X','BBB',7) ,('X','CCC',2) ,('X','CCC',4) ,('X','CCC',7) ,('X','DDD',1)
,('X','DDD',8) ,('X','DDD',9) ,('X','EEE',5) ,('X','EEE',6) ,('X','FFF',1) ,('Y','GGG',2)
,('Y','HHH',1) ,('Y','HHH',2) ,('Y','HHH',3)
) T (Site, Router, PC)
),
Nos as (
-- Up to 8 routers per site are supported
select T0.N+T1.N*2+T2.N*4+T3.N*8+T4.N*16+T5.N*32+T6.N*64+T7.N*128 as Combtn
from
(values (0),(1)) T0(N), (values (0),(1)) T1(N), (values (0),(1)) T2(N), (values (0),(1)) T3(N),
(values (0),(1)) T4(N), (values (0),(1)) T5(N), (values (0),(1)) T6(N), (values (0),(1)) T7(N)
),
Routers as (
select Site
, Router
, power(2, row_number() over (partition by Site order by Router)) as RouterSeqBM
from (select distinct Site, Router from MyTbl) S1
),
RouterCombos as (
select R.Site, N.Combtn, R.Router
from Nos N
inner join Routers R
on R.RouterSeqBM & N.Combtn <> 0 --< Adjust this &
)
select RC.Site, RC.Router
from
(
select *
from (
-- Choose the coombination with the least no of routers
select Seqd.*
, row_number()
over (partition by Site
order By NumRouters) as NumRouterSeq
from (
-- count routers for each site covering all PCs
select Site, Combtn, count(*) as NumRouters
from RouterCombos RC
where not exists -- Make sure that all PCs are covered
(select 1
from MyTbl MT
where MT.Site=RC.Site
and MT.PC not in
(select distinct PC
from
RouterCombos RC2
inner join MyTbl MT2
on MT2.Site=RC2.Site
and MT2.Router=RC2.Router
where RC2.Combtn=RC.Combtn
and RC2.Site=RC.Site))
group by Site, Combtn
) Seqd
) Seqd1
where Seqd1.NumRouterSeq=1
) BestRouterCombs
inner join
RouterCombos RC
on RC.Site=BestRouterCombs.Site
and RC.Combtn=BestRouterCombs.Combtn
这适用于 SQLServer,您需要根据您的环境进行调整。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.