Почему ORDER BY не работает в запросе Presto?

#tsql #presto #trino #treasure-data

#tsql #presto #trino #сокровище-данные

Вопрос:

У меня довольно простой запрос 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, строки являются случайными.

Комментарии:

1. В это трудно поверить. Либо order by он не является частью выполняемого запроса, либо вы неверно интерпретируете результаты.

2. Можете ли вы поделиться некоторыми примерами данных и результатом, который вы получаете для этого?

3. На самом деле, я забыл включить скобки, завершающие запрос (добавлены сейчас). Я устранял неполадки с подвыборкой, и при выполнении запроса, заключенного в скобки, ORDER BY завершается ошибкой. Без скобок работает нормально. Спасибо за вашу помощь в устранении неполадок.

Ответ №1:

Спасибо @DShultz за отчет. Это действительно так, и я сообщил https://github.com/trinodb/trino/issues/6008 для этого. Давайте продолжим обсуждение, является ли это желательным или ошибочным поведением.

В качестве обходного пути…. хорошо, уберите скобки. Но это вы уже знаете.

Более общая причина, почему это так — Presto игнорирует ORDER BY, где он не изменяет семантику запроса (например, в подзапросах), как указано в спецификации SQL. Смотрите https://trino.io/blog/2019/06/03/redundant-order-by.html для получения дополнительной информации.

Ответ №2:

Спецификация 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 не содержит сразу an <order by clause> , то порядок строк в T зависит от реализации.

(QE — это <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
  

Комментарии:

1. Я проверил, что даже с круглыми скобками (выберите ..), order by по-прежнему не работает.