SQL-запрос, чтобы получить результаты только при наличии всех запрошенных совпадений из двух столбцов - PullRequest
0 голосов
/ 01 июня 2018

Я хочу получить результат, в котором значение столбца 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

Я хочу найти фрукты, которые имеют форму = круглые, имеют цвет = красный и поверхность = гладкая.Результат в приведенной выше таблице должен быть "привлекательным", но мои попытки выяснить правильный 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 */

Ответы [ 3 ]

0 голосов
/ 01 июня 2018

Другой подход к получению фруктов, обладающих всеми этими свойствами, заключается в использовании агрегации

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

0 голосов
/ 01 июня 2018

Я бы просто сделал:

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 с точки зрения производительности, и это не делает ненужных подзапросов.Так что это должно победить и на этом фронте.

0 голосов
/ 01 июня 2018

Ты был так близко.Просто продолжайте выбирать фрукты из своих предложений и не беспокойтесь о количестве - также вы были правы, используя 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, который я использовал

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...