具有多个表和可能的外部联接的半分层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,因此使用它的报告生成功能生成报告。