0

我有一个相当简单的 Presto 查询,它不是按我指定的列排序:

(SELECT 
  tag_monitor_domains.property_name,
  count(*) as HourCount
FROM pageviews
  INNER JOIN tag_monitor_domains 
  ON pageviews.property_id = CAST(tag_monitor_domains.property_id AS varchar) 
WHERE FROM_UNIXTIME(pageviews.time) > date_add('month', -1, CURRENT_DATE)
AND FROM_UNIXTIME(pageviews.time) < date_add('hour', -0, CURRENT_TIMESTAMP)
GROUP BY 1
ORDER BY 1 DESC)

但结果不是按 property_name 排序的,行是随机的。

4

2 回答 2

2

感谢@DShultz 的报告。确实是这样,我为此报告了https://github.com/trinodb/trino/issues/6008。让我们继续讨论这是期望的行为还是错误的行为。

作为一种解决方法....好吧,删除括号。但这你已经知道了。

出现这种情况的更一般的原因是——Presto忽略了 ORDER BY,它不会改变查询的语义(例如在子查询中),这是由 SQL 规范管理的。有关更多信息,请参阅https://trino.io/blog/2019/06/03/redundant-order-by.html

于 2020-11-18T22:06:48.467 回答
1

SQL 规范定义了以下语法规则:

<query expression> ::=
  [ <with clause> ]
  <query expression body>
  [ <order by clause> ]
  [ <result offset clause> ]
  [ <fetch first clause> ]

<query expression body> ::=
    <query term>
  | <query expression body> UNION [ ALL | DISTINCT ] [ <corresponding spec> ] <query term>
  | <query expression body> EXCEPT [ ALL | DISTINCT ] [ <corresponding spec> ] <query term>

<query term> ::=
    <query primary>
  | <query term> INTERSECT [ ALL | DISTINCT ] [ <corresponding spec> ] <query primary>

<query primary> ::=
    <simple table>
  | <left paren>
       <query expression body>
       [ <order by clause> ]
       [ <result offset clause> ]
       [ <fetch first clause> ]
    <right paren>

带括号的查询是一个<query expression>只包含一个<query primary>形状的<left paren> <query expression body> ... <right paren>

此外,它指定:

a) 如果QE不立即包含<order by clause>,则行的顺序T取决于实现。

(量化宽松是<query expression>

因此,由于在<query expression>括号中的情况下 不立即包含 ORDER BY 子句,<query primary>因此不能保证排序。

Presto 优化了这种情况并产生警告,表明您可能无法获得预期的结果:

presto> (SELECT x FROM (VALUES 1) t(x) ORDER BY x);
 x
---
 1
(1 row)

WARNING: ORDER BY in subquery may have no effect

要获得所需的顺序,您需要确保ORDER BY子句位于顶层,或者按照其他回复中的建议删除括号,或者将其移到括号外:

(SELECT ...)
ORDER BY 1 DESC
于 2020-11-19T01:09:19.673 回答