我使用的是 SQL Server 2012。
我们有多家公司的订单。每个订单可以有一个或多个销售订单行。 订单行可以包含一篇文章,但绝不能包含多于一篇文章。但是,同一篇文章可以出现在多个销售订单行中。
Table Order - FinalCustomerId 是 Customer 的外键
Id FinalCustomerId Code
1 2 X45
2 1 O30
3 2 Y74
4 5 XY0
桌子顾客
Id Name
1 XPTO
2 BOSS
3 TREND
4 XIPS
5 VALLEY
表格文章
Id Name
1 DVD
2 San Disk
3 CD
4 SPAM
Table OrderLine(按 OrderId 排序,然后按 Number 排序) - OrderId 是 Order 的外键,ArticleId(如果是 Article 的 FK)。
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
注意:该表有3个订单,只有第三个订单有一种类型的文章(id 2)。
Table CustomerArticleMark - MainArticleId 是 Article 的 FK
Id FinalCustomerId MainArticleId
1 2 1
2 2 2
3 1 3
4 5 4
5 3 2
6 5 4
目标:对于 CustomerArticleMark 的每一行,关联包含该商品的相应销售订单代码。
规则:
从最后一张表开始,期望的结果应该是这个:
决赛桌 - 期望的结果。
Id (of CustomerArticleMark) FinalCustomer MainArticle SALES ORDER Code
1 BOSS DVD X45
1 BOSS DVD Y74
2 BOSS SanDisk Y74
3 XPTO CD (there is no o. line with article 3)
4 VALLEY SPAM (there is no o. line with article 4)
5 TREND SanDisk (no final customer id5 in Order)
6 VALLEY SPAM XY0
它应该出现所有这 7 行。仅在 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,但应该显示销售订单代码为空。
差异用星号标记。怎样才能得到我们想要的结果呢? 感谢您的关注。
尝试将 where 子句移至连接条件中,如下所示 -
LEFT JOIN {Order} ON {Order}.[Id] = {SalesOrderLine}.[OrderId]
AND {Order}.[FinalCustomerId] = {CustomerArticleMark}.[FinalCustomerId]
原因是,对于
OUTER JOIN
,WHERE
子句在内表上的 JOIN
子句之后进行评估 - 在我们的例子中是 {Order}
。因此,尽管 LEFT (OUTER) JOIN 带来了所需的行,但 WHERE 子句正在过滤掉 NULL