MySQL在同一個表上的多個連接問題
使用 MySQl 5.6 作為我的數據庫,我試圖在另一個連接的表上加入一個表兩次,但我得到了重複的結果,而不是合併的行。
所以,我有一個檢查表,可以將檢查分配給一個或多個儲存在 check_assigned_area 表中的區域。此表中的條目可以是位置或部門。位置是部門的父級。
所以,我通過 PK(check_id)將 checks_assigned_area 表加入到檢查表中
然後我嘗試加入區域表兩次,一次用於位置,一次用於部門,具體取決於 area_level。3是一個位置,4是一個部門。
但不是查詢返回帶有位置名稱和部門名稱的單行。它返回 2 個單獨的行,並且沒有填充部門名稱。
我嘗試了各種左/內/右連接組合、不同、分組方式,但我無法正確獲取數據。
我什至可以這樣做嗎?我的邏輯告訴我是的,但實際上我無法讓它工作。
如果我可以讓它輸出我需要的數據有什麼想法嗎?
這是我的數據和查詢的 SQL 小提琴http://sqlfiddle.com/#!9/63d6ce/4
檢查表:
+----------+---------------+------------+------------+--------+----------+ | check_id | check_type_id | 到期 | created_by | 狀態 | 簽收 | +----------+---------------+------------+------------+--------+----------+ | 19335 | 43 | 18/09/2017 | 3 | 1 | 1 | | 19336 | 4 | 19/09/2017 | 3 | 1 | 1 | | 19358 | 62 | 21/09/2017 | 47336 | 1 | 1 | +----------+---------------+------------+------------+--------+----------+
檢查分配區域表:
+------------------------+---------------+----------+ | check_assigned_area_id | check_area_id | check_id | +------------------------+---------------+----------+ | 18801 | 9 | 19335 | | 18802 | 816 | 19336 | | 18803 | 816 | 19336 | | 18804 | 8091 | 19358 | | 18835 | 8092 | 19358 | +------------------------+---------------+----------+
詢問:
SELECT `c`.*, `t`.`check_name`,`a`.`check_area_id`,`l`.`area_name` AS 'location_name', `d`.`area_name` AS 'dept_name' FROM `checks` `c` LEFT JOIN `check_assigned_areas` `a` ON `a`.`check_id` = `c`.`check_id` LEFT JOIN `areas` `l` ON `l`.`area_id` = `a`.`check_area_id` AND `l`.`area_level` = '3' LEFT JOIN `areas` `d` ON `d`.`area_id` = `a`.`check_area_id` AND `d`.`area_level` = '4' LEFT JOIN `check_types` `t` ON `t`.`check_type_id` = `c`.`check_type_id` WHERE `c`.`org_id` = '297' AND `c`.`status` != '0' AND `c`.`due` <= '2017-09-21'
我調整了你提供的小提琴,我相信我現在得到了你想要的結果。這是更新的小提琴。
更新後的查詢是:
SELECT `c`.*, `t`.`check_name`,`al`.`check_area_id` as 'loc_check_area_id',`l`.`area_name` AS 'location_name',`ad`.`check_area_id` as 'dept_check_area_id', `d`.`area_name` AS 'dept_name' FROM `checks` `c` LEFT JOIN (`check_assigned_areas` `al` INNER JOIN `areas` `l` ON `l`.`area_id` = `al`.`check_area_id` AND `l`.`area_level` = '3' ) ON `al`.`check_id` = `c`.`check_id` LEFT JOIN (`check_assigned_areas` `ad` INNER JOIN `areas` `d` ON `d`.`area_id` = `ad`.`check_area_id` AND `d`.`area_level` = '4' ) ON `ad`.`check_id` = `c`.`check_id` LEFT JOIN `check_types` `t` ON `t`.`check_type_id` = `c`.`check_type_id` WHERE `c`.`org_id` = '297' AND `c`.`status` != '0' AND `c`.`due` <= '2017-09-21' ;
這是結果(截斷以僅顯示位置和部門數據)。
check_id | ... | loc_check_area_id | location_name | dept_check_area_id | dept_name ----------+ ... +-------------------+---------------+--------------------+-------------- 19358 | ... | 8091 | Luton Office | 8092 | Development 19357 | ... | (null) | (null) | (null) | (null)
由於具有有效位置和部門的支票有兩個單獨
check_assigned_areas
的行,因此從邏輯上講,您將獲得該支票的兩行。一行代表一個位置,一個代表部門。因此,您為這些值獲得了單獨的行。我更改了查詢,因此不是單獨
LEFT JOIN
的 s forcheck_assigned_areas
,areas
即位置,areas
即部門,而是一個LEFT JOIN
forcheck_assigned_areas
和areas
,即位置,以及一個單獨LEFT JOIN
的 forcheck_assigned_areas
和areas
,即部門。在這兩個LEFT JOIN
s 中,check_assigned_areas
那組areas
行被INNER JOIN
編輯在一起。這意味著您將獲得與此檢查相關的位置的一(組)行,以及部門的一行。
請注意,其中涉及兩個
check_assigned_areas.check_area_id
值,因此我將check_area_id
from the location 和check_area_id
from the department 顯示為兩個單獨的列。另請注意,如果有多個
areas
與支票相關的位置和/或多個部門,您將看到找到的位置和部門的每個可能組合對應的一行;這就是為什麼寫上一段是為了允許這樣。但是,如果有 0 個或 1 個位置,以及 0 個或 1 個部門,您將得到一行,其中包含找到的位置和部門。