Оптимизированный SQL select для выбора в нескольких таблицах

#sql #sqlite

#sql #sqlite

Вопрос:

У меня есть следующие таблицы (тестирование с помощью SQLite).

 create table group_header (id int, minCount int, maxCount int);

create table group_items(id int, group_id int, product varchar(10), cons varchar(10));
  

Group_header содержит следующие записи:

 id|minCount|maxCount
1|2|2
  

Group_items содержит следующие записи:

 id|group_id|product|cons
1|1|A|optional
2|1|B|optional
3|1|C|required
4|1|D|optional
  

SQL-запрос должен возвращать идентификатор group_header, который удовлетворяет следующим условиям:

  • Вводом будет один или несколько продуктов (например, ‘A’ и ‘C’)
  • SQL-запрос должен проверять следующие критерии:
    • minCount должно выполняться для optional продуктов (т.е. count количество optional элементов во входных данных должно быть >= minCount значение)
    • все required продукты в таблице group_item должны существовать во входном списке продуктов

Методом перебора это можно сделать, выполнив следующее:

 select * from group_items where group_id = 1 and product in ('A') or cons='required';
  

и затем оцениваем minCount и required отдельно вне SQL. Любые предложения, если это может быть более оптимизированным способом с использованием SQL.

Комментарии:

1. » minCount должно быть выполнено». Что это значит?

2. количество optional продуктов должно быть >= minCount

3. Является ли group_id из group_items таблицы внешним ключом к group_header.id или наоборот?

4. ДА. group_id in group_items — это FK, который ссылается на group_header.id

Ответ №1:

Если я правильно понимаю, это агрегирование с having предложением.

 select gh.id
from group_header gh left join
     group_items gi
     on gh.id = gi.group_id
group by gh.id
having sum( case when gi.cons = 'required' and gi.product in ('A') then 1 else 0 end) = 1 and
       sum( case when gi.cons = 'optional' then 1 else 0 end) >= gh.mincount;