繁体   English   中英

查找循环中的最小迭代次数 - BigQuery

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM