Я хочу получить результат, когда значение столбца 1 можно найти для трех (или более) комбинаций столбца 2 и 3 (по парам?) Пример... здесь гипотетическая таблица из 3 столбцов:
FRUIT | TRAIT | DESCRIBED ------------------------------- Apple | color | red Apple | shape | round Pear | surface | smooth pear | stem | red grape | shape | round grape | color | red grape | surface | smooth
Я хочу найти фрукты, имеющие форму = круглые, цвет = красный и всплывающий = гладкий. Результат в приведенной выше таблице должен быть "grape", но мои попытки выяснить правильный SQL-запрос, я не могу сузить его. Я получаю Apple, потому что она красная, и груша, потому что она гладкая. Но я не хочу этих. Мне нужен плод, который появляется для всех трех признаков/описаний.
Я добрался до этого, думая, что есть способ использовать группу, и я использовал подзапросы - думая, что это даст мне способ потребовать. Но это все равно не дает мне только "виноград" в результатах.
SELECT fruit /* DISTINCT ?*/ FROM table1 WHERE fruit
IN (SELECT fruit FROM table1 WHERE trait = 'shape' AND described = 'round')
AND (SELECT fruit FROM table1 WHERE trait = 'color' AND described = 'red')
AND (SELECT fruit FROM table1 WHERE trait = 'surface' AND described = 'smooth')
HAVING count(fruit) = 3 /* or whatever number of trait/described combos were searched for */
Ты был так близко. Просто продолжайте выбирать фрукты из своих статей и не беспокойтесь о счете - также вы были правы в использовании DISTINCT
SELECT DISTINCT FRUIT FROM Table1
WHERE FRUIT IN (SELECT FRUIT FROM Table1 WHERE TRAIT = 'shape' AND DESCRIBED = 'round')
AND FRUIT IN (SELECT FRUIT FROM Table1 WHERE TRAIT = 'color' AND DESCRIBED = 'red')
AND FRUIT IN (SELECT FRUIT FROM Table1 WHERE TRAIT = 'surface' AND DESCRIBED = 'smooth')
Вы можете выполнить свое тестирование на SQL Fiddle, который я использовал
Я бы просто сделал:
SELECT fruit
FROM table1
WHERE (trait, described) IN ( ('shape', 'round'), ('color', 'red'), ('surface', 'smooth') )
GROUP BY fruit
HAVING count(fruit) = 3 ;
Это намного проще читать, писать и поддерживать, чем запрос с ненужными подзапросами. Что касается производительности, SELECT DISTINCT
по существу совпадает с GROUP BY
с точки зрения производительности, и это не делает ненужных подзапросов. Поэтому он должен побеждать и на этом фронте.
Другой подход для получения плодов, у которых есть все эти свойства, вы можете использовать агрегацию
SELECT FRUIT
FROM table1
GROUP BY FRUIT
HAVING SUM(CASE WHEN TRAIT = 'color' AND DESCRIBED = 'red' THEN 1 ELSE 0 END ) > 0
AND SUM(CASE WHEN TRAIT = 'shape' AND DESCRIBED = 'round' THEN 1 ELSE 0 END ) > 0
AND SUM(CASE WHEN TRAIT = 'surface' AND DESCRIBED = 'smooth' THEN 1 ELSE 0 END ) > 0
Используя Mysql, вы также можете использовать sum(a=b)
, SUM(TRAIT = 'color' AND DESCRIBED = 'red' )
как сокращенное выражение, используя выражение внутри sum()
приведет к логическому значению 0/1, true/false