【问题标题】:SQL Hierarchical query - Multiple layers, only care about oneSQL分层查询 - 多层,只关心一个
【发布时间】:2015-09-26 19:54:24
【问题描述】:

我有一张列出工作和工单信息的表格。每个工作至少有一个工单,大多数工作有很多工单。一些工单可以有子工单,而子也可以有子。这为我们提供了多层层次结构。

对于我正在构建的报告,我想按它们所属的第二级工作订单对所有工作订单进行分组。我称它为 SectorWO。

我编写了以下查询,它几乎可以实现我正在寻找的内容,但它不包括二级工单本身。我试图在 SQL Fiddle 上构建示例数据,但我的查询不会在那里运行(但它确实在生产 SQL Server 2012 上运行)。在填充该表的语句终止后查询临时表似乎有问题?

无论如何,这是我在 SQL Fiddle 上构建的,希望它足以证明......

架构:

CREATE TABLE WOMaster (WorkOrder VARCHAR(12), ParentWorkOrder VARCHAR(12), Job VARCHAR(12))
INSERT INTO WOMaster (WorkOrder, ParentWorkOrder, Job)
VALUES (1,NULL,101),(2,1,101),(3,2,101),(4,3,101),(5,4,101),(6,4,101),(7,4,101),(8,4,101),(9,2,101),(10,2,101),
    (11,2,101),(12,1,101),(13,12,101),(14,12,101),(15,12,101),(16,2,101),(17,1,101),(18,17,101),(19,17,101),(20,1,101),
    (21,1,101),(22,21,101),(23,22,101),(24,22,101),(25,24,101),(26,24,101),(27,1,101),(28,27,101),(29,28,101),
    (30,1,101),(31,30,101),(32,31,101),(33,32,101),(34,1,101),(35,34,101),(36,35,101),(37,36,101);

查询:

    DECLARE @pJob VARCHAR(Max)

SET @pJob = '101'

DECLARE @pWorkOrder VARCHAR(6)

SET @pWorkOrder = '1'

DECLARE @WOList1 TABLE (
    Job VARCHAR(12)
    ,WorkOrder VARCHAR(12)
    ,ParentWorkOrder VARCHAR(12)
    )
DECLARE @WOList2 TABLE (
    Job VARCHAR(12)
    ,WorkOrder VARCHAR(12)
    ,SectorWO VARCHAR(12)
    )

INSERT INTO @WOList1 (
    Job
    ,WorkOrder
    ,ParentWorkOrder
    )
SELECT Job
    ,WorkOrder
    ,ParentWorkOrder
FROM WOMaster
WHERE Job = @pJob
    AND ParentWorkorder <> WorkOrder;

WITH cte
AS (
    SELECT WO1.WorkOrder
        ,WO1.ParentWorkOrder
    FROM @WOList1 WO1

    UNION ALL

    SELECT c.WorkOrder
        ,WO1.ParentWorkOrder
    FROM @WOList1 WO1
    INNER JOIN cte c ON c.ParentWorkOrder = WO1.WorkOrder
    )
INSERT INTO @WOList2 (
    Job
    ,WorkOrder
    ,SectorWO
    )
SELECT WO1.Job
    ,C.WorkOrder
    ,C.ParentWorkOrder
FROM CTE C
LEFT JOIN @WOList1 WO1 ON C.WorkOrder = WO1.WorkOrder
WHERE C.ParentWorkOrder IN (
        SELECT WorkOrder
        FROM @WOList1
        WHERE ParentWorkOrder = @pWorkOrder
        )

预期输出:

Job WorkOrder   SectorWO
101 2   2
101 3   2
101 4   2
101 5   2
101 6   2
101 7   2
101 8   2
101 9   2
101 10  2
101 11  2
101 16  2
101 12  12
101 13  12
101 14  12
101 15  12
101 17  17
101 18  17
101 19  17
101 20  20
101 21  21
101 22  21
101 23  21
101 24  21
101 25  21
101 26  21
101 27  27
101 28  27
101 29  27
101 30  30
101 31  30
101 32  30
101 33  30
101 34  34
101 35  34
101 36  34
101 37  34

【问题讨论】:

  • SQL Server 是您的目标数据库吗?还是换一个?
  • SQL Server 是目标。

标签: sql hierarchy common-table-expression hierarchical-data hierarchical


【解决方案1】:

您还没有给出您希望输出的样子的示例。所以这是我最好的尝试。我认为您可能使这变得比必要的复杂。

SELECT subwo.job, subwo.workorder SubWO, secondsubwo.workorder SecondSubWO
FROM WOMaster
LEFT JOIN WOMaster SubWO ON Subwo.parentworkorder = womaster.workorder
LEFT JOIN WOMaster SecondSubWo ON SecondSubWo.parentworkorder = Subwo.workorder
WHERE WOMaster.parentworkorder IS NULL
ORDER BY cast(subwo.workorder AS INT), cast(secondsubWO.workorder AS INT)

现在你已经澄清了你的输出。我认为您应该使用递归公用表表达式来获得所需的内容。

;
with woList as
(select toplevel.workorder, toplevel.job, toplevel.parentworkorder
, 1 as WOLevel
From womaster toplevel
UNION ALL
SELECT wo.workorder, wo.job, wo.parentworkorder
, wolist.wolevel+1 as wolevel
FROM womaster wo
INNER JOIN wolist on wo.parentworkorder=wolist.workorder
WHERE wo.parentworkorder is not null)

select 
WoMaster.job, WoMaster.workorder, sector.workorder SectorWO
 from womaster womaster
 inner join wolist sector on sector.workorder=womaster.parentworkorder
 where wolevel=2
UNION ALL 
Select sector2.job, sector2.workorder, sector2.workorder
FROM wolist sector2
where wolevel=2
 order by cast(womaster.job as int), cast(sector.workorder as int), cast(womaster.workorder as int)

Pinal Dave explains this really well.

【讨论】:

  • 将编辑具有预期输出的原始帖子。这不是我想的。我同意我可能会让事情变得过于复杂。
  • 如果您查看我的原始查询,我确实使用了递归 CTE(尽管可能不是最有效的),并且得到的结果与您的查询相同。问题是 2 级工单本身需要出现在结果中,并且它们需要在各自的部门中。例如,工单 2 应使用 SectorWO 2。
  • 哦,那很简单。您距离添加它们只有一个 UNION ALL。
  • 哇,我真的没有注意到你的做法。 tldr
  • 您好 TTG,我实际上正在仔细研究您的结果,但它们与我的不同。查看 SectorWO 2,您的查询仅返回工单 3、9、10、11 和 16。这些是扇区 2 的直系子代。我需要孙子、曾孙等。我的查询确实提供了所有代,尽管老实说,我不知道为什么。 (第一次使用 CTE)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多