2013-08-23 32 views
1

在我的rails應用程序中,我有兩個表 - device_portscircuits。我的目標是獲得device_ports的列表,其id未被用於circuits表的physical_port_id列中。MySQL - 選擇行的id不存在作爲另一個表中的外鍵

我在其他表格上做過類似的事情,但這裏我的查詢只返回一行,當它返回23行時 - 這個設備有24個設備端口,一個正在使用。

select id, name, device_id, multiuse 
from device_ports 
where (device_id = 6 and multiuse = 1) 
or device_ports.id not in (select physical_port_id from circuits) 

所以這個查詢獲取所有多用途端口(這樣即使ID是外鍵引用,該行仍然應該退還),並應該得到的所有行DEVICE_ID是6,但沒有被引用電路,但只有多用途行正在返回。

從查詢結果是

id | name | device_id | multiuse 
------------------------------------ 
268 | test-1 |  6  | 1 

我曾嘗試創建一個SQL小提琴,但在構建似乎只是超時。

CREATE TABLE `device_ports` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `device_id` int(11) DEFAULT NULL, 
    `name` tinytext, 
    `speed` tinytext, 
    `multiuse` tinyint(1) DEFAULT NULL, 
    `created_at` datetime DEFAULT NULL, 
    `updated_at` datetime DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `id` (`id`) 
) ENGINE=MyISAM AUTO_INCREMENT=291 DEFAULT CHARSET=latin1; 

INSERT INTO `device_ports` (`id`, `device_id`, `name`, `speed`, `multiuse`, `created_at`, `updated_at`) 
*emphasized text*VALUES 
(1, 1, 'Test Device Port', '100', 0, NULL, NULL), 
(2, 1, 'Test Port 2', '300', 1, NULL, NULL), 
(289, 6, 'test-22', '100', 0, NULL, NULL), 
(290, 6, 'test-23', '100', 0, NULL, NULL), 
(288, 6, 'test-21', '100', 0, NULL, NULL), 
(287, 6, 'test-20', '100', 0, NULL, NULL), 
(286, 6, 'test-19', '100', 0, NULL, NULL), 
(284, 6, 'test-17', '100', 0, NULL, NULL), 
(285, 6, 'test-18', '100', 0, NULL, NULL), 
(283, 6, 'test-16', '100', 0, NULL, NULL), 
(282, 6, 'test-15', '100', 0, NULL, NULL), 
(281, 6, 'test-14', '100', 0, NULL, NULL), 
(280, 6, 'test-13', '100', 0, NULL, NULL), 
(279, 6, 'test-12', '100', 0, NULL, NULL), 
(278, 6, 'test-11', '100', 0, NULL, NULL), 
(277, 6, 'test-10', '100', 0, NULL, NULL), 
(276, 6, 'test-9', '100', 0, NULL, NULL), 
(275, 6, 'test-8', '100', 0, NULL, NULL), 
(274, 6, 'test-7', '100', 0, NULL, NULL), 
(273, 6, 'test-6', '100', 0, NULL, NULL), 
(272, 6, 'test-5', '100', 0, NULL, NULL), 
(271, 6, 'test-4', '100', 0, NULL, NULL), 
(270, 6, 'test-3', '100', 0, NULL, NULL), 
(269, 6, 'test-2', '100', 0, NULL, NULL), 
(268, 6, 'test-1', '100', 1, NULL, NULL), 
(267, 6, 'test-0', '100', 0, NULL, NULL); 


CREATE TABLE `circuits` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `organisation_id` int(11) DEFAULT NULL, 
    `physical_port_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=248 DEFAULT CHARSET=latin1; 

INSERT INTO `circuits` (`id`, `organisation_id`, `physical_port_id`) 
VALUES (1, 125, 267); 
+0

我想在我結束它上面貼的代碼是給我25個記錄.. –

+0

你的第一個表是MyISAM和第二個表InnoDB的..我希望沒有發揮作用.. –

+0

@Sonali以及斑點......不確定這是否會產生影響,25個聲音是否正確,因爲這會給你23個來自設備6的結果和兩個來自設備1的結果?我忘了將'AND device_id = 6'添加到查詢中以將其過濾掉。 – martincarlin87

回答

7

你可以嘗試使用LEFT OUTER JOIN:

SELECT DISTINCT d.id, d.name, d.device_id, d.multiuse 
FROM device_ports d 
LEFT OUTER JOIN circuits c ON c.physical_port_id = d.id 
WHERE 
(c.physical_port_id IS NULL AND d.device_id = 6) 
OR (d.multiuse = 1 AND d.device_id = 6) 
ORDER BY d.id 

這有幾種查詢技術,看看What's the difference between NOT EXISTS vs. NOT IN vs. LEFT JOIN WHERE IS NULL?

+0

我接近你的原始答案,但編輯只是給了我一行。這是我最近的嘗試:'SELECT d.id,d.name,d.device_id,d.multiuse FROM device_ports d LEFT OUTER JOIN circuits c ON c.physical_port_id = d.id WHERE(c.physical_port_id IS NULL AND ORDER BY ID ASC'幾乎是完美的,唯一的'錯誤'是,如果一個多用途端口IS引用它會出現兩次結果。可能只是在ID上分組,但希望查詢更聰明 – martincarlin87

+0

好的。我編輯了我的答案以使用WHERE子句。我添加了DISTINCT,是否解決了你重複的行? –

+0

完美,謝謝 – martincarlin87

0
SELECT p.* 
    FROM device_ports p 
    LEFT 
    JOIN circuits c 
    ON c.physical_port_id = p.id 
WHERE p.device_id = 6 
    AND multiuse = 1 
    AND c.id IS NULL; 
相關問題