在SQL Server 2008中的同一个表内递归过滤

时间:2014-09-04 16:26:34

标签: sql sql-server-2008

我在SQL Server 2008数据库中有一个表,其中包含以下字段:

  • ProductionBomNo
  • LINENO
  • 类型

Type列是一个包含2个可能值(ItemProductionBom)的选项列,Code列包含Item代码或另一个ProductionBom的代码(因此我可以在同一个表中搜索ProductionBomNo = ProductionBom代码)

这可能会在第一个级别下发生更多级别。

我想创建一个视图,显示所有级别内的所有Item列表(基本上分解Item列表)

+..............+........+................+.............+
|ProductionBOM | LineNo | Type           | Code        |
+..............+........+................+.............+
|A             |   1    | Item           | A1          |
|A             |   2    | Item           | A2          |
|A             |   3    | Item           | A3          |
|A             |   4    | Item           | B1          |
|A             |   5    | Item           | B2          |
|A             |   6    | ProductionBom  | B           |
+..............+........+................+.............+

在同一个表中,还有上一个表中引用的生产物料清单的productionBom行,所以:

+--------------+--------+----------------+-------------+
|ProductionBOM | LineNo | Type           | Code        |
+--------------+--------+----------------+-------------+
|B             |   1    | Item           | C1          |
|B             |   2    | Item           | C2          |
|B             |   3    | Item           | S3          |
|B             |   4    | Item           | S5          |
|B             |   5    | Item           | S7          |
+--------------+--------+----------------+-------------+

我想要的结果是:

+--------+-------------+
| LineNo | Code        |
+--------+-------------+
|   1    | A1          |
|   2    | A2          |
|   3    | A3          |
|   4    | B1          |
|   5    | B2          |
|   6    | C1          |
|   7    | C2          |
|   8    | S3          |
|   9    | S5          |
|  10    | S7          |
+--------+-------------+

由于

2 个答案:

答案 0 :(得分:0)

试试这个(假设里面的LineNo需要添加ProductionBom&#39的LineNo来获取新的LineNo):

仅适用于2级树:

select coalesce(p.ProductionBomNo,t1.ProductionBomNo),coalesce(p.[LineNo],1)+t1.[LineNo] -1 ,t1.Code
from tableName t1
left join (select ProductionBomNo,code,[LineNo] from tableName where Type='ProductionBom') as p
on t1.ProductionBomNo=p.code
where t1.type = 'Item'

测试: SQLFiddle

结果是:

PRODUCTIONBOMNO LINENO  CODE
              A      1    A1
              A      2    A2
              A      3    A3
              A      4    B1
              A      5    B2
              A      6    C1
              A      7    C2
              A      8    S3
              A      9    S5
              A     10    S7

对于n级树:

WITH BOM(ProductionBOMno,[LineNo],Type,Code)
AS
(
    SELECT ProductionBOMno
        ,CAST([LineNo] AS INT)
        ,[Type]
        ,Code 
    FROM tableName 
    WHERE ProductionBOMNo 
        -- Top level to start with
        NOT IN (SELECT DISTINCT Code 
                FROM tableName)
    UNION ALL
    --Recursion link
    SELECT BOM.ProductionBOMno --get the ancestor BOMno
        ,BOM.[LineNo] + tbl.[LineNo] -1  AS [LineNo]
        ,tbl.[Type]
        ,tbl.Code

    FROM BOM
    JOIN tableName tbl ON BOM.Type='ProductionBom'
                  AND BOM.Code = tbl.ProductionBOMno
)
SELECT *
FROM BOM WHERE [Type]='Item'
ORDER BY ProductionBOMno,[LINENO]

测试: SQLFiddle

答案 1 :(得分:0)

我认为您可以使用以下递归查询。对指定数据工作正常。

;WITH BOM(ProductionBOM,[LineNo],Type,Code)
AS
(
    SELECT ProductionBOM
        ,CAST([LineNo] AS INT)
        ,[Type]
        ,Code 
    FROM ProductionBOM 
    WHERE ProductionBOM 
        -- Top level to start with
        NOT IN (SELECT DISTINCT Code 
                FROM ProductionBOM)
    UNION ALL
    --Recursion link
    SELECT tbl.ProductionBOM
        ,BOM.[LineNo] + tbl.[LineNo] -1  AS [LineNo]
        ,tbl.[Type]
        ,tbl.Code

    FROM BOM
    JOIN ProductionBOM tbl ON BOM.Type='ProductionBom'
                  AND BOM.Code = tbl.ProductionBOM
)
SELECT BOM.Code,BOM.[LineNo]
FROM BOM WHERE [Type]='Item'