我有这样的疑问
SELECT *
FROM table1 as t1
WHERE (t1.phone != "" OR t1.sms_phone != "")
and t1.docType in (1,2,3)
and not exists (select id from table2 where product_id=1 and doc_id=t1.id);
而我想用JOIN来替换带有“不存在”的部分,所以我尝试了这种方法:
SELECT *
FROM table1 as t1
LEFT OUTER JOIN table2
ON table2.doc_id = t1.id
AND table2.product_id = 1
and table2.id IS NULL
WHERE (t1.phone != "" OR t1.sms_phone != "")
and t1.docType in (1,2,3);
但第二个查询返回的记录要多得多。
2条答案
按热度按时间kmbjn2e31#
它是如何工作的(正式地,从用户的Angular 来看)?
1.我们取表1并选择与
(t1.phone != "" OR t1.sms_phone != "") AND t1.docType in (1,2,3)
匹配的行,因为这些条件只处理表1。不匹配的行将被逐出。1.我们取表2并选择与
t2.product_id=1
匹配的行,因为此条件只处理表2。不匹配的行将被逐出。1.现在,我们使用
t2.doc_id=t1.id
组合这些行。t2中不匹配的行将被逐出。1.现在,根据
t2.doc_id IS NULL
,我们仅选择t1中没有t2中的配对行的那些行。根据形式执行逻辑,#1必须在#3和#4之间执行,但这不会影响结果(无论如何,这些行都会被弹出),所以我把它放在最前面。
mznpcxlj2#
我认为在第二个查询中有一个错误,并且“FROM table1 as t1office_id”部分不属于这个查询。
当使用外连接时,过滤产生的结果会因i的位置而有所不同。
基本上,您的查询是“将t1与table2中除.....之外的所有行进行外部连接"。这将使您获得等于或多于t1行数的行数。
您需要考虑的是连接所有行并在AFTERWARDS后过滤它们。要实现这一点,您必须将过滤子句移到查询的WHERE部分。请尝试以下操作: