工会的奇怪类型

时间:2019-05-27 13:42:37

标签: sql sql-server

抱歉,标题很奇怪,我对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 个答案:

答案 0 :(得分:3)

我不会像使用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

答案 1 :(得分:0)

这似乎是union alljoin

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;

答案 2 :(得分:0)

您的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`