Сокращение SQL-запроса для проверки записей имеют специальные значения или не существуют - PullRequest
0 голосов
/ 21 июня 2019

У меня есть таблица тегов, где в каждой строке есть столбцы «имя» и «значение». Имена уникальны.

У меня есть (фиксированный) набор имен (хотя со временем мне, возможно, придется добавить в набор - все в порядке, чтобы редактировать запрос, когда это произойдет)

Мне нужно проверить, что для каждого имени в наборе либо нет строки с таким именем, либо, если строка существует, соответствующее значение является одной из двух разных фиксированных строк (скажем, «ОДИН» и «ДВА»)

У меня также есть ограничение на длину запроса - он хранится в таблице БД и должен иметь длину <2048 символов. </p>

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

Есть ли другой (более короткий) способ сделать это? Запросить, чтобы получить подмножество имен тегов, которые существуют, а затем проверить, что все они имеют одно из двух значений?

Идеи (которые я не знаю, как делать в SQL): Подсчитайте количество тегов, имена которых есть в моем фиксированном списке. Подсчитайте количество тегов с именами в моем фиксированном списке и одно из двух допустимых значений, сравните счетчики

Получить все различные значения тегов в моем фиксированном списке. Проверьте, что различные значения являются подмножеством моего списка разрешенных значений

БД - это Oracle, но мне бы хотелось решение, которое также работает с MariaDB. Я могу использовать HQL или SQL.

and (
    NOT exists(
      from
        tags T
      where
        T.name = 'FOOBAR'
    )
    OR exists(
      from
        tags T
      where
        T.name = 'FOOBAR'
        and T.value in('ONE', 'TWO')
    )
  )

Ответы [ 2 ]

2 голосов
/ 21 июня 2019

Это должно выполнить ту же цель:

and (
    NOT exists(
      from
        tags T
      where
        T.name = 'FOOBAR'
      and
        T.value not in ('ONE','TWO')
)

т.е.он будет фильтровать записи, где T.name = 'FOOBAR', если только value не входит в ваш набор.

Не уверен, что он сэкономит достаточно места.

0 голосов
/ 21 июня 2019

Попробуйте

where nvl((select max(t.value) from tags t where name ='FOOBAR'), 'ONE') in ('ONE', 'TWO')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...