запрос на наличие определенного набора записей в базе данных - PullRequest
0 голосов
/ 17 октября 2019

Я храню различные последовательности в базе данных SQLite. Каждая последовательность имеет свой собственный идентификатор последовательности, и каждый элемент в последовательности имеет свой собственный индекс в последовательности, а также значение.

CREATE TABLE Sequence (rowid INTEGER PRIMARY KEY, 
                       SequenceId INTEGER, 
                       Index INTEGER, 
                       Value TEXT);

Например, первая последовательность, которую я мог бы добавить, могла бы быть "Красная", "Зеленая", "Синяя" следующим образом:

INSERT INTO Sequence (SequenceId, Index, Value) VALUES (1,1,"Red"), (1,2,"Green"), (1,3,"Blue"); 

Я получаю SequenceId от другогоТаблица. Когда я буду готов добавить новую последовательность в базу данных, я сначала хочу убедиться, что ее там еще нет. Моей первой мыслью было, что я могу создать запрос проверки на наличие каждой строки в последовательности и AND их вместе. Например, перед добавлением последовательности «Красный», «Зеленый», «Синий» я бы запустил запрос, который выглядит следующим образом:

SELECT
    EXISTS(SELECT * FROM Sequence 
           WHERE SequenceId = ? AND Index = 1 AND Value='Red')
    AND EXISTS(SELECT * FROM Sequence 
           WHERE SequenceId = ? AND Index = 2 AND Value='Green')
    AND EXISTS(SELECT * FROM Sequence 
           WHERE SequenceId = ? AND Index = 3 AND Value='Blue')
    AND NOT EXISTS(SELECT * FROM Sequence 
           WHERE SequenceId = ? AND Index = 4);

Мне все равно, какой фактический ранее назначенный SequenceId был, только если последовательность существует. Но потом я понял, что у меня нет возможности убедиться, что SequenceId одинаково для каждого предложения EXISTS.

Есть ли в SQLite какой-либо способ выполнить это?

1 Ответ

1 голос
/ 17 октября 2019

Вы можете group by sequenceid и установить условия в предложении HAVING:

select sequenceid
from sequence
group by sequenceid
having 
  sum(`index` = 1 and `value` = 'Red') > 0
  and 
  sum(`index` = 2 and `value` = 'Green') > 0
  and
  sum(`index` = 3 and `value` = 'Blue') > 0

Этот код вернет один (или несколько) существующих sequenceid с «Red», «Green»и "синий". Смотрите демо . Если вам не нужны sequenceid s, используйте его как подзапрос:

select exists (
  select sequenceid
  from sequence
  group by sequenceid
  having 
    sum(`index` = 1 and `value` = 'Red') > 0
    and 
    sum(`index` = 2 and `value` = 'Green') > 0
    and
    sum(`index` = 3 and `value` = 'Blue') > 0
)  

См. demo . Или с CTE:

with cte(`Index`, `Value`) as (
  select * from (
    values (1, 'Red'), (2, 'Green'), (3, 'Blue')
  )
)
select exists (
  select sequenceid
  from sequence
  where (`index`, `value`) in (select `index`, `value` from cte)
  group by sequenceid
  having count(*) = 3
) 

См. Демонстрационную версию .

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