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

具有多个表和可能的外部联接的半分层SQL查询,sql,join,multiple-tables,hierarchical,libreoffice-base,Sql,Join,Multiple Tables,Hierarchical,Libreoffice Base,我有产品。每个产品都由项目和组件组成。组件本身也可以由项目组成。因此,这是一个层次结构,但深度有限。我想做的是列出产品及其包含的项目和组件,以及产品组件中的任何项目 这是我希望看到的输出。它不必看起来完全像这样,但目的是显示产品中的项目,然后是组件以及每个组件中的项目。列的数量不是固定的,如果需要更多的列来显示程序集中的项,则没有问题 ProductID ProductName AssemblyID AssemblyName ItemID ItemName --------- ---------

我有产品。每个产品都由项目和组件组成。组件本身也可以由项目组成。因此,这是一个层次结构,但深度有限。我想做的是列出产品及其包含的项目和组件,以及产品组件中的任何项目

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

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。它有向导和其他有用的东西,但它们没有扩展到我所处的复杂情况。其目的是数据库包含价格,并可用于根据项目成本和装配时间对产品进行正确定价


温柔一点,我是这样做的新手。

正常的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中执行此操作,但最佳方法取决于您所使用的数据库。

欢迎使用SO:)您的问题很好,尽管这通常是一个很好的实践,可以向我们展示您的尝试;)我建议您也看看我们的常见问题解答:我尝试过以下方法:从“TBLPProductList”中选择“TBLPProductList”。“ProductID”,“TBLPProductItems”。“ItemID”,“TBLPProductAssemblys”。“AssemblyID”从“TBLPProductList”左键连接“TBLPProductItems”,从(“TBLPProductList”。“ProductID”=“TBLPProductItems”。“ProductID”)从(“TBLPProductList”。“ProductID”=“TBLPProductAssemblys”左键连接“TBLPProductAssemblys”。“ProductID”),但我只是让每个产品重复项目*程序集次数(例如3个程序集x 5个项目意味着我让一个产品重复15次)。我已经尝试了左和右。正如我所说,我不知道连接语法,除了一个表之外,什么都做不了。你可以编辑自己的帖子来添加此信息,只需单击“编辑”按钮“链接;)谢谢你。我将用你的例子来表演。您对查询工作原理的解释对解决查询的不同部分有很大帮助。我使用的是LibreOffice 3.5,因此使用它的报告生成功能生成报告。