首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在这个带有左联接和筛选器的select查询中,我做错了什么?

在这个带有左联接和筛选器的select查询中,我做错了什么?
EN

Stack Overflow用户
提问于 2019-06-19 18:27:03
回答 2查看 229关注 0票数 0

使用Actian v13:

我试图连接两个表,并通过几个条件过滤结果集。一个表是客户销售历史记录。另一张表将客户与购买组联系起来。并不是所有的客户都是在一个购买集团,所以我做一个左加入,以获得所有可能的销售历史结果。我不希望结果包括在购买集团'SALREP‘任何人,但我确实希望看到客户谁不是在任何购买组。此外,所谓的“运费”部分正在从结果中筛选出来。

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

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

以下是查询:

代码语言:javascript
复制
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之后开具发票的任何产品,而不包括名为“运费”的部分,也不应包括名为“SALREP”的组内的客户。然而,实际的结果集是不完整的。例如:

代码语言:javascript
复制
CUSTOMER | GROUP_CUST | DATE_INVOICE  | PART   | etc.
-----------------------------------------------------
ABC      |  A12       |  2019-06-14   | WIDGET
DEF      |  A12       |  2019-06-14   | GEAR

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

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

代码语言:javascript
复制
CUSTOMER | GROUP_CUST | DATE_INVOICE  | PART   | etc.
-----------------------------------------------------
ABC      |  A12       |  2019-06-14   | WIDGET
DEF      |  A12       |  2019-06-14   | GEAR
GHI      |            |  2019-06-15   | WIDGET

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-07 19:43:42

谢谢https://mode.com/resources/sql-tutorial/sql-joins-where-vs-on/。本文提到,“WHERE子句中的筛选也可以过滤空值,因此我们增加了一行以确保包含空值。”

这使我测试并认识到,当对正确的表进行筛选时,有必要显式地声明将包含该筛选列的空值(不匹配的行),否则这些不匹配的行将从结果集中删除。我还发现,有必要将过滤器对放在括号或结果集“爆炸性”中。我进行了测试,发现只有在对右表进行过滤时才需要这样做;对左边表的筛选没有这个问题(很明显)。

最后答案:

代码语言:javascript
复制
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)

票数 0
EN

Stack Overflow用户

发布于 2019-06-19 18:29:29

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

代码语言:javascript
复制
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;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56673783

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档