将多个交叉表中的数据关联到一个表中

问题描述 投票:0回答:1

我使用的是 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 的每一行,关联包含该商品的相应销售订单代码。

规则:

  1. CustomerArticleMark 中的文章出现在两个订单的 5 个订单行中,因此主文章必须出现 2 次而不是 5 次;
  2. CustomerArticleMark 中的文章出现在一个订单的 5 个订单行中,因此主文章只能出现一次,而不是 5 次;
  3. CustomerArticleMark 中的文章不会出现在任何订单行中,因此主文章应该出现,但销售订单代码为空值;
  4. CustomerArticleMark 中的文章对于每个订单和订单中的每个 FinalCustomer 销售订单行中的每个不同文章都必须是唯一的。有相同商品但最终客户不同的订单。

从最后一张表开始,期望的结果应该是这个:

决赛桌 - 期望的结果。

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,但应该显示销售订单代码为空。

差异用星号标记。怎样才能得到我们想要的结果呢? 感谢您的关注。

sql database tsql sql-server-2012
1个回答
0
投票

尝试将 where 子句移至连接条件中,如下所示 -

LEFT JOIN {Order} ON {Order}.[Id] = {SalesOrderLine}.[OrderId]
                AND {Order}.[FinalCustomerId] = {CustomerArticleMark}.[FinalCustomerId]

原因是,对于

OUTER JOIN
WHERE
子句在内表上的
JOIN
子句之后进行评估 - 在我们的例子中是
{Order}
。因此,尽管 LEFT (OUTER) JOIN 带来了所需的行,但 WHERE 子句正在过滤掉
NULL

© www.soinside.com 2019 - 2024. All rights reserved.