【问题标题】:Recursive CTE with multiple valid same parent child relationships具有多个有效的相同父子关系的递归 CTE
【发布时间】:2014-04-24 21:19:53
【问题描述】:

我正在开发一个设备库存应用程序。这件设备是我的顶级设备,它包含组件、子组件和零件。我正在尝试使用递归 CTE 来显示父/子关系。我遇到的问题是某些组件可以有多个相同的子组件,这意味着零件编号没有差异。这导致我的查询无法根据我的 order by 语句显示正确的关系。这是我第一次使用 CTE,所以我在网上学到了很多东西。

PartNumberID 174 在此程序集中使用了两次。

    Sample  Table   
    equipmentID   parentPartNumberID  partNumberID
       17                1              281
       17              281              156
       17              156              161
       17              161              224
       17              281              174
       17              174              192
       17              192               56
       17              174              193
       17              281              174
       17              174              192
       17              192               56
       17              174              193
       17              281              283
       17   `          283              183
       17              283              277
       17              283              173

     Results of Query
    PARENT      CHILD   PARTLEVEL   HIERARCHY
      1           281       0         281
    281           156       1         281.156
    156           161       2         281.156.161
    161           224       3         281.156.161.224
    281           174       1         281.174
    281           174       1         281.174
    174           192       2         281.174.192
    174           192       2         281.174.192
    192            56       3         281.174.192.56
    192            56       3         281.174.192.56
    174           193       2         281.174.193
    174           193       2         281.174.193
    281           283       1         281.283
    283           173       2         281.283.173
    283           183       2         281.283.183
    283           277       2         281.283.277

如您所见,层次结构已正确创建,但未正确返回,因为 order by 语句的这 2 个程序集没有任何独特之处。

代码:

with parts(PARENT,CHILD,PARTLEVEL,HIERARCHY) as (select parentPartNumberID,
---  Used to get rid of duplicates
  CASE WHEN ROW_NUMBER() OVER (PARTITION BY partNumberID ORDER BY partNumberID) > 1
    THEN NULL 
    ELSE partNumberID END AS  partNumberID,
   0,
  CAST( partNumberID as nvarchar) as PARTLEVEL 
  FROM db.tbl_ELEMENTS
  WHERE parentPartNumberID=1 and equiptmentID=17

  UNION ALL
  SELECT part1.parentPartNumberId,
         ---  Used to get rid of duplicates
  CASE WHEN ROW_NUMBER() OVER (PARTITION BY parts1.partNumberID ORDER BY parts1.partNumberID) > 1
    THEN 10000 + parts1.partNumberID  
    ELSE parts1.partNumberID END,
            PARTLEVEL+1,
   cast(parts.hierarchy + '.' + CAST(parts1.partNumberID as nvarchar) as nvarchar)
          from dbo.tbl_BOM_Elements as parts1 inner 
                   join parts onparts1.parentPartNumberID=parts.CHILD 
          where id =17)

    select CASE WHEN PARENT > 10000
    THEN PARENT - 10000
    ELSE PARENT END AS PARENT,
    CASE WHEN CHILD > 10000
    THEN CHILD - 10000
    ELSE CHILD END AS CHILD,
            PARTLEVEL,HIERARCHY
    from parts
    order by hierarchy

我尝试创建一个唯一的 ID 以进行订购,但没有成功。任何建议将不胜感激。

【问题讨论】:

  • 您能否详细解释一下“我尝试创建一个唯一的 ID 以进行订购但没有成功?”
  • 当然,我试图在创建“parts”(cte-Name)数据时动态创建顺序 ID,以便我有一个可以订购的唯一字段。我认为这将允许多个相同的子组件。蒂姆

标签: tsql


【解决方案1】:

我将首先回答有关获取顺序 ID 的部分。

如果您有控制权,您可以只为源表设置一个唯一的 ID。拥有代理主键在这里非常典型。

您可以改为在递归 CTE 之前使用第二个 CTE,并使用 ROW_NUMBER() OVER BY (ORDER BY deviceID, parentPartNumberID, partNumberID) 添加行号。然后根据它而不是直接构建源表来构建您的递归 CTE。

最好使用第一个 CTE 代替 GROUP BY deviceID、parentPartNumberID、partNumberID 并添加 COUNT(1) 字段。这将让您改为使用层次结构中的计数,而不是获取重复项。像 281.283.277x2 之类的东西。

【讨论】:

  • 谢谢,我会在更改源表之前尝试您的建议。我有一种感觉,换桌子可能是最简单的方法......蒂姆
  • 我最终更改了我的源表,因为没有很多数据。然后,我按新的唯一 ID 进行排序,并获得所需的视图。在我的情况下,这是最简单的解决方案。卡尔谢谢你的帮助
猜你喜欢
  • 2022-11-14
  • 2019-02-17
  • 2013-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
  • 2014-07-01
  • 1970-01-01
相关资源
最近更新 更多