2013-01-17 119 views
1

我有一個簡單的應用程序,用於跟蹤食客和他們最喜歡的口味和甜點。 records表只是餐館的名稱和ID,mid表跟蹤甜點和味道(再次通過鏈接到另一個值表的ID)。連接表上的多個WHERE子句

CREATE TABLE IF NOT EXISTS `records` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; 


INSERT INTO `records` (`id`, `name`) VALUES 
(1, 'Jimmy Jones'), 
(2, 'William Henry'); 


CREATE TABLE IF NOT EXISTS `mid` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `diner` int(11) NOT NULL, 
    `dessert` int(11) NOT NULL DEFAULT '0', 
    `flavor` int(11) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ; 


INSERT INTO `mid` (`id`, `diner`, `dessert`, `flavor`) VALUES 
(1, 1, 3, 0), 
(2, 1, 2, 0), 
(3, 1, 15, 0), 
(4, 1, 0, 1), 
(5, 2, 3, 0), 
(6, 2, 6, 0), 
(7, 2, 0, 4), 
(8, 1, 34, 0), 
(9, 2, 0, 4), 
(10, 2, 0, 22); 

我有點由什麼應該是一個簡單query--我想從records表,其中某些甜點或香味的要求得到滿足所有ID難倒:

SELECT a.id 
FROM records AS a 
JOIN mid AS b ON a.id = b.diner 
WHERE b.dessert IN (3,2,6) 
AND b.flavor IN (4,22) 

這個查詢即使存在與where子句匹配的記錄,也不會返回任何行。我很確定我錯過了JOIN,但我已經嘗試了INNER,OUTER,LEFT和RIGHT,但沒有成功。

有人能讓我走上正確的軌道,並解釋我錯過了什麼嗎?

感謝

+0

將包含語句的語句換成語句或使其成爲語句? –

+1

我想謙卑地建議你給你的表格描述性/有意義的名字。我相信你這樣做會讓生活變得更容易。我會打電話給存放食客餐桌的餐桌,我可能會說另一個餐桌,我不知道,'餐'?很難說這些數據應該以'mid'爲基礎。這將使您不僅更容易思考問題,而且更容易讓其他人幫助您,更容易讓未來的開發人員(可能意味着您的未來自己)維護您的代碼。 –

+0

這似乎也許你應該有一個'甜點'表,一個'味道'表,然後'甜點_味道'表。確切知道你試圖存儲什麼是有幫助的。 –

回答

0

你似乎想要食客有組合。這裏有一種方法:

select diner 
from records 
group by diner 
having max(b.dessert = 3) = 1 and 
     max(b.dessert = 2) = 1 and 
     max(b.dessert = 6) = 1 and 
     max(b.flavor = 4) = 1 and 
     max(b.flavor = 22) = 1 

這回答您的評論:

select diner 
from records 
group by diner 
having max(case when b.dessert in (2, 3, 6) then 1 esle 0 end) = 1 and 
     max(case when b.dessert in (4, 22) then 1 else 0 end) = 1 

如果你只是尋找一個符合條件,使用記錄:

select r.*, d.name 
from records r join 
    diner d 
    on r.diner = d.id 
where b.dessert IN (3,2,6) AND b.flavor IN (4,22) 

如果這是你想要的,查詢中的連接條件是錯誤的(a.id應該是a.diner)。

+0

我想我明白你在說什麼。我猜我需要知道是否有一種方法可以讓同一個表「加入」兩次,也許是別名或別的東西,這樣我就可以得到有甜點IN(1,2,3)和IN(3, 4,5)(顯然是任意數字) – user101289

+0

@ user101289。 。 。我以爲你可能想看一個小餐館的所有記錄。在我編輯的答案中,第二個查詢回答您評論中的問題。 –

+0

謝謝!有一個'JOIN'需要嗎? – user101289

0

您的SQL語句是好的,但你的樣本記錄不符合你的條件,這將匹配應該是這樣的

dessert flavor 
3  4 
3  22 
2  4 
2  33 
6  4 
6  22 

您輸入記錄的非記錄有任何這些組合

0

您的WHERE條件不適合「中」表中的任何記錄。

沒有在(3,2,6)和(4,22)中有甜點的記錄,所以查詢(正確)不返回任何結果。

0

您沒有任何符合條件的記錄。

(1, 1, 3, 0) - Matches dessert IN (3,2,6) 
(2, 1, 2, 0) - Matches dessert IN (3,2,6) 
(3, 1, 15, 0) 
(4, 1, 0, 1) 
(5, 2, 3, 0) - Matches dessert IN (3,2,6) 
(6, 2, 6, 0) - Matches dessert IN (3,2,6) 
(7, 2, 0, 4) - Matches flavor IN (4,22) 
(8, 1, 34, 0) 
(9, 2, 0, 4) - Matches flavor IN (4,22) 
(10, 2, 0, 22) - Matches flavor IN (4,22) 

也許你的意思是OR?

SELECT a.id 
FROM records AS a 
JOIN mid AS b ON a.id = b.diner 
WHERE b.dessert IN (3,2,6) 
OR b.flavor IN (4,22) 

應該返回7個結果。

此外,你對JOIN的想法是一個紅色的鯡魚。 LEFT和RIGHT的區別在於,當join子句與它們之間的記錄不匹配時,哪個表優先。 INNER和OUTER之間的區別就是當兩個表之間沒有匹配的記錄時發生的情況。試試這個explanative article from coding horror瞭解更多關於連接的細節(在另一個SO問題中有助於我指出,呵呵)。