【问题标题】:How do I get a list of corporations where corporation (ID) is included?如何获取包含公司 (ID) 的公司列表?
【发布时间】:2020-08-05 08:42:33
【问题描述】:

重要...在我的 RL 项目中,ID 不是 INT,而是 GUID,所以我的数据不是分层的!

我有一个包含公司的表格和一个包含公司之间链接的表格。

我需要能够从特定公司 ID 中检索公司列表。

这是我的测试代码...

CREATE TABLE ##corporations
(  
    CorporationID INT NOT NULL,  
    CorporationName NVARCHAR(20) NOT NULL
);  

CREATE TABLE ##corporationLinks
(  
    FromCorporationID INT NOT NULL,  
    ToCorporationID INT NOT NULL
);  

INSERT INTO ##corporations (CorporationID, CorporationName) VALUES (1, 'Nike')
INSERT INTO ##corporations (CorporationID, CorporationName) VALUES (2, 'Cocal Cola')
INSERT INTO ##corporations (CorporationID, CorporationName) VALUES (3, 'Apple')
INSERT INTO ##corporations (CorporationID, CorporationName) VALUES (4, 'Google')
INSERT INTO ##corporations (CorporationID, CorporationName) VALUES (5, 'Amazon')
INSERT INTO ##corporations (CorporationID, CorporationName) VALUES (6, 'Samsung')

INSERT INTO ##corporationLinks (FromCorporationID, ToCorporationID) VALUES (1, 2)
INSERT INTO ##corporationLinks (FromCorporationID, ToCorporationID) VALUES (2, 3)
INSERT INTO ##corporationLinks (FromCorporationID, ToCorporationID) VALUES (4, 5)
INSERT INTO ##corporationLinks (FromCorporationID, ToCorporationID) VALUES (4, 6)

SELECT * FROM ##corporationLinks WHERE FromCorporationID = 2 OR ToCorporationID = 2

/** 

Organisations (##corporationLinks) are...

Nike + Coca Cola + Apple + Marcy

and...

Google + Amazon + Samsung

**/

-- How do I eg get a list of companies where Coca Cola is in ... that is where FromCorporationID = 2 OR ToCorporationID = 2 ... result should be Nike, Coca Cola and Apple?
-- How do I eg get a list of companies where Samsung is in ... that is where FromCorporationID = 6 OR ToCorporationID = 6 ... result should be Google, Amazon Cola and Samsung?

DROP TABLE ##corporationLinks 
DROP TABLE ##corporations

UDPATE:

如果我需要找到可口可乐所在的公司,那么我会去寻找……

SELECT * FROM ##corporationLinks WHERE FromCorporationID = 2 或 ToCorporationID = 2

那我会得到2个结果...

FromCorporationID   ToCorporationID
-----------------------------------
1                   2
2                   3

在此之后,我需要查看结果属于哪些公司...

SELECT * FROM ##corporationLinks WHERE FromCorporationID = 1 OR ToCorporationID = 1

SELECT * FROM ##corporationLinks WHERE FromCorporationID = 3 OR ToCorporationID = 3

然后我会再获得一个公司(7):

FromCorporationID   ToCorporationID
-----------------------------------
3                   7

然后我需要深入了解与 7 相关的公司......

SELECT * FROM ##corporationLinks WHERE FromCorporationID = 7 OR ToCorporationID = 7

并深入研究该结果(猜想它被称为递归)。等等

更新 2:

我更新了上面的示例,添加了一家公司,如果搜索可口可乐,则应返回该公司。

上述查询(可口可乐)的预期结果:

CorporationID:
--------------
2
1
3
7

【问题讨论】:

  • 使用递归 CTE 查询来查询层次关系。
  • 抱歉不清楚(我已经更新了我的帖子)......在我的 RL 项目中,我没有使用 INT,而是 GUID......而且它不是分层数据。
  • 所以...您是在问如何编写一个简单的SELECT 查询?
  • 表格格式的预期输出是什么?
  • 您自相矛盾 - 您说您的数据不是分层的(这与使用 GUID 无关,顺便说一句)但是您说您需要递归地重复查询。

标签: sql-server tsql recursive-cte


【解决方案1】:

使用递归CTE:

with 
  root as (select CorporationID id from companies where CorporationName = 'Coca Cola'),
  cte as (
    select 
      case when r.id = cl.FromCorporationID then cl.ToCorporationID else cl.FromCorporationID end id,
      case when r.id = cl.FromCorporationID then cl.FromCorporationID else cl.ToCorporationID end otherid      
    from corporationLinks cl inner join root r
    on r.id in (cl.FromCorporationID, cl.ToCorporationID)
    union all
    select 
      case when c.id = cl.FromCorporationID then cl.ToCorporationID else cl.FromCorporationID end id,
      case when c.id = cl.FromCorporationID then cl.FromCorporationID else cl.ToCorporationID end otherid            
    from corporationLinks cl inner join cte c
    on c.id in (cl.FromCorporationID, cl.ToCorporationID)
    and c.otherid not in (cl.FromCorporationID, cl.ToCorporationID)
  )
select id CorporationID from root
union all
select id from cte

请参阅demo
结果:

> | CorporationID |
> | ------------: |
> |             2 |
> |             1 |
> |             3 |
> |             7 |

【讨论】:

    【解决方案2】:

    左加入##companies,包括其CorporationID,或者您可以在查询中包括公司名称,然后按CorporationID分组,您应该能够看到它属于哪个公司

    【讨论】:

    • 我看不出这会起作用,因为如果我搜索“可口可乐”,那么“Marcy”将如何成为您解决方案结果的一部分?
    • 如果你只搜索可口可乐,那么所有结果都会在可口可乐下,玛西也是如此,如果你想同时查看或全部查看,那么选择所有公司而不过滤哪个公司,我希望就是这样你的意思
    • 很抱歉不够清楚。我不需要搜索##corporations 表......我需要搜索##corporationLinks 以查找与例如“可口可乐”链接的公司......这将是1、2、3和7。
    【解决方案3】:

    只需使用递归 CTE

    WITH cte
    AS
    (
        SELECT l1.FromCorporationID,l1.ToCorporationID
        FROM ##corporationLinks l1
        UNION ALL
        SELECT cte.FromCorporationID,l3.ToCorporationID
        FROM ##corporationLinks l3
        JOIN cte 
            ON cte.ToCorporationID = l3.FromCorporationID
    
    )
    
    SELECT cte.ToCorporationID--parent
    FROM cte
    WHERE cte.FromCorporationID =2
    UNION
    SELECT cte.FromCorporationID--child
    FROM cte
    WHERE cte.ToCorporationID =2
    UNION
    SELECT c.CorporationID--self
    FROM ##corporations c
    WHERE c.CorporationID = 2
    

    【讨论】:

      猜你喜欢
      • 2021-08-02
      • 1970-01-01
      • 2019-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-23
      相关资源
      最近更新 更多