子查询:使用 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.

我正在尝试列出 lidname 仅由生产商 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;