SQL-запрос нескольких подуровней

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня есть база данных, которая содержит две таблицы. Первый представляет собой список номеров деталей, а второй — список компонентов, связанных с родительской деталью.

Таблица 1 — Inv

  • Исходный код
  • ProductClass

Таблица 2 — Спецификация

  • ParentPart
  • Компонент
  • QtyPer

Третья таблица представляет собой базовую таблицу сведений о заказе на продажу.

Команда blow SQL возвращает все элементы, найденные в таблице спецификации, которая содержит деталь с классом продукта ‘FG’.

     SELECT     SD.SalesOrderLine, SD.StockCode, SD.BackOrderQty*Bom.QtyPer AS TotalReq, 
               Bom.Component, SD.MLineShipDate
    FROM       SalesOrder SD
    JOIN       Bom ON SD.StockCode=Bom.ParentPart
    JOIN       Inv On BS.Component=Inv.StockCode
    WHERE      SD.SalesOrder=xxxxx
    AND        Inv.ProductClass='FG'
  

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что некоторые из возвращаемых составных частей могут также содержать запись в таблице спецификации в качестве родительской части. В результате мне нужно вернуть все элементы, которые отображаются с классом ‘FG’ в начальной родительской части, с соответствующим общим количеством для каждого. Это может не возвращать никаких результатов, но в то же время может возвращать от 1 до 4 подуровней запроса.

Пример данных

Inv

  • Часть 1, ‘FG’
  • Часть 2, ‘RM’
  • Часть 3, ‘RM’
  • Часть 4, ‘FG’
  • Часть 5, ‘RM’
  • Часть 6, ‘FG’
  • Часть 7, ‘RM’
  • Часть 8, ‘RM’
  • Часть 9, ‘FG’
  • Часть 10, ‘RM’
  • Часть 11, ‘FG’
  • Часть 12, ‘FG’

Спецификация

  • Часть1, Часть2, 1
  • Часть1, Часть3, 1
  • Часть1, Часть4, 1
  • Часть4, Часть5, 2
  • Часть1, Часть6, 2
  • Часть6, Часть7, 1
  • Часть6, Часть8, 1
  • Часть6, Часть9, 3
  • Часть 9, часть 10, 1
  • Часть 9, Часть 11, 1
  • Часть11, Часть12, 1

Основываясь на этих данных, заказ, обработанный для 2 из «Part1», должен возвращать следующее

Результаты

  • 1, Часть1, 2, Часть4, дд / мм / гг
  • 1, Часть1, 4, Часть6, дд / мм / гг
  • 1, Часть6, 12, Часть9, дд / мм / гг
  • 1, Часть 9, 12, часть 11, дд / мм / гг

Комментарии:

1. Пожалуйста, предоставьте некоторый образец данных и выходные данные, которые вам нужны.

2. @gofr1, я добавил некоторые примеры данных.

3. Спасибо! Это здорово! Один вопрос: вы упоминаете части 1, 4, 6,9 и 11, а как насчет Part2 и Part3, в Bom таблице с Part1 в первом столбце

4. Поскольку их код части — «RM», мне не нужно их возвращать.

5. И еще один вопрос: что такое 1 перед частью 1 и 2,4,12,12 после других частей и дд / мм / гг? А как насчет Part11 и Part12, есть оба FG.

Ответ №1:

Я надеюсь, что это поможет вам:

 ;WITH cte AS (
SELECT  CAST(NULL as nvarchar(6)) as Parent,
        StockCode as Child,
        ProductClass
FROM Inv 
WHERE StockCode = 'Part1'
UNION ALL
SELECT  b.ParentPart,
        b.Component,
        i.ProductClass
FROM Bom b
INNER JOIN cte c
    ON c.Child = b.ParentPart
INNER JOIN Inv i
    ON i.StockCode = b.Component AND i.ProductClass = c.ProductClass
)

SELECT  *
FROM cte
WHERE Parent IS NOT NULL
  

Вывод:

 Parent  Child   ProductClass
Part1   Part4   FG
Part1   Part6   FG
Part6   Part9   FG
Part9   Part11  FG
Part11  Part12  FG
  

Вы можете удалить WHERE оператор из CTE, чтобы получить всю иерархию. И соедините этот CTE с другой таблицей.