AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 22704
Accepted
Jeff Sacksteder
Jeff Sacksteder
Asked: 2012-08-18 18:26:09 +0800 CST2012-08-18 18:26:09 +0800 CST 2012-08-18 18:26:09 +0800 CST

建立一个三表连接,中间有一个递归表?

  • 772

我有三个相关的表:Parts、PartGroup 和 MarkupGroup。

零件很简单。

PartID          artificial primary key
Part            part number
PartGroupID     Foreign key

样本数据:

1   T1000           5
2   wizbang gold    17
3   flux capacitor  2

PartGroup 是使用自链接父键建模的无环有向图(树)

PartGroupID     artificial primary key
Description     name of group
ParentID        foreign key linked to PartGroupID
MarkupGroupID   foreign key linked to MarkupGroup

样本数据看起来像这样 -

1   system      null    null
2   component   null    1 
3   software    null    2
4   abc         1       3
5   xyz         1       4
6   123         4       null
7   456         4       null
8   789         5       null
9   a1          6       null
10  b2          6       null
11  c3          7       null
12  d4          7       null
13  e5          8       null  
14  f6          8       null
15  alpha       3       null
16  beta        3       null
17  gamma       3       null

MarkupGroup 是将一个标记因子应用到几个 PartGroup 作为一个集合。

MarkupGroupID   primary key
MarkupFactor    numeric attribute field

样本数据-

1   15
2   20
3   25
4   22

我需要编写一个查询,为部件表中的每个部件返回适当的标记量。永远不会有多个标记可以应用于零件的情况。我需要递归图表以找到标记,并且在查询时我不知道需要递归多少级别才能找到非空标记。

永远不会有零件在向上树的过程中遇到多个可能的连接到边缘的情况,因此不需要进行累积。

t1000 是 xyz 类型,它有一个 MarginGroup 的外键,所以我们可以加入并获取一个值。它也有一个父母,但这无关紧要,因为我们有我们需要的价值。

Wizbang Gold 是 gamma-group 软件,它没有外键,但父节点“软件”有,我们应该返回它。

磁通电容器是一个组件,它具有指向 MarginGroup 的直接外键。返回该值。

所以结果将是:

1   T1000           22
2   wizbang gold    20
3   flux capacitor  15

我很确定我将需要一个递归 CTE 和一些 APPLY 的味道来获得这个,但我的大脑目前工作不太好。如果不是因为中间表的递归性质,这将非常简单。平台是 MS-SQL。

sql-server join
  • 1 1 个回答
  • 1648 Views

1 个回答

  • Voted
  1. Best Answer
    Mikael Eriksson
    2012-08-19T05:37:53+08:002012-08-19T05:37:53+08:00

    您可以随身携带自上而下在 CTE 中进行递归MarkupGroupID。

    with C as
    (
      select P.PartGroupID,
             P.ParentID,
             P.MarkupGroupID
      from PartGroup as P
      where P.ParentID is null
      union all 
      select P.PartGroupID,
             P.ParentID,
             coalesce(P.MarkupGroupID, C.MarkupGroupID)
      from PartGroup as P 
        inner join C 
          on P.ParentID = C.PartGroupID
    )
    select P.PartID,
           P.Part,
           MG.MarkupFactor
    from Parts as P
      inner join C
        on P.PartGroupID = C.PartGroupID
      inner join MarkupGroup as MG
        on C.MarkupGroupID = MG.MarkupGroupID
    order by P.PartID
    

    SQL小提琴

    递归 CTE 将创建一个如下所示的派生表。

    PartGroupID ParentID    MarkupGroupID
    ----------- ----------- -------------
    1           NULL        NULL
    2           NULL        1
    3           NULL        2
    15          3           2
    16          3           2
    17          3           2
    4           1           3
    5           1           4
    8           5           4
    13          8           4
    14          8           4
    6           4           3
    7           4           3
    11          7           3
    12          7           3
    9           6           3
    10          6           3
    

    如果您需要未连接到标记的部分组的部分,您可以MarkupGroup在主查询中使用外连接。

    with C as
    (
      select ...
    )
    select P.PartID,
           P.Part,
           MG.MarkupFactor
    from Parts as P
      inner join C
        on P.PartGroupID = C.PartGroupID
      left outer join MarkupGroup as MG
        on C.MarkupGroupID = MG.MarkupGroupID
    order by P.PartID
    
    • 5

相关问题

  • INNER JOIN 和 OUTER JOIN 有什么区别?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • JOIN 语句的输出是什么样的?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何查看 Oracle 中的数据库列表?

    • 8 个回答
  • Marko Smith

    mysql innodb_buffer_pool_size 应该有多大?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    从 .frm 和 .ibd 文件恢复表?

    • 10 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve