Установить пересечение в MySQL: чистый способ - PullRequest
1 голос
/ 29 декабря 2011

Я хочу получить объекты, которые удовлетворяют всем n ограничениям Я даю их.

ИЛИ операции могут быть выполнены UNION.Я бы не стал задавать этот вопрос, если бы MySQL поддерживал INTERSECT.

У меня есть объекты в таблице subject и их атрибуты в * subject_attribute *.

Я вижу единственный способ для операций AND как вложенные запросы :

SELECT id
FROM subject_attribute
WHERE attribute = 'des_sen'
AND numerical_value >= 2.0
AND id
IN (
   SELECT id
   FROM subject_attribute
   WHERE attribute = 'tough'
   AND numerical_value >= 3.5
)

Это означает: «извлекать объекты, которые удовлетворяют наименьшему подзапросу, затем исключать тех, кто удовлетворяет более высокому запросу» и т. Д.


rows(condn x) AND rows(condn y) AND rows(cond z) <--ideal
rows(condn x:rows(cond y:rows(cond z))) <-- I am stuck here

Я предпочитаю линейноцепочка условий вместо того, чтобы вкладывать их, как я хочу,

  1. составлять запросы программно
  2. лучше их отлаживать

Мой вопрос: Учитывая n отдельных запросов , как я И их чисто и линейно в MySQL?

Не используя вложенные запросы или хранимые процедуры.

Обратите внимание на частьоб отдельных запросах.


Обновление : Джонатан Леффлер ответил правильно.Ответ Марка Баннистера намного проще (но я принял несколько плохих решений).Пожалуйста, обратитесь к моему ответу, если вы все еще не знаете, как присоединиться.

Ответы [ 3 ]

2 голосов
/ 29 декабря 2011

Если предположить, что каждый отдельный запрос выполняется к одной и той же таблице и каждый из них обращается к различным значениям attribute, самый простой способ пересечения всех таких запросов имеет вид:

SELECT id
FROM subject_attribute
WHERE (attribute = 'des_sen' AND numerical_value >= 2.0) or
      (attribute = 'tough'   AND numerical_value >= 3.5) or
...
group by id
having count(distinct attribute) = N;

- где N - количество пар условий атрибут-числовое_значение.

1 голос
/ 29 декабря 2011

Разве ВНУТРЕННЕЕ СОЕДИНЕНИЕ (или просто СОЕДИНЕНИЕ) не является необходимым перекрестком? Предполагая, что вы делаете объединение по соответствующим общим столбцам.

Таким образом:

SELECT s1.id
  FROM (SELECT id
          FROM subject_attribute
         WHERE attribute = 'des_sen'
           AND numerical_value >= 2.0
       ) AS s1
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'tough'
          AND numerical_value >= 3.5
       ) AS s2
    ON s1.id = s2.id

Это распространяется на N запросов (N> 2) чисто и линейно.


Пожалуйста, объясните, как вы расширяете его.

SELECT s1.id
  FROM (SELECT id
          FROM subject_attribute
         WHERE attribute = 'des_sen'
           AND numerical_value >= 2.0
       ) AS s1
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'tough'
          AND numerical_value >= 3.5
       ) AS s2
    ON s1.id = s2.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'though'
          AND numerical_value = 14
       ) AS s3
    ON s1.id = s3.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'through'
          AND numerical_value != 45
       ) AS s4
    ON s1.id = s4.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'plough'
          AND numerical_value < 9
       ) AS s5
    ON s1.id = s5.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'cough'
          AND numerical_value < 5
       ) AS s6
    ON s1.id = s6.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'bucolic'
          AND numerical_value >= 3.5
       ) AS s7
    ON s1.id = s7.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'set'
          AND numerical_value BETWEEN 0.23 AND 3.0
       ) AS s8
    ON s1.id = s8.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'intelligent'
          AND numerical_value >= 0.001
       ) AS s9
    ON s1.id = s9.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'anal-retentive'
          AND numerical_value < 7
       ) AS s10
    ON s1.id = s10.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'magnificent'
          AND numerical_value = 35
       ) AS s11
    ON s1.id = s11.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'quantum'
          AND numerical_value >= 55
       ) AS s12
    ON s1.id = s12.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'thoughtfulness'
          AND numerical_value >= 350.237
       ) AS s13
    ON s1.id = s13.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'calamity'
          AND numerical_value = 3.0
       ) AS s14
    ON s1.id = s14.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'pink'
          AND numerical_value > 0.5
       ) AS s15
    ON s1.id = s15.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'cornucopia'
          AND numerical_value BETWEEN 1 AND 12
       ) AS s16
    ON s1.id = s16.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'maudlin'
          AND numerical_value < 3.625
       ) AS s17
    ON s1.id = s17.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'triad'
          AND numerical_value >= 1.723
       ) AS s18
    ON s1.id = s18.id
  JOIN (SELECT id
          FROM subject_attribute
         WHERE attribute = 'ambient'
          AND numerical_value >= 3.1
       ) AS s19
    ON s1.id = s19.id
0 голосов
/ 29 декабря 2011

В случае, если кто-то не понимает, как объединить несколько запросов, вот упрощенное представление:

SELECT result1.id
FROM (
<query #1>
) AS result1

INNER JOIN (
<query #2>
) AS result2
ON result1.id = result2.id

INNER JOIN (
<query #3>
) AS result3
ON result1.id = result3.id

где будет

SELECT id
FROM subject_attribute
WHERE attribute = 'des_sen'
AND numerical_value >= 2.0

Это называется самообъединением, соединяющим таблицу с самим собой. Здесь result1, result2 и result3 являются псевдонимами одной и той же таблицы.

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