SQLite - HAVING 子句
SQLite - HAVING 子句
Section titled “SQLite - HAVING 子句”HAVING 子句与 GROUP BY 子句结合使用,用于筛选聚合函数的结果。它作用类似于 WHERE 子句,但针对的是组而不是单个行。
WHERE 与 HAVING:清晰的区别
Section titled “WHERE 与 HAVING:清晰的区别”这是一个常见的混淆点。关键区别在于查询中的操作顺序:
WHERE子句在行被分组之前进行筛选。它作用于单个行数据。HAVING子句在组通过GROUP BY创建之后进行筛选。它作用于聚合函数(如COUNT()、SUM()、AVG())的结果。
HAVING 子句必须出现在 GROUP BY 子句之后,以及任何 ORDER BY 子句之前。
SELECT column_name(s), aggregate_function(column_name)FROM table_nameWHERE [ 单个行条件 ]GROUP BY column_name(s)HAVING [ 基于聚合函数的组条件 ]ORDER BY column_name(s);让我们考虑一个 products 表,其中包含以下记录:
CREATE TABLE products ( id INTEGER PRIMARY KEY, name TEXT, category TEXT, price REAL, stock_quantity INTEGER);
INSERT INTO products (name, category, price, stock_quantity) VALUES('Laptop', 'Electronics', 1200.00, 10),('Mouse', 'Electronics', 25.00, 150),('Keyboard', 'Electronics', 75.00, 70),('Desk Chair', 'Furniture', 150.00, 30),('Coffee Table', 'Furniture', 220.00, 15),('T-Shirt', 'Apparel', 20.00, 200),('Jeans', 'Apparel', 60.00, 80);问题:查找产品数量超过一个的类别。
Section titled “问题:查找产品数量超过一个的类别。”我们需要按 category 分组,然后计算每个组中的产品数量。最后,筛选这些组,只保留数量大于 1 的组。
SELECT category, COUNT(id) AS product_countFROM productsGROUP BY categoryHAVING COUNT(id) > 1;这将产生以下结果:
category product_count----------- -------------Apparel 2Electronics 3Furniture 2问题:查找产品平均价格超过 100 美元的类别。
Section titled “问题:查找产品平均价格超过 100 美元的类别。”在这里,我们按 category 分组,计算每个类别的平均价格,然后使用 HAVING 根据该平均价格进行筛选。
SELECT category, AVG(price) AS average_priceFROM productsGROUP BY categoryHAVING AVG(price) > 100.00;这将产生以下结果:
category average_price----------- ----------------Electronics 433.333333333333Furniture 185.0结合使用 WHERE 和 HAVING
Section titled “结合使用 WHERE 和 HAVING”让我们查找产品平均价格(成本超过 50 美元)超过 100 美元的类别。
SELECT category, AVG(price) as average_priceFROM productsWHERE price > 50.00 -- 首先筛选单个行GROUP BY categoryHAVING AVG(price) > 100.00; -- 在聚合后筛选组此查询首先从计算中排除 ‘Mouse’ 和 ‘T-Shirt’,然后对组进行分组和筛选。
category average_price----------- ----------------Electronics 637.5Furniture 185.0将 WHERE 用于聚合函数: 以下查询将失败,因为 WHERE 无法对 COUNT() 的结果进行操作。
-- 不正确SELECT category, COUNT(id)FROM productsGROUP BY categoryWHERE COUNT(id) > 1; -- 错误!将 HAVING 用于非聚合条件: 尽管有些数据库允许这样做,但这是一种不好的做法,效率也较低。请使用 WHERE 筛选单个行。
-- 效率低下(尽管在 SQLite 中可能有效)SELECT category, AVG(price)FROM productsGROUP BY categoryHAVING category = 'Electronics';
-- 正确且高效SELECT category, AVG(price)FROM productsWHERE category = 'Electronics'GROUP BY category;