Эквивалент «IN», в котором используется логика AND вместо логики OR? - PullRequest
2 голосов
/ 11 ноября 2011

Я знаю, что нарушаю некоторые правила с помощью динамического SQL, но мне все еще нужно спросить.Я унаследовал таблицу, которая содержит серию тегов для каждого тикета, из которого мне нужно получить записи.

Простой пример ... У меня есть массив, содержащий «Яблоки», «Апельсины», «Виноград», и я пытаюсь получить все записи, которые содержат ВСЕ элементы, содержащиеся вмассив.

Мой SQL выглядит так:

 SELECT * FROM table WHERE basket IN ( " + fruitArray + " )

Что, конечно, будет эквивалентно:

 SELECT * FROM table WHERE basket = 'Apples' OR basket = 'Oranges' OR basket = 'Grapes'

Мне любопытно, если естьфункция, которая работает так же, как IN (массив), за исключением того, что она использует AND вместо OR, чтобы я мог получить те же результаты, что и:

 SELECT * FROM table WHERE basket LIKE '%Apples%' AND basket LIKE '%Oranges%' AND basket LIKE '%Grapes%'

Возможно, я мог бы просто сгенерировать всю строку вручную, но хотел быболее элегантное решение, если это вообще возможно.Любая помощь будет оценена.

Ответы [ 5 ]

1 голос
/ 11 ноября 2011

Это очень распространенная проблема в SQL.В основном есть два решения:

  1. Сопоставьте все строки в вашем списке, сгруппируйте по столбцу, который имеет общее значение для всех этих строк, и убедитесь, что количество различных значений в группеколичество элементов в вашем массиве.

    SELECT basket_id FROM baskets
    WHERE basket IN ('Apples','Oranges','Grapes')
    GROUP BY basket_id
    HAVING COUNT(DISTINCT basket) = 3
    
  2. Выполните самостоятельное объединение для каждого отдельного значения в вашем массиве;только тогда вы можете сравнивать значения из нескольких строк в одном выражении WHERE.

    SELECT b1.basket_id
    FROM baskets b1
    INNER JOIN baskets b2 USING (basket_id)
    INNER JOIN baskets b3 USING (basket_id)
    WHERE (b1.basket, b2.basket, b3.basket) = ('Apples','Oranges','Grapes')
    
0 голосов
/ 11 ноября 2011

Находятся ли вы в поиске товаров в одном и том же порядке в корзине?Если да, то достаточно одного LIKE:

SELECT * FROM table WHERE basket LIKE '%Apples%Oranges%Grapes%';

И объединение массива в строку с разделителями% должно быть тривиальным.

0 голосов
/ 11 ноября 2011

Если basket является строкой, как показывает ваш пример, то вы можете использовать LIKE '%apples%oranges%grapes%', который можно легко создать с помощью '%'.implode('%', $tags).'%'

Проблема в этомесли некоторые из тегов могут содержаться в других тегах, например, 'supercalifragilisticexpialidocious' LIKE '%super%' будет истинным.

0 голосов
/ 11 ноября 2011

Если вам нужно сделать LIKE сравнение, я думаю, вам не повезло. Если вы выполняете точное сравнение, вызывая совпадающие множества в произвольном порядке, вам следует изучить параметры INTERSECT и EXCEPT оператора SELECT. Они немного сбивают с толку, но могут быть довольно мощными. (Вам придется анализировать строки с разделителями в табличном формате, но, конечно, вы все равно это делаете, не так ли?)

0 голосов
/ 11 ноября 2011

Может быть что-то подобное в полнотекстовом поиске, но в целом я искренне сомневаюсь, что такой оператор был бы очень полезен вне сочетания с LIKE.

Рассмотрим:

SELECT * FROM table WHERE basket ='Apples' AND basket = 'Oranges'

всегда будет соответствовать нулю строк.

...