子查询:使用 having 子句过滤掉包含子查询空值的外部查询行是一种好习惯吗
subquery: is it good practise to use having clause to filter out rows of outer query that contains subquery's null values
我有以下 tables:
SELECT * FROM medicine
| id | name | producer |
+----+-------------+----------+
| 1 | aspirin | pharma |
| 2 | cetamol | tamiko |
| 3 | brufen | pharma |
| 4 | cetacodeine | adamco |
| 5 | actifed | tamiko |
| 6 | claritin | tamiko |
+----+-------------+----------+
SELECT * FROM liquid
+-----+------+-------+
| lid | m_id | price |
+-----+------+-------+
| l1 | 2 | 1000 |
| l2 | 3 | 1500 |
| l3 | 4 | 3000 |
| l4 | 5 | 2000 |
| l5 | 6 | 1800 |
+-----+------+-------+
SELECT * FROM tablet
+-----+------+-------+
| tid | m_id | price |
+-----+------+-------+
| t1 | 1 | 900 |
| t2 | 2 | 600 |
| t3 | 3 | 1200 |
| t4 | 5 | 2000 |
+-----+------+-------+
最后两个 m_id 在第一个 tablest 中有外键引用 id table.
我正在尝试列出 lid 和 name 仅由生产商 tamiko 生产的液态药物
执行以下语句将导致包含从子查询返回的空值的行,我想省略
SELECT lid, (SELECT name FROM medicine WHERE liquid.m_id=medicine.id AND medicine.producer='tamiko') AS byTamiko FROM liquid;
+-----+----------+
| lid | byTamiko |
+-----+----------+
| l1 | cetamol |
| l2 | NULL |
| l3 | NULL |
| l4 | actifed |
| l5 | claritin |
+-----+----------+
所以我做了一些尝试,使用 HAVING
子句似乎是一个解决方案
SELECT lid, (SELECT name FROM medicine WHERE liquid.m_id=medicine.id AND medicine.producer='tamiko') AS byTamiko FROM liquid HAVING byTamiko IS NOT NULL;
| lid | byTamiko |
+-----+----------+
| l1 | cetamol |
| l4 | actifed |
| l5 | claritin |
+-----+----------+
但是,我的老师不同意 HAVING
子句只能与聚合函数一起使用,并与 GROUP BY
语句一起使用。我现在很困惑这是否是一种适当的用法?到底发生了什么让它起作用?
注意:我必须只使用子查询而不是任何 JOIN
或不同的语句来执行此查询。
注意 2:请注意,这不是重复的,我正在尝试解释它是如何工作的以及它是否是正确的用法。
不太合适。
在SQL标准中having
定义为过滤after聚合而where
用于聚合之前的过滤(如果有任何聚合)。
MySQL 扩展它以允许在非聚合查询中使用 having
。此扩展允许您在不使用子查询的情况下过滤列别名。但是你应该在聚合之前使用 where
进行过滤。
所以它应该是这样的?
SELECT lid, (
SELECT name
FROM medicine
WHERE liquid.m_id=medicine.id AND medicine.producer='tamiko'
) AS byTamiko
FROM liquid
WHERE byTamiko IS NOT NULL;
我有以下 tables:
SELECT * FROM medicine
| id | name | producer |
+----+-------------+----------+
| 1 | aspirin | pharma |
| 2 | cetamol | tamiko |
| 3 | brufen | pharma |
| 4 | cetacodeine | adamco |
| 5 | actifed | tamiko |
| 6 | claritin | tamiko |
+----+-------------+----------+
SELECT * FROM liquid
+-----+------+-------+
| lid | m_id | price |
+-----+------+-------+
| l1 | 2 | 1000 |
| l2 | 3 | 1500 |
| l3 | 4 | 3000 |
| l4 | 5 | 2000 |
| l5 | 6 | 1800 |
+-----+------+-------+
SELECT * FROM tablet
+-----+------+-------+
| tid | m_id | price |
+-----+------+-------+
| t1 | 1 | 900 |
| t2 | 2 | 600 |
| t3 | 3 | 1200 |
| t4 | 5 | 2000 |
+-----+------+-------+
最后两个 m_id 在第一个 tablest 中有外键引用 id table.
我正在尝试列出 lid 和 name 仅由生产商 tamiko 生产的液态药物 执行以下语句将导致包含从子查询返回的空值的行,我想省略
SELECT lid, (SELECT name FROM medicine WHERE liquid.m_id=medicine.id AND medicine.producer='tamiko') AS byTamiko FROM liquid;
+-----+----------+
| lid | byTamiko |
+-----+----------+
| l1 | cetamol |
| l2 | NULL |
| l3 | NULL |
| l4 | actifed |
| l5 | claritin |
+-----+----------+
所以我做了一些尝试,使用 HAVING
子句似乎是一个解决方案
SELECT lid, (SELECT name FROM medicine WHERE liquid.m_id=medicine.id AND medicine.producer='tamiko') AS byTamiko FROM liquid HAVING byTamiko IS NOT NULL;
| lid | byTamiko |
+-----+----------+
| l1 | cetamol |
| l4 | actifed |
| l5 | claritin |
+-----+----------+
但是,我的老师不同意 HAVING
子句只能与聚合函数一起使用,并与 GROUP BY
语句一起使用。我现在很困惑这是否是一种适当的用法?到底发生了什么让它起作用?
注意:我必须只使用子查询而不是任何 JOIN
或不同的语句来执行此查询。
注意 2:请注意,这不是重复的,我正在尝试解释它是如何工作的以及它是否是正确的用法。
不太合适。
在SQL标准中having
定义为过滤after聚合而where
用于聚合之前的过滤(如果有任何聚合)。
MySQL 扩展它以允许在非聚合查询中使用 having
。此扩展允许您在不使用子查询的情况下过滤列别名。但是你应该在聚合之前使用 where
进行过滤。
所以它应该是这样的?
SELECT lid, (
SELECT name
FROM medicine
WHERE liquid.m_id=medicine.id AND medicine.producer='tamiko'
) AS byTamiko
FROM liquid
WHERE byTamiko IS NOT NULL;