具有多个表和可能的外连接的半分层SQL查询

时间:2012-11-01 12:09:56

标签: sql join multiple-tables hierarchical libreoffice-base

我有产品。每个产品都由物品和组件组成。装配本身也可以由物品组成。所以它是一个层次结构,但深度有限。我想要做的是列出包含其中包含的物品和组件的产品,以及产品组件中的任何物品。

这是我想看到的输出。它不必看起来像这样,但目的是显示产品中的项目,然后是装配体以及每个装配体中的项目。列数不固定,如果需要更多列来显示程序集中的项目,则没有问题。

ProductID ProductName AssemblyID AssemblyName ItemID ItemName
--------- ----------- ---------- ------------ ------ --------
 P0001001 Product One
                                               I0045 Item A
                                               I0082 Item B
                          A00023 Assembly 1
                                               I0320 Item 1
                                               I0900 Item 2
                          A00024 Assembly 2
                                               I0877 Item 3
                                               I0900 Item 2
                                               I0042 Item 4

然后我可以使用它来构建一个按产品ID分组的报告,列出每个产品的内容。

这是我目前的表结构。

+ProductList-+             +ProductItems-+                                  
|ProductID   | ----------> |ProductID    |                                   +ItemList-+
|ProductName | \           |ItemID       | --------------------------------> |ItemID   |
|Price       |  \          +-------------+                                 > |ItemName |
+------------+   \                                                        /  |Cost     |
                  \    +ProductAssemblies-+                              /   +---------+
                   \-> |ProductID         |       +AssemblyItems-+      /
                   +-- |AssemblyID        | ----> |AssemblyID    |     /
                   |   |BuildTime         |       |ItemID        | ---/
                   |   +------------------+       +--------------+
                   |
                   |   +AssemblyList-+
                   +-> |AssemblyID   |
                       |AssemblyName |
                       +-------------+

我需要使用哪种SELECT语句。

我认为我需要某种外连接,但我并不完全了解SQL语法以了解如何构造select语句。我所有的努力总是导致产品被列出多次为每个项目和组装。因此,如果产品有3个项目和2个组件,则产品会显示6次。

寻找这类问题并不容易,因为我不知道自己需要搜索什么。它是一个三表问题,一个外连接问题,还是一个简单的语法答案。

或者在不使用程序集的情况下切换到纯层次表结构会更好吗?然后,在分层表上搜索以解决我可能遇到的任何问题会更容易。

我使用的是LibreOffice 3.5.6.2 Base。它有向导和其他有用的东西,但它们并没有延伸到我发现自己所处的情况的复杂性。目的是数据库包含价格,它可以用来从成本中正确定价产品。构建组件的项目和时间。

要温柔,我是SO的新手。

1 个答案:

答案 0 :(得分:0)

正常的SQL方法会将所有数据放在一行上,而不是分成几行。所以,你的数据看起来像是:

ProductID ProductName AssemblyID AssemblyName ItemID ItemName
--------- ----------- ---------- ------------ ------ --------
 P0001001 Product One                          I0045 Item A
 P0001001 Product One                          I0045 Item B
 P0001001 Product One     A00023 Assembly 1    I0320 Item 1
 P0001001 Product One     A00023 Assembly 1    I0320 Item 2
 . . .

例如,产品和装配信息对于给定的项目不是空白的。一切都会在同一条线上。

此信息来自两个来源,产品项目和装配项目。以下查询获取每个组件,然后将它们联合在一起,最后按产品排序结果:

select *
from ((select p.Productid, p.ProductName, NULL as AssemblyId, NULL as AssemblyName, il.Itemid, il.ItemName
       from Product p join
            ProductItems pi
            on p.productId = pi.ProductId join
            ItemList il
            on pi.ItemId = il.ItemId
      ) union all
      (select p.Productid, p.ProductName, al.AssemblyId, al.AssemblyName, il.Itemid, il.ItemName
       from Product p join
            ProductAssemblies pa
            on pa.ProductId = p.ProductId join
            AssemblyList al
            on pl.AssembyId = al.AssemblyId, join
            AssemblyItems ai
            on al.AssemblyItems join
            ItemList il
            on p.ItemId = il.ItemId
      )
     ) t
order by 1, 2, 3, 4, 5, 6

通常,重组为您想要的格式将在应用级别完成。您可以在SQL中执行此操作,但最佳方法取决于您使用的数据库。