提问人:graphene 提问时间:9/11/2023 最后编辑:graphene 更新时间:9/11/2023 访问量:68
将表中来自多个交叉表的数据关联
Associate data in a table from several crossed tables
问:
我正在使用 SQL Server 2012。
我们有几家公司的订单。每个订单可以有一个或多个销售订单行。 订单行可以有一篇文章,但它永远不会有多篇文章。但是,同一文章可以出现在多个销售订单行中。
Table Order - FinalCustomerId 是 Customer 的外键
Id FinalCustomerId Code
1 2 X45
2 1 O30
3 2 Y74
4 5 XY0
表 Customer
Id Name
1 XPTO
2 BOSS
3 TREND
4 XIPS
5 VALLEY
表文章
Id Name
1 DVD
2 San Disk
3 CD
4 SPAM
表 OrderLine(按 OrderId 排序,然后按 Number 排序)- OrderId 是 Order 的外键,如果 FK 为 Article,则为 ArticleId。
Id Number OrderId ArticleId
1 10 1 1
3 20 1 1
4 30 1 1
7 40 1 2
6 10 2 2
8 20 2 1
2 10 3 2
5 20 3 2
9 10 4 4
注意:此表有 3 个订单,只有第三个订单有一种类型的文章(id 2)。
表 CustomerArticleMark - MainArticleId 是 Article 的 FK
Id FinalCustomerId MainArticleId
1 2 1
2 2 2
3 1 3
4 5 2
5 3 2
6 5 4
目标:对于 CustomerArticleMark 的每一行,关联包含该商品的相应销售订单代码。
规则:
- CustomerArticleMark 中的文章出现在两个订单的 5 个订单行中,因此主文章必须出现 2 次而不是 5 次;
- CustomerArticleMark 中的文章出现在一个订单的 5 个订单行中,因此主文章只能出现一次,而不是 5 次;
- CustomerArticleMark 中的 article 不会出现在任何订单行中,因此 Main Article 应该显示,但 Sales Order code 的值为空;
- CustomerArticleMark 中的 article 对于 Sales Order 行 per Order 和 order 中的 per FinalCustomer 中的每个不同文章必须是唯一的。有些订单具有相同的商品,但最终客户不同。
从最后一个表开始,所需的结果应为以下结果:
最终表格 - 期望的结果。
Id (of CustomerArticleMark) FinalCustomer MainArticle SALES ORDER Code
1 BOSS DVD X45
2 BOSS SanDisk Y74
3 XPTO CD (there is no o. line with article 3)
4 VALLEY SanDisk -
5 TREND SanDisk (no final customer id5 in Order)
6 VALLEY SPAM XY0
它应该出现在所有这六行中。只有在 ID 为 3、4 和 5 的行中,销售订单代码必须为空,但其余代码必须填写!
我尝试过使用 T-SQL:
SELECT DISTINCT
{CustomerArticleMark}.[Id]
, {Customer}.[Name] AS FinalCustomer
, {Article}.[Name] AS MainArticle
, {Order}.[Code] AS SALES ORDER Code
FROM {CustomerArticleMark}
LEFT JOIN {Customer} ON {Customer}.[Id] = {CustomerArticleMark}.[FinalCustomerId]
LEFT JOIN {Article} ON {Article}.[Id] = {CustomerArticleMark}.[MainArticleId]
LEFT JOIN {SalesOrderLine} ON {SalesOrderLine}.[ArticleId] = {Article}.[Id]
LEFT JOIN {Order} ON {Order}.[Id] = {SalesOrderLine}.[OrderId]
WHERE {Order}.[FinalCustomerId] = {CustomerArticleMark}.[FinalCustomerId]
我明白了:
Id (of CustomerArticleMark) FinalCustomer MainArticle SALES ORDER Code
1 BOSS DVD X45
1 BOSS SanDisk* X45*
2 BOSS SanDisk Y74
6 VALLEY SPAM XY0
它没有显示 3、4 和 5,但应该显示销售订单代码为空。
差异用星号标记。我们怎样才能得到想要的结果? 感谢您的关注。
答:
好的,由于 SalesOrderLine 直接链接到 Order,我们应该将它们视为单个实体。然后我们可以将其加入 CustomerArticleMark。请尝试以下...
SELECT DISTINCT
{CustomerArticleMark}.[Id]
, {Customer}.[Name] AS FinalCustomer
, {Article}.[Name] AS MainArticle
, {Order}.[Code] AS SALES ORDER Code
FROM {CustomerArticleMark}
LEFT JOIN ( {SalesOrderLine} INNER JOIN {Order} ON {Order}.[Id] = {SalesOrderLine}.[OrderId]) ON {SalesOrderLine}.[ArticleId] = {CustomerArticleMark}.[MainArticleId]
AND {Order}.[FinalCustomerId] = {CustomerArticleMark}.[FinalCustomerId]
LEFT JOIN {Customer} ON {Customer}.[Id] = {CustomerArticleMark}.[FinalCustomerId]
LEFT JOIN {Article} ON {Article}.[Id] = {CustomerArticleMark}.[MainArticleId]
此外,在您想要的结果中,我认为您不能有以下内容,因为 MainArticleId/FinalCustomerId 没有匹配的 Orderline/Order -
Id (of CustomerArticleMark) FinalCustomer MainArticle SALES ORDER Code
1 BOSS DVD Y74
6 VALLEY SPAM XY0
或者,如果你想使用 CTE(我也在下面使用了 GROUP BY,你可以使用 DISTICNT)
;WITH cte as (
SELECT [SalesOrderLine].[ArticleId] , [Order].[FinalCustomerId] , [Order].[Code] FROM [SalesOrderLine] INNER JOIN [Order] ON [Order].[Id] = [SalesOrderLine].[OrderId])
SELECT
[CustomerArticleMark].[Id]
, [Customer].[Name] AS FinalCustomer
, [Article].[Name] AS MainArticle
, [cte].[Code] AS [SALES ORDER Code]
FROM [CustomerArticleMark]
LEFT JOIN [cte] ON [cte].[ArticleId] = [CustomerArticleMark].[MainArticleId]
AND [cte].[FinalCustomerId] = [CustomerArticleMark].[FinalCustomerId]
JOIN [Customer] ON [Customer].[Id] = [CustomerArticleMark].[FinalCustomerId]
JOIN [Article] ON [Article].[Id] = [CustomerArticleMark].[MainArticleId]
GROUP BY [CustomerArticleMark].[Id]
, [Customer].[Name]
, [Article].[Name]
, [cte].[Code]
评论