Пересоединение в SQL

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня есть 2 таблицы в SQL Server, в одной из которых перечислены спецификации:

 MainPartNo
RequiredPartNo
Quantity
  

и тот, в котором перечислены все сериализованные сборки и любые сериализованные части :

 PartNo
SerialNo
Child PartNo
Child SerialNo
  

Что я пытаюсь сделать, так это перечислить все спецификации и отобразить серийный номер, если дочерний элемент принадлежит родительскому. Я справился с этим на одном уровне, но некоторые спецификации вызывают вспомогательные спецификации, и в итоге я получаю слишком много результатов из моего запроса: если спецификация содержит 5 элементов и есть один дочерний серийный номер, я получаю 5 строк, в которых отображаются одни и те же родительский и дочерний

Мой текущий запрос следующий:

 SELECT
    MainPartNo,
    ParentSerialNo,
    RequiredPartNo,
    ChildSerialNo
FROM 
    BoM_TBL 
LEFT JOIN 
    Serial_TBL on MainPartNo = PartNo
  

Это должно быть просто JOIN но мои различные перестановки еще не оказались успешными.

Я ищу, чтобы увидеть список спецификаций для каждой сериализованной сборки со NULL значениями в ChildSerialNo строке столбца, где сборка содержит сериализованный дочерний элемент.

Редактировать

Структура данных таблиц

Последовательная таблица

Последовательная таблица

Таблица спецификации

Таблица спецификации

Желаемый результат

Желаемый результат

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

1. Привет, Гордон, я не могу опубликовать фактические данные, но я воссоздам образец структуры и обновлю.

2. Я думаю, что вы используете здесь неправильную таблицу. Обычно серийный номер применяется к каждому отдельному экземпляру детали, поэтому в вашей таблице с серийными номерами вы найдете один и тот же номер детали (или номер дочерней детали) много раз

3. @tomRedox Это правильно, я должен увидеть много экземпляров одной и той же части и дочернего элемента. В таблице спецификации указана структура, а в таблице серийных номеров указаны отдельные отношения

Ответ №1:

Может сработать внешнее приложение…

 SELECT 
A.MainPartNo,
B.ParentSerialNo,
A.RequiredPartNo,
C.ChildSerialNo
FROM Serial_TBL A
OUTER APPLY (
    SELECT DISTINCT ParentSerialNo FROM BoM_TBL WHERE PartNoParent = A.MainPartNo
) B
LEFT JOIN BoM_TBL C on A.MainPartNo = C.PartNoParent AND B.ParentSerialNo = C.ParentSerialNo AND A.RequiredPartNo = C.PartNoChild 
  

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

1. Спасибо, это почти то, что мне нужно. Я думаю, что смогу использовать это, большое вам спасибо

Ответ №2:

Вы хотите что-то вроде этого

 CREATE TABLE #BoM 
(
    MainPartNo VARCHAR(20),
    RequiredPartNo VARCHAR(20),
    Quantity INT
)

INSERT INTO #BoM (MainPartNo, RequiredPartNo, Quantity)
VALUES ('AssemblyA', 'ChildA', 2), ('AssemblyA', 'ChildA', 2),
       ('AssemblyA', 'ChildB', 2), ('AssemblyA', 'ChildC', 2),
       ('AssemblyA', 'PartA', 1), ('AssemblyA', 'PartB', 2),
       ('AssemblyB', 'ChildA', 2), ('AssemblyB', 'ChildD', 3),
       ('AssemblyB', 'ChildE', 1), ('AssemblyB', 'PartA', 1)

CREATE TABLE #Serial 
(
     ParentSerialNo INT,
     ChildSerialNo INT,
     PartNoChild VARCHAR(20),
     PartNoParent VARCHAR(20)
)

INSERT INTO #Serial (ParentSerialNo, ChildSerialNo, PartNoChild, PartNoParent)
VALUES (5001, 10001, 'ChildA', 'AssemblyA'),
       (5001, 10002, 'ChildA', 'AssemblyA'),
       (5001, 11001, 'ChildB', 'AssemblyA'),
       (5001, 11002, 'ChildB', 'AssemblyA'),
       (5001, 12001, 'ChildC', 'AssemblyA'),
       (5001, 12002, 'ChildC', 'AssemblyA'),
       (5002, 10003, 'ChildA', 'AssemblyB'),
       (5002, 10004, 'ChildA', 'AssemblyB'), 
       (5002, 13001, 'ChildD', 'AssemblyB'),
       (5002, 13002, 'ChildD', 'AssemblyB'),
       (5002, 13003, 'ChildD', 'AssemblyB'),
       (5002, 14001, 'ChildE', 'AssemblyB')


SELECT 
    MainPartNo, 
    ParentSerialNo,
    RequiredPartNo,
    ChildSerialNo
FROM
    #BoM B
FULL JOIN 
    #Serial S ON B.MainPartNo = S.PartNoParent
              AND B.RequiredPartNo = S.PartNoChild
  

Но я предполагаю, что в вашей таблице спецификации есть столбец типа MainPortSerialNo , iIf поэтому используйте MainPortSerialNo вместо ParentSerialNo в запросе

Ответ №3:

Доставит ли это то, что вы хотите (примерная таблица результатов была бы полезна)?

 Select

MainPartNo,
aa.serial_tbl as ParentSerialNo,
RequiredPartNo

FROM BoM_TBL 
Outer apply (select top 1 Serial_TBL where MainPartNo = PartNo and childserialno is null) aa
  

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

1. Спасибо, но не смог добиться, чтобы это дало мне нужный результат.

2. Нет проблем — после того, как вы обновили вопрос, я бы обновил свой ответ в соответствии с Дэниелсом, но он меня опередил!