2014-04-10 42 views
1
CREATE TABLE `locationcodes` (
    `id` int, 
    `customer` varchar(100), 
    `locationcode` varchar(50), 
    `parentid` int 
); 

insert into locationcodes values (1, 'Test, Inc.', 'California', NULL); 
insert into locationcodes values (2, 'Test, Inc.', 'Los Angeles', 1); 
insert into locationcodes values (3, 'Test, Inc.', 'San Francisco', 1); 
insert into locationcodes values (4, 'Test, Inc.', 'Sacramento', 1); 

我想要一個父母位置及其孩子的列表。如果沒有孩子,然後再打印父父:在MySQL中,如何以最有效的方式編寫此SQL查詢?

SQL:

SELECT DISTINCT parent.locationcode as 'Parent', parent.locationcode as 'Child', 1 AS `level` 
FROM locationcodes parent 
JOIN locationcodes child ON parent.id = child.parentid 
WHERE parent.parentid IS NULL 
AND parent.customer = 'Test, Inc.' 
UNION 
SELECT DISTINCT parent.locationcode as 'Parent', child.locationcode as 'Child', 2 AS `level` 
FROM locationcodes parent 
JOIN locationcodes child ON parent.id = child.parentid 
WHERE NOT child.parentid IS NULL 
AND child.customer = 'Test, Inc.' 
ORDER BY 1, 2 

結果是正確的:

PARENT   CHILD   LEVEL 
California  California   1 
California  Los Angeles   2 
California  Sacramento   2 
California  San Francisco  2 

我的問題是我沒有有效地編寫SQL越好?

http://sqlfiddle.com/#!2/87a3d/3

+0

如何LEFT JOIN和接合 – Strawberry

+0

你不需要'WHERE NOT child.parentid IS NULL'。當它爲空時,'parent.id = child.parentid'將不匹配。 – Barmar

+0

此問題似乎是無關緊要的,因爲有關改進工作代碼的問題屬於codereview.stackexchange.com。 – Barmar

回答

1

如何只使用單個連接和一些國際單項體育聯合會內聯?

SELECT IFNULL(parent.locationcode,child.locationcode) AS 'Parent', child.locationcode AS 'Child', IF(child.parentid,2,1) AS `level` 
FROM locationcodes child 
LEFT JOIN locationcodes parent ON parent.id = child.parentid 
WHERE child.customer = 'Test, Inc.' 
ORDER BY 1, 2 

這將選擇所有(子)位置,然後嘗試在可能的情況下連接父數據。應該比使用UNION和另一個JOIN更高效(並且簡單!)。

演示:http://sqlfiddle.com/#!2/87a3d/21/0