Contents

SQL ON /WHERE差別

Contents

最近在 left join 使用 on 做篩選
結果出來跟我想要的不太一樣
後來有爬文找到原因

1
from a left join b on a.id=b.id and b.word = 'xxxx'

結果跑出來東西是多筆

其實以上結果的關鍵原因就是 left join,right join,full join 的特殊性,不管 on 上的條件是否為真都會返回 left 或 right 表中的記錄,full 則具有 left 和 right 的特性的並集。 而 inner join 沒這個特殊性,則條件放在 on 中和 where 中,返回的結果集是相同的。
http://blog.sina.com.cn/s/blog_6826662b0101atu1.html

http://louis176127.pixnet.net/blog/post/186150706-sql-%E6%A2%9D%E4%BB%B6%E5%BC%8F%E5%AF%AB%E5%9C%A8on%E4%BB%A5%E5%8F%8Awhere%E7%9A%84%E5%B7%AE%E5%88%A5

2018-12-24
子查詢 join 無法抓到外面的表
終於知道為什麼子查詢沒辦法抓取外面的表 | 程式狂想筆記

2018-12-25

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
SELECT
                      xxx,ooo
                    FROM table1 ous
                      LEFT JOIN table2 vc
                        ON  vc.user_id = 'dddddd'
                        AND vc.type = 'ADD'
                        AND vc.cancel IS NULL
AND DATE_FORMAT(vc.end_date, '%Y-%m-%d') >= DATE_FORMAT('2018-01-01', '%Y-%m-%d') AND DATE_FORMAT(START_DATE, '%Y-%m-%d') < DATE_FORMAT('2018-11-02' , '%Y-%m-%d')
                    WHERE  ous.uid = 'dddddd'

                    ORDER BY vc.sid DESC LIMIT 1

移至 WHERE 結果是不一樣的!!!
因為是 LEFT JOIN
所以 ous 不管做甚麼條件,都不會消失
vc 會變成 null

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
SELECT
                      xxx,ooo
                    FROM table1 ous
                      LEFT JOIN table2 vc
                        ON  vc.user_id = 'dddddd'
                        AND vc.type = 'ADD'
                        AND vc.cancel IS NULL
                    WHERE  ous.uid = 'dddddd'
AND DATE_FORMAT(vc.end_date, '%Y-%m-%d') >= DATE_FORMAT('2018-01-01', '%Y-%m-%d') AND DATE_FORMAT(START_DATE, '%Y-%m-%d') < DATE_FORMAT('2018-11-02' , '%Y-%m-%d')

                    ORDER BY vc.sid DESC LIMIT 1

要改成

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
SELECT
                      xxx,ooo
                    FROM table1 ous
                      LEFT JOIN table2 vc
                        ON  vc.user_id = 'dddddd'
                        AND vc.type = 'ADD'
                        AND vc.cancel IS NULL
                    WHERE  ous.uid = 'dddddd'
OR (  ous.uid = 'dddddd' AND DATE_FORMAT(vc.end_date, '%Y-%m-%d') >= DATE_FORMAT('2018-01-01', '%Y-%m-%d') AND DATE_FORMAT(START_DATE, '%Y-%m-%d') < DATE_FORMAT('2018-11-02' , '%Y-%m-%d'))

                    ORDER BY vc.sid DESC LIMIT 1