mysql - 找到可以在任何酒吧找到的最低价格啤酒的名称

标签 mysql sql

考虑 Bars and Beers 数据库中的以下关系:

sells (bar, beer, price):指示在每个酒吧出售的每种啤酒的价格(请注意,每个酒吧可以出售许多啤酒,许多酒吧可以以可能不同的价格出售相同的啤酒)。

以下查询查找可以在任何酒吧找到的最低价格啤酒的名称。

SELECT s.beer
FROM sells s
WHERE NOT EXISTS (SELECT si.beer
FROM sells si
WHERE si.price <= s.price) 

您好,我正在慢慢学习 sql,我在理解“si.price <= s.price”部分时遇到了问题。整个查询不会总是返回一个空表,因为嵌套选择基本上是在比较相同的两个表吗?

最佳答案

该查询中有一个错误 - 它永远不会返回任何行,因为没有价格不等于它本身。

要工作,它应该是:

...
WHERE si.price < s.price) 


假设进行了更改,对其工作原理的解释是内部查询对表中的每一行执行一次并依赖于外部表(称为“相关子查询”)。因为在内部查询中使用同一个表,所以您需要为外部表起别名(在本例中为“s”)。内部查询断言没有(其他)价格低于正在执行的行中的价格。

顺便说一句,内部查询的别名是不必要的 - 你可以删除“s1”它仍然有效,因为内部查询是默认范围:

SELECT beer
FROM sells s
WHERE NOT EXISTS (
    SELECT *
    FROM sells  -- no alias needed
    WHERE price <= s.price)

此外,这是一个“坏”查询,因为相关子查询会导致执行“n”个查询(每行一个)。您最好使用 min() 聚合函数:

SELECT beer
FROM sells
WHERE price = (SELECT min(price) FROM sells)

除了这个查询更简单、更容易理解(两个好处)之外,它执行速度更快,因为只执行了两个查询(一个子查询用于查找最低价格,另一个子查询用于获取包含它的整行)。


最后,最后一个(尽管是次要的)错误是,如果有多个价格相同的低价啤酒,所有这些都将返回多行。要返回价格最低的啤酒,您需要将行数限制为 1 并决定如何打破平局(可能是名字)。事实上,只返回一行允许更简单的查询:

select beer
FROM sells
ORDER BY price
LIMIT 1

如果您需要始终打破平局(即不以相同的最低价格返回随机相同价格的啤酒),也可以按名称订购:

select beer
FROM sells
ORDER BY price, beer
LIMIT 1

关于mysql - 找到可以在任何酒吧找到的最低价格啤酒的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14715597/

相关文章:

sql - 代码优先 Entity Framework 在初始化时不拾取 web.config 连接字符串

sql - 统计一年中每个月的记录

mysql - 获取相关结果并按匹配次数排序

PHP-fputcsv : put JSON values retrieved from MySQL field in separate columns

MySQL/SQL : Update with correlated subquery from the updated table itself

sql - 子查询返回超过 1 个值 : DateTime

mysql - GROUP BY 与两列中的 MAX()

mysql - 如何从右侧表中加入每组的行数

mysql - 对 SQL count() 值进行计算

php - MYSQL 根据多行从表中选择