复杂的多层次分层SQL

时间:2020-02-25 16:33:52

标签: sql sql-server

如何使用SQL Server中的查询获得以下结果。

表格:shares_info

复杂的多层层次结构:

comp_name investee

APPLE     MS
APPLE     INTEL
APPLE     MRF
APPLE     GOOG
MS        GOOG
MS        MRF
MRF       STF
MRF       ABC
GOOG      INTEL
GOOG      TRF
GOOG      XYZ

想法是这样的。 APPLE已投资于MS,INTEL,MRF,GOOG。等等。现在,下面的输入类似于出售我的股份,但首先出售没有依赖性的股份。这就是我的输出所传达的。如果我想出售GOOG股份,则基于我的以下输入,GOOG依赖于INTEL / TRF / XYZ,因此在出售GOOG之前,我需要出售(123,XYZ)和(456 INTEL)。接下来,如果我要出售APPLE,则它依赖于MS / INTEL / MRF / GOOG,因此,根据以下输入,我需要首先出售INTEL / MRF / GOOG来出售APPLE。

表格:shares_sell_info

一些输入

id  comp_name

123 APPLE
456 APPLE
123 XYZ
789 GOOG
456 INTEL
243 MRF
432 ABC

订购应如下所示

123 XYZ  (XYZ does not have any dependency and hence should come at the top)
432 ABC (MRF has a dependency on ABC and hence ABC comes on top)
243 MRF (MRF’s dependency is all taken care and hence we have MRF)
456 INTEL (APPLE and GOOGLE has a dependency on INTEL and hence INTEL is on top)
789 GOOG (At this point we can add GOOG because all its dependents are already at top)
123 APPLE (APPLE has a dependency on GOOG and hence GOOG come before APPLE)
456 APPLE

在上述顺序中,XYZ / ABC中的一个可以排在第一位,这并不重要,因为它们都不具有任何依赖性

3 个答案:

答案 0 :(得分:0)

dbfiddle

WITH 
 cte_com as (SELECT * FROM (VALUES
(123 ,'APPLE'),
(456 ,'APPLE'),
(123 ,'XYZ'),
(789 ,'GOOG'),
(456 ,'INTEL'),
(243 ,'MRF'),
(432 ,'ABC')) as cte_com(id, comp))
,cte_temp as (SELECT * FROM (VALUES
 ('APPLE',     'MS'),  
 ('APPLE',     'INTEL' ),
 ('APPLE',     'MRF' ),
 ('APPLE',     'GOOG' ),
 ('MS',        'GOOG' ),
 ('MS',        'MRF' ),
 ('MRF',       'STF' ),
 ('MRF',       'ABC' ),
 ('GOOG',      'INTEL' ),
 ('GOOG',      'TRF' ),
 ('GOOG',      'XYZ')) as cte_temp(one, two))


 SELECT id, comp , one
     , count(*) as count
 from cte_com
 left join cte_temp on cte_temp.one=cte_com.comp
 group by id, comp, one
 order by count(*)

但是尚不清楚为什么该解决方案可以提供所需的顺序。

“ XYZ”和“ ABC”有什么区别? 它们都取决于另外1个补偿。

输出:

id  comp    one count
123 XYZ             1
432 ABC             1
456 INTEL           1
243 MRF     MRF     2
789 GOOG    GOOG    3
123 APPLE   APPLE   4
456 APPLE   APPLE   4
7 rows

答案 1 :(得分:0)

我认为@Luuk的想法稍作修改是正确的。这是对我有用的查询。

select * from shares_sell_info as ssi
left join (
select comp_name, count(*) as count
    from shares_info si
    group by comp_name
UNION
select comp_name, 0 as count
    from shares_info
    where investee is null
) temp on temp.comp_name = share_info.comp_name
where id in (
            )
order by count

答案 2 :(得分:0)

这是我从另一篇文章中获得的问题的实际答案。

https://stackoverflow.com/questions/60420380/assign-weight-based-on-hierarchical-depth