前言
永遠相信美好的事情即將發生
背景
前段時間碰到過這樣一個問題,查詢出一家店鋪在2020年和2019年活動類型爲’xxx’的日期,因歷史原因,2019年的活動和2020年的活動分別存儲在兩張表中,需要通過外連接將查詢結果放在一起展示,最終要的結果大概長這樣:
2019年日期 | 2019年活動 | 2020年日期 | 2020年活動 |
---|---|---|---|
2019/01/05 | xxx節 | 2020/02/01 | xxx節 |
2019/03/12 | xxx節 | 2020/04/10 | xxx節 |
2019/07/19 | xxx節 | 2020/06/05 | xxx節 |
2020/09/09 | xxx節 | ||
2020/12/15 | xxx節 |
踩坑
剛接手需求的時候,我的內心是這樣的
我祭出我小學5年級的SQL功底,通過費馬定理,泰勒公式,拉格朗日定理以及洛必達法則,再結合我眼花繚亂的一指禪打字技術,終於不負衆望的沒寫出來
問題的原因是什麼呢,單獨查詢2019年活動類型爲’xxx’的日期很簡單,單獨查詢2020年活動類型爲’xxx’的日期也很簡單,那麼關聯條件呢?肯定會有憨憨說用店鋪id關聯啊,或者說用活動類型關聯啊
左邊的查詢結果和右邊的查詢結果已經查詢出了這家店鋪分別在2020年和2019年活動類型爲’xxx’的日期,無論是通過店鋪id還是活動類型關聯都會做笛卡爾積,所以需要另尋其他關聯條件
解決
抱着不恥下問,不對,是不恥上問的學習態度,請教了我們的老大,當時的情景大概是這樣
大佬給我指了條明路,行號關聯查詢,然後親自指導了一番,在大牛的光輝照耀以及我的不懈努(bai)力(du)下,我終於不負衆望的寫了出來,SQL簡化後大體如下:
SELECT
*
FROM
(
SELECT
@rownuma := @rownuma + 1 AS num_1, table_a.*
FROM table_a,
( SELECT @rownuma := 0 )
) a
LEFT JOIN (
SELECT
@rownumb := @rownumb + 1 AS num_2, table_b.*
FROM table_b,
( SELECT @rownumb := 0 )
) b ON a.num_1 = b.num_2
給左邊的查詢結果和右邊的查詢結果分別添加一個行號,行號都是從1開始,這樣就可以做到左邊的數據集和右邊的數據集進行關聯,但是
當左邊結果集的行數小於等於右邊的結果時,這種寫法沒有任何的問題,那麼當右邊的結果集行數大於左邊呢,沒錯,它只能顯示和左邊行數一樣的部分,那麼問題來了,當左右結果集行數不確定的時候怎麼辦呢?沒錯,使用union連接一下左外連接和右外連接的結果集就o的k了
SELECT
*
FROM
(
SELECT
@rownuma := @rownuma + 1 AS num_1, table_a.*
FROM table_a,
( SELECT @rownuma := 0 )
) a
LEFT JOIN (
SELECT
@rownumb := @rownumb + 1 AS num_2, table_b.*
FROM table_b,
( SELECT @rownumb := 0 )
) b ON a.num_1 = b.num_2
UNION
SELECT
*
FROM
(
SELECT
@rownumc := @rownumc + 1 AS num_1, table_a.*
FROM table_a,
( SELECT @rownumc := 0 )
) a
RIGHT JOIN (
SELECT
@rownumd := @rownumd + 1 AS num_2, table_b.*
FROM table_b,
( SELECT @rownumd := 0 )
) b ON a.num_1 = b.num_2
注意點
使用行號名的時候切記不要使用相同的名稱,應該像這樣
如果使用了相同的名稱,你會發現關聯之後的結果集某一列一開始會有很多的空白,別問我爲什麼知道,以前有一個憨憨就這樣被坑了半天還不知道原因
總結
實際開發中碰到這種類似無規則關聯的情景其實也比較少,但由於MySQL中缺少很多SQL關聯的方法,就導致需要想點其他的方法去解決,希望各位看了我的踩坑之旅後能少踩點雷。
與諸君共勉