Фильтрация sqlite-запроса - PullRequest
       1

Фильтрация sqlite-запроса

0 голосов
/ 28 ноября 2018

Возникли проблемы с фильтрацией в моем запросе sqlite3.Я работаю с тремя таблицами ниже.

Table: models
id|data 
1|car
2|truck

Table: descriptions
id|model_id|colour|make
1|1|blue|accord
2|1|green|prius
3|1|red|fusion
4|1|black|civic
5|1|white|jeep
6|1|purple|jeep
7|1|brown|jeep
8|1|brown|civic

Table: banned
model_id|colour_id|colour
1|3|black|
1|15|brown|

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

SELECT models.id, make, count(make) 
FROM description 
JOIN models ON models.id = descriptions.model_id 
GROUP BY models.id, descriptions.make;

Вывод будет ниже

1|accord|1
1|prius|1
1|fusion|1
1|civic|2
1|jeep|3

Однако я хочу добавить квалификатор, который аннулирует все, что содержит запрещенную комбинацию цвета / модели, используя banned.colour.Я попытался присоединиться к таблице и отфильтровать, как показано ниже, но, кажется, счет удваивается.

SELECT models.id, make, count(make) 
FROM description 
JOIN models ON models.id = descriptions.model_id 
JOIN banned ON banned.model_id = models.id 
WHERE NOT ( banned.colour = descriptions.colour) 
GROUP BY models.id, descriptions.make;

Мой желаемый результат - аннулировать две машины, которые соответствуют этому классификатору из подсчета.Окончательный результат должен быть ниже

1|accord|1
1|prius|1
1|fusion|1
1|jeep|2

Как мне этого добиться?

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Вы можете использовать свой подход.,,с проверками left join и where:

SELECT m.id, d.make, count(*) 
FROM description d JOIN
     models m
     ON m.id = d.model_id LEFT JOIN
     banned b
     ON b.model_id = m.id AND b.colour = d.colour
WHERE b.model_id IS NULL   -- no match
GROUP BY m.id, d.make;

Обычный способ написания запроса также будет использовать NOT EXISTS:

SELECT m.id, d.make, count(*) 
FROM description d JOIN
     models m
     ON m.id = d.model_id         
WHERE NOT EXISTS (SELECT 1
                  FROM banned b
                  WHERE b.model_id = m.id AND b.colour = d.colour
                 )
GROUP BY m.id, d.make;

Хотя вы также можете использовать NOT IN Я настоятельно не рекомендую использовать его с подзапросом.Он не будет делать то, что вы хотите, если любое из значений, возвращаемых подзапросом, равно NULL.

0 голосов
/ 28 ноября 2018

Вы можете использовать NOT IN с зависимым подзапросом, чтобы избежать запрещенных комбинаций.

SELECT models.id, make, count(make) 
FROM description 
JOIN models ON models.id = descriptions.model_id 
WHERE colour NOT IN (
  SELECT colour 
  FROM banned
  WHERE banned.model_id = models.id
)
GROUP BY models.id, descriptions.make;

Единственный подводный камень NOT IN - это возможность иметь NULL в результате подзапроса.Однако я считаю, что безопасно, если атрибут colour определен как NOT NULL (что имеет смысл в этом случае).

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