0

使用 Actian PSQL v13:

我正在尝试加入两个表并按一些标准过滤结果集。一张表是客户销售历史。另一个表将客户与购买组相关联。并非所有客户都在购买组中,所以我正在做一个左连接以获得所有可能的销售历史结果。我不希望结果包括购买组“SALREP”中的任何人,但我确实希望看到不属于任何购买组的客户。此外,所谓的“运费”部分正在从结果中过滤掉。

我遇到的问题是,当我过滤掉“SALREP”组时,只会选择购买组中的客户;不属于购买组的所有客户都丢失了。

我已经通过注释掉“SALREP”的过滤器来测试这一点,结果集确实包括不属于购买组的客户。我还尝试使用不同的过滤方法,以防 Actian PSQL 很挑剔。例如,我尝试了不同的“不等于”方法,例如!=,not()<>; 问题仍然存在。另外,我用过同样left joinleft outer join问题。

这是查询:

select T2.GROUP_CUST, T1.DATE_INVOICE, T1.SALESPERSON, T1.CUSTOMER, T1.PRODUCT_LINE, T1.PART, T1.DESCRIPTION, T1.QTY_SHIPPED, T1.EXTENSION 
from ORDER_HIST_LINE T1 
left join BUYING_GROUP T2 on T1.CUSTOMER=T2.CUSTOMER 
where DATE_INVOICE > '2019-06-13' and PART != 'FREIGHT'
and T2.GROUP_CUST != 'SALREP' 
and T1.CUSTOMER in ('ABC', 'DEF', 'GHI')
order by T1.CUSTOMER;

预期结果集应包括 2019-06-13 之后开具发票的任何内容,不包括名为“FREIGHT”的部分,并且在名为“SALREP”的组中没有客户。但是,实际结果集是不完整的。例如:

CUSTOMER | GROUP_CUST | DATE_INVOICE  | PART   | etc.
-----------------------------------------------------
ABC      |  A12       |  2019-06-14   | WIDGET
DEF      |  A12       |  2019-06-14   | GEAR

基本上,所有不属于任何购买组的客户都被排除在外。

注释掉该部分and T2.GROUP_CUST != 'SALREP'并找到预期的结果。例如:

CUSTOMER | GROUP_CUST | DATE_INVOICE  | PART   | etc.
-----------------------------------------------------
ABC      |  A12       |  2019-06-14   | WIDGET
DEF      |  A12       |  2019-06-14   | GEAR
GHI      |            |  2019-06-15   | WIDGET

我正在考虑为选择查询创建左联接,该查询首先从购买组中删除“SALREP”,但这不允许结果集识别并从该组中删除任何人。前任。:left join (select * from BUYING_GROUP where GROUP_CUST != 'SALREP') T2

8/7/19 进一步尝试:我在 MySQL v5.0.12 上发现了同样的困境。我可以留下连接表以产生不匹配的结果。我可以根据那些不匹配的结果过滤左表,而不会意外丢失任何东西。但是,如果不让所有不匹配的行消失,我就无法根据这些不匹配的结果过滤正确的表。

4

2 回答 2

1

您需要在子句中的第二个表上设置条件。ON唯一明显的参考是T2.GROUP_CUST,但它也可能适用于DATE_INVOICEPART

from ORDER_HIST_LINE T1 left join
     BUYING_GROUP T2
     on T1.CUSTOMER = T2.CUSTOMER and
        T2.GROUP_CUST <> 'SALREP'
where DATE_INVOICE > '2019-06-13' and
      PART <> 'FREIGHT' and
      T1.CUSTOMER in ('ABC', 'DEF', 'GHI')
order by T1.CUSTOMER;
于 2019-06-19T18:29:29.023 回答
0

感谢https://mode.com/resources/sql-tutorial/sql-joins-where-vs-on/。文章提到,“在 WHERE 子句中过滤也可以过滤空值,因此我们添加了一个额外的行来确保包含空值。”

这使我开始测试并意识到,在针对正确的表进行过滤时,有必要明确声明要包含该过滤列的 NULL 值(不匹配的行),否则将从结果集中删除那些不匹配的行。我还发现有必要将过滤器对放在括号中或结果集“爆炸”。我测试并发现只有在过滤正确的表时才需要这样做;过滤左表没有这个问题(显然)。

最终答案:

select T2.GROUP_CUST, T1.DATE_INVOICE, T1.SALESPERSON, T1.CUSTOMER, T1.PRODUCT_LINE,             
T1.PART, T1.DESCRIPTION, T1.QTY_SHIPPED, T1.EXTENSION 
from ORDER_HIST_LINE T1 
left join BUYING_GROUP T2 on T1.CUSTOMER=T2.CUSTOMER 
where DATE_INVOICE > '2019-06-13' and PART != 'FREIGHT' 
and (T2.GROUP_CUST != 'SALREP' or T2.GROUP_CUST is null) 
and T1.CUSTOMER in ('ABC', 'DEF', 'GHI') 
order by T1.CUSTOMER;

注意线and (T2.GROUP_CUST != 'SALREP' or T2.GROUP_CUST is null)

于 2019-08-07T19:43:42.060 回答