Mariadb
MariaDb - 僅在存在單個右側記錄時如何確保(左)加入
我有兩張桌子需要連接在一起。但是,我只想在有 unqiue 匹配時加入記錄,而不是選擇幾個中的一個進行加入。
版本控制:
使用 MariaDB 版本 10.3.34
範例數據:
核心(左)數據
towns
id | town | postcode ----------------------------------------- 1 | Hudderfield | HD11 4ER 2 | Manchester | MN14 3JE 3 | Macklesfield | MK17 9FL 4 | Edinburgh | ED5 3MJ 5 | Liverpool | LV9 8XT
加入(右)數據
peoples
:id | names | postcode ----------------------------------------- 1 | Jimmy Saville | HD11 4ER 2 | Jason Bomb | IP14 8FK 3 | Micky Mouse | MK17 9FL 4 | Bobby Dillian | ED5 3MJ 5 | Lenny Davies | ED5 3MJ
我的 SQL:
我的初始查詢將類似於:
SELECT towns.id, towns.town, peoples.name FROM towns LEFT JOIN people ON towns.postcode = peoples.postcode
但這將包括
Edinburgh
但愛丁堡有兩個人,我只想在有一個單獨的行加入時加入。我使用 LEFT 連接,因為我需要返回所有
towns
但只返回唯一的peoples
.預期成績:
id | town | names ----------------------------------------- 1 | Hudderfield | Jimmy Saville 2 | Manchester | <null> 3 | Macklesfield | Micky Mouse 4 | Edinburgh | <null> 5 | Liverpool | <null>
我試過的
我已經嘗試
COUNT()
在 JOIN 中使用,但無法使其正常工作,SELECT towns.id, towns.town, peoples.names FROM towns LEFT JOIN people ON towns.postcode = peoples.postcode AND count(peoples.id) = 1
出現語法錯誤。
我想不出我如何才能限定這個只有在找到一個結果時才加入的加入。網際網路搜尋給了我很多更模糊和離題的參考。
我敢肯定這很簡單,但我做不到。另外,如果可能的話,我想避免子查詢?
Lennart 的視窗函式答案的另一種方法是僅對錶使用
GROUP BY
andHAVING
子句peoples
來過濾掉具有相同的子句,如下所示postcode
:SELECT towns.id, towns.town, peoples.names FROM towns LEFT JOIN ( SELECT MAX(names) AS names, postcode FROM peoples GROUP BY postcode HAVING COUNT(name) = 1 ) peoples ON towns.postcode = peoples.postcode
你應該能夠離開加入人民:
(select name, postcode from ( select name, postcode, count(1) over (partition by postcode) as cnt from peoples ) as t where cnt = 1)
IE
SELECT t.id, t.town, p.name FROM towns t LEFT JOIN (SELECT name, postcode FROM ( SELECT name, postcode , count(1) over (partition by postcode) as cnt FROM peoples ) as x WHERE cnt = 1 ) p USING (postcode)
編輯:
鑑於更新中提供的 ddl 我創建了db<>fiddle
SELECT t.id, t.town, p.names FROM towns t LEFT JOIN ( SELECT names, postcode FROM ( SELECT names, postcode , count(1) over (partition by postcode) as cnt FROM peoples ) as x WHERE cnt = 1 ) p USING (postcode);
它似乎給出了預期的結果