Странный тип союза - PullRequest
0 голосов
/ 27 мая 2019

Извините за странный заголовок, у меня нет большого опыта работы с SQL.Я работаю с 2 таблицами: таблица COMPONENTS, в которой перечислены некоторые компоненты, и таблица OPERATIONS, которая представляет собой список операций, применяемых к компонентам.

Таблица COMPONENTS выглядит следующим образом:

+-------+--------------+-------------------+-------+
| Level | Main Article | Secondary Article | Brand |
+-------+--------------+-------------------+-------+
|     1 | Article A    | Article 1         | Foo   |
|     1 | Article B    | Article 1         | Bar   |
+-------+--------------+-------------------+-------+

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

Таблица OPERATIONS содержит все операции, которые должен выполнить вторичный товар, чтобы включить его в основной:

+--------------------+-----------+------+
| Secondary Article  | Operation | Cost |
+--------------------+-----------+------+
| Article 1          | Cutting   | X    |
| Article 1          | Knitting  | Y    |
| Article 1          | Bleaching | Z    |
+--------------------+-----------+------+

Как лучше всего объединить эти две таблицы в одну, имеющую такую ​​структуру?

+-------+--------------+-------------------+-----------+------+-------+
| Level | Main Article | Secondary Article | Operation | Cost | Brand |
+-------+--------------+-------------------+-----------+------+-------+
|     1 | Article A    | Article 1         |           |      | Foo   |
|     1 | Article A    | Article 1         | Cutting   | X    | Foo   |
|     1 | Article A    | Article 1         | Knitting  | Y    | Foo   |
|     1 | Article A    | Article 1         | Bleaching | Z    | Foo   |
|     1 | Article B    | Article 1         |           |      | Bar   |
|     1 | Article B    | Article 1         | Cutting   | X    | Bar   |
|     1 | Article B    | Article 1         | Knitting  | Y    | Bar   |
|     1 | Article B    | Article 1         | Bleaching | Z    | Bar   |
+-------+--------------+-------------------+-----------+------+-------+

Я попытался максимально упростить проблему.Как мне действовать, чтобы справиться с этим?Я пробовал с объединениями и объединениями, но это не работает.

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

Ответы [ 3 ]

3 голосов
/ 27 мая 2019

Вместо использования UNION я бы сделал что-то вроде этого:

SELECT C.Level,
       C.MainArticle,
       C.SecondaryArticle,
       O.Operation,
       O.Cost,
       C.Brand
FROM COMPONENTS C
     CROSS APPLY (VALUES(0),(1)) V(Header)
     LEFT JOIN OPERATIONS O ON V.Header = 1
                           AND C.SecondaryArticle = O.SecondaryArticle
ORDER BY C.MainArticle,
         V.Header,
         O.Cost;

db <> fiddle

0 голосов
/ 27 мая 2019

Ваша join / union интуиция была правильной, вы можете сделать что-то вроде этого:

select
    Level,
    `Main Article`,
    `Secondary Article`,
    '' as Operation,
    '' as Cost,
    Brand
from
    COMPONENTS
union select
    COMPONENTS.Level,
    COMPONENTS.`Main Article`,
    COMPONENTS.`Secondary Article`,
    OPERATIONS.Operation,
    OPERATIONS.Cost,
    COMPONENTS.Brand
from
    COMPONENTS
    left join OPERATIONS on COMPONENTS.`Secondary Article` = OPERATIONS.`Secondary Article`
0 голосов
/ 27 мая 2019

Это похоже на union all с join:

select c.Level, c.MainArticle, c.SecondaryArticle, 
       NULL as operation, NULL as cost, c.brand
from components c
union all
select c.level, c.MainArticle, c.SecondaryArticle,
       o.operation, o.cost, c.brand
from components c join
     operations o
     on c.SecondaryArticle = o.SecondaryArticle;

Если вы заботитесь о порядке в наборе результатов, используйте:

order by MainArticle, SecondaryArticle

и любые другие ключи, которые вы можете захотеть.

Вы также можете сделать union all до join, хотя это может повлиять на производительность:

select c.level, c.MainArticle, c.SecondaryArticle,
       o.operation, o.cost, c.brand
from components c join
     ((select o.SecondaryArticle, o.operation, o.cost
       from operations o
      ) union all
      (select c.SecondaryArticle, NULL, NULL
       from components c
      )
     ) o
     on c.SecondaryArticle = o.SecondaryArticle;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...