过滤sqlite查询

时间:2018-11-28 18:50:11

标签: sql sqlite

在我的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 :(得分:1)

您可以使用您的方法。 。 。进行left joinwhere检查:

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,它将不会执行您想要的操作。

答案 1 :(得分:0)

您可以将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(在这种情况下很有意义)是安全的。