Несколько строк со смешанными значениями в MySQL IN по сравнению с подзапросом - PullRequest
0 голосов
/ 05 июля 2011

Прошу прощения за запутанный заголовок. Мне интересно вот что: у меня есть запрос SELECT, который в своих условиях WHERE выполняет сравнение нескольких столбцов IN с набором результатов, возвращаемым подзапросом. По сравнению с результатами этого подзапроса я хочу сравнить два возможных набора значений, каждый из которых включает одно значение из родительского запроса SELECT и несколько констант.

Другими словами, как я могу сделать что-то вроде этой работы:

SELECT ... WHERE ((id, 1, 2, 3), (id, 4, 5, 6)) IN (SELECT a, b, c, d FROM atable)

В этом случае 'id' предоставляется родительским оператором SELECT, но другие значения являются константами. Намерение состоит в том, чтобы сравнить эти два набора значений с множеством различных значений (a, b, c и d) в «atable».

Я знаю, что могу сделать эту работу, добавив ИЛИ и повторив сравнение IN, чтобы сравнить два возможных набора с результатами подзапроса по отдельности, но я не хочу делать это ради эффективности (так как это повторится подзапрос).

Я прошу прощения, если этот запрос не был сформулирован очень изящно, но я надеюсь, что смысл встречается. Я попытался найти в Google и прочитать документацию по MySQL безрезультатно (возможно, потому, что не знаю, как правильно сформулировать проблему).

Заранее спасибо за ваше время и помощь.

Ответы [ 4 ]

3 голосов
/ 05 июля 2011

Это все еще чувствует себя довольно медленно.Разве не имеет смысла просто использовать соединение?

select query.* from query 
inner join atable on (atable.a=query.id) and ((b=1 and c=2 and d=3) or (b=4 and c=5 and d=6)

Это все еще читабельно и очень быстро.Обратите внимание на дополнительные условия при объединении.

1 голос
/ 05 июля 2011

В зависимости от вашей ситуации в мире, соответствует ли следующий коэффициент вашим потребностям?

SELECT
  *
FROM
  query
WHERE
  EXISTS (
    SELECT
      *
    FROM
      atable
    WHERE
      a = query.id
      AND (
           (b = 1 AND c = 2 AND d = 3)
           OR
           (b = 4 AND c = 5 AND d = 6)
          )
  )


Или, возможно ...

SELECT
  *
FROM
  query
INNER JOIN
(
  SELECT atable.a FROM atable
  WHERE (b = 1 AND c = 2 AND d = 3) OR (b = 4 AND c = 5 AND d = 6)
  GROUP BY atable.a
)
  AS filter
    ON filter.a = query.id


в обобщенном смысле ...

SELECT
  *
FROM
  query
INNER JOIN
(
  SELECT
    atable.a
  FROM
    atable
  INNER JOIN
  (
    SELECT 1 AS b, 2 AS c, 3 AS d
    UNION ALL
    SELECT 4 AS b, 5 AS c, 6 AS d
  )
    AS patterns
      ON  patterns.b = atable.b
      AND patterns.c = atable.c
      AND patterns.d = atable.d
  GROUP BY
    atable.a
)
  AS filter
    ON filter.a = query.id
0 голосов
/ 05 июля 2011

Вы также можете объединить несколько разных запросов вместе. Иногда объединение из двух простых запросов оптимизируется оптимизатором лучше, чем один более сложный запрос. Не то чтобы так было, но часто так и есть.

P.S. Я был бы признателен, зная причины понижения. Обеспокоенность выше была для производительности («чувствует себя медленно»). Ощущается

0 голосов
/ 05 июля 2011
SELECT ... 
WHERE EXISTS
  ( SELECT *
    FROM 
      ( SELECT a, b, c, d FROM atable
      ) AS tmp
    WHERE (id, 1, 2, 3) = (a, b, c, d)
       OR (id, 4, 5, 6) = (a, b, c, d)
  )

или JOIN, которые предлагает Эляким, слегка изменено. Вам, вероятно, понадобится GROUP BY, чтобы удалить повторяющиеся результаты:

SELECT ... 
  JOIN
      ( SELECT a, b, c, d FROM atable
      ) AS tmp
    ON (id, 1, 2, 3) = (a, b, c, d)
    OR (id, 4, 5, 6) = (a, b, c, d)
GROUP BY id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...