我在PostgreSQL中有一个名为的关系,该关系product包含2个字段:id和quantity,我想找到id具有最高值的产品quantity。据我所知,有两种方法可以做到:
product
id
quantity
SELECT id FROM product WHERE quantity >= ALL(SELECT quantity FROM product)
或者
SELECT id FROM product WHERE quantity = (SELECT MAX(quantity) FROM product)
他们的执行速度有什么不同吗?
如果有任何行,第一个查询将失败quantity IS NULL(如Gordon所示)。 仅当所有行都具有时,第二个查询才会失败quantity IS NULL。因此,它在大多数情况下应该是可用的。(而且速度更快。)
quantity IS NULL
如果在 Postgres 12或更早版本中 需要NULL安全查询,即NULL是有效结果,请考虑:
SELECT id, quantity FROM product WHERE quantity IS NOT DISTINCT FROM (SELECT MAX(quantity) FROM product);
或者,可能更快:
SELECT id, quantity FROM ( SELECT *, rank() OVER (ORDER BY quantity DESC NULLS LAST) AS rnk FROM product ) sub WHERE rnk = 1;
看:
Postgres 13 添加了标准的SQL子句 WITH TIES :
WITH TIES
SELECT id FROM product ORDER BY quantity DESC NULLS LAST FETCH FIRST 1 ROWS WITH TIES;
db <>在这里拨弄
可使用任何数量的NULL值。
NULL
手册:
SQL:2008引入了不同的语法来实现相同的结果,PostgreSQL也支持该语法。它是: OFFSET start { ROW | ROWS } FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES } 在这种语法中,标准要求 _ start or _ count 值是文字常量,参数或变量名;作为PostgreSQL扩展,允许使用其他表达式,但通常需要将其括在括号中以避免歧义。如果 _ count_ 在FETCH子句中省略if ,则默认为1。此WITH TIES 选项用于根据该ORDER BY子句返回与结果集中最后一行相关的所有其他行;否则,默认为1 。ORDER BY在这种情况下是强制性的。ROW和ROWS以及FIRST和NEXT是不影响这些条款的影响干扰词。
SQL:2008引入了不同的语法来实现相同的结果,PostgreSQL也支持该语法。它是:
OFFSET start { ROW | ROWS } FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES }
在这种语法中,标准要求 _ start or _ count 值是文字常量,参数或变量名;作为PostgreSQL扩展,允许使用其他表达式,但通常需要将其括在括号中以避免歧义。如果 _ count_ 在FETCH子句中省略if ,则默认为1。此WITH TIES 选项用于根据该ORDER BY子句返回与结果集中最后一行相关的所有其他行;否则,默认为1 。ORDER BY在这种情况下是强制性的。ROW和ROWS以及FIRST和NEXT是不影响这些条款的影响干扰词。
start
count
FETCH
ORDER BY
ROW
ROWS
FIRST
NEXT
值得注意的是,WITH TIES不能与(non-standard)short语法一起使用LIMIT n。
LIMIT n
这是 最快的解决方案 。比您当前的任何一个查询都要快。对于 性能而言 更重要:在上有一个 索引(quantity)。或更专业的覆盖索引允许仅索引扫描(速度稍快一点):
(quantity)
CREATE INDEX ON product (quantity DESC NULLS LAST) INCLUDE (id);
我们需要NULLS LAST使NULL值最后以降序排列。看:
NULLS LAST