2010-12-04 65 views
2

我有三個表有點像下面的例子:選擇條目基地在另一個表的MySQL

CARS

carId carName 
----- -------- 
1  a 
2  a 
3  b 
4  b 
5  b 
6  c 
7  d 
8  e 
9  f 
10  g 

CAR NAMES

nameId carName 
------ ------- 
1  a 
2  b 
3  c 
4  d 
5  e 
6  f 
7  g 

CAR ATTRIBUTES

nameId attribute 
------ --------- 
1  FAST 
1  SMALL 
1  SHINY 
2  BIG 
2  SLOW 
3  EXPENSIVE 
4  SHINY 
5  FAST 
5  SMALL 
6  FAST 
7  SMALL 

我一直在試圖建立一個查詢來獲取它既有快而小的屬性carId,但一直沒有運氣。做這個的最好方式是什麼?

在這個例子中,結果將被carID 1和carName一個其中attribute =小和屬性= FAST

回答

3

尋找這樣的? (未經測試)

select a.carId 
    from cars  a 
    join car_names b using(carName) 
    join car_attribs c using(nameId) 
where c.attribute in('SMALL', 'FAST') 
group 
    by a.carId 
having count(distinct c.attribute) = 2; 
+0

+1 ...好答案。測試和工作:) – 2010-12-04 17:55:08

2

這是不被視爲一個詳盡的答案,但在話題上僅僅只有幾個點。

由於問題標有[mysql]標籤,讓我說,一般來說,relational databases並不特別適用於使用EAV模型存儲數據。您仍然可以在SQL中設計一個EAV模型,但是您將不得不犧牲關係數據庫的許多優勢。不僅你不能強制引用完整性,爲值使用SQL數據類型並強制實施強制屬性,但即使是非常基本的查詢(比如這個)也很難編寫。事實上,爲了克服這個限制,一些EAV解決方案依賴於數據複製,而不是與相關的表格結合,正如你可以想象的那樣,它有很多缺點。

如果您確實需要無模式設計,您可以考慮使用NoSQL解決方案。儘管EAV相對於關係數據庫的弱點也適用於NoSQL替代品,但您將獲得傳統SQL數據庫難以實現的額外功能。例如,通常NoSQL數據存儲的縮放比關係數據庫容易得多,僅僅是因爲它們被設計用於解決某種可伸縮性問題,並且他們故意丟棄使伸縮變得困難的功能。

另一方面,@Ronnis' solution應該工作,並且通常使用COUNT()是解決您的問題的一種常用技術。

測試用例:

CREATE TABLE `cars` (carId int, carName char(1)); 
CREATE TABLE `car_names` (nameId int, carName char(1)); 
CREATE TABLE `car_attributes` (nameId int, attribute varchar(40)); 

INSERT INTO `cars` VALUES (1, 'a'); 
INSERT INTO `cars` VALUES (2, 'a'); 
INSERT INTO `cars` VALUES (3, 'b'); 
INSERT INTO `cars` VALUES (4, 'b'); 
INSERT INTO `cars` VALUES (5, 'b'); 
INSERT INTO `cars` VALUES (6, 'c'); 
INSERT INTO `cars` VALUES (7, 'd'); 
INSERT INTO `cars` VALUES (8, 'e'); 
INSERT INTO `cars` VALUES (9, 'f'); 
INSERT INTO `cars` VALUES (10, 'g'); 


INSERT INTO `car_names` VALUES (1, 'a'); 
INSERT INTO `car_names` VALUES (2, 'b'); 
INSERT INTO `car_names` VALUES (3, 'c'); 
INSERT INTO `car_names` VALUES (4, 'd'); 
INSERT INTO `car_names` VALUES (5, 'e'); 
INSERT INTO `car_names` VALUES (6, 'f'); 
INSERT INTO `car_names` VALUES (7, 'g'); 


INSERT INTO `car_attributes` VALUES (1, 'FAST'); 
INSERT INTO `car_attributes` VALUES (1, 'SMALL'); 
INSERT INTO `car_attributes` VALUES (1, 'SHINY'); 
INSERT INTO `car_attributes` VALUES (2, 'BIG'); 
INSERT INTO `car_attributes` VALUES (2, 'SLOW'); 
INSERT INTO `car_attributes` VALUES (3, 'EXPENSIVE'); 
INSERT INTO `car_attributes` VALUES (4, 'SHINY'); 
INSERT INTO `car_attributes` VALUES (5, 'FAST'); 
INSERT INTO `car_attributes` VALUES (5, 'SMALL'); 
INSERT INTO `car_attributes` VALUES (6, 'FAST'); 
INSERT INTO `car_attributes` VALUES (7, 'SMALL'); 

結果:

SELECT a.carId 
FROM  cars a 
JOIN  car_names b USING(carName) 
JOIN  car_attributes c USING(nameId) 
WHERE  c.attribute IN('SMALL', 'FAST') 
GROUP BY a.carId 
HAVING COUNT(distinct c.attribute) = 2; 

+-------+ 
| carId | 
+-------+ 
|  1 | 
|  2 | 
|  8 | 
+-------+ 
3 rows in set (0.00 sec) 
相關問題