Выбор записей основывается на нескольких записях в другой таблице MySQL - PullRequest
2 голосов
/ 04 декабря 2010

У меня есть три таблицы, вроде примера ниже:

ТАБЛИЦА 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

TABLE 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, где он имеет атрибуты FAST и SMALL, ноне повезло.Каков наилучший способ сделать это?

В этом примере результатом будет carID 1 и carName, где attribute = SMALL и attribute = FAST

Ответы [ 2 ]

3 голосов
/ 04 декабря 2010

Ищете что-то подобное? (Непроверенные)

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;
2 голосов
/ 04 декабря 2010

Это не считается исчерпывающим ответом, это всего лишь несколько моментов по теме.

Поскольку вопрос помечен тегом [mysql], позвольте мне сказать, что в целом реляционные базы данных не особенно подходят для хранения данных с использованием модели EAV .Вы все еще можете разработать модель EAV на SQL, но вам придется пожертвовать многими преимуществами, которые дает реляционная база данных.Мало того, что вы не сможете обеспечить ссылочную целостность, использовать типы данных SQL для значений и принудительные обязательные атрибуты, но даже самые простые запросы (вроде этого) могут стать трудными для написания.Фактически, чтобы преодолеть это ограничение, некоторые решения EAV основаны на дублировании данных, а не на соединении со связанными таблицами, которые, как вы можете себе представить, имеют множество недостатков.рассмотрите возможность использования решения NoSQL .Даже несмотря на то, что недостатки EAV по отношению к реляционным базам данных также применимы к альтернативам NoSQL, вам будут предложены дополнительные функции, которые трудно реализовать с помощью традиционных баз данных SQL.Например, обычно хранилища данных NoSQL можно масштабировать гораздо проще, чем реляционные базы данных, просто потому, что они были разработаны для решения какой-то проблемы масштабируемости, и они намеренно отбрасывали функции, затрудняющие масштабирование.

С другой стороны, решение @ Ронниса должно работать, и, как правило, использование 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...