【问题标题】:I don't understand why my Athena (Presto) SQL query doesn't work我不明白为什么我的 Athena (Presto) SQL 查询不起作用
【发布时间】:2019-07-09 23:34:08
【问题描述】:

我有一个具体的问题和一个更一般的问题...对于上下文,我使用的是 Athena。这是我的具体问题:

1)我正在尝试编写一个查询,计算按国家/地区细分的连续 2 个月的 DAU(我最终希望按国家和日期细分 DAU/MAU,但我想我会从简单的开始... )。我对如何解决这个问题的想法是,我需要两个查询,每个月一个,它使用国家分组并应用必要的过滤器。最后,我将能够加入国家以获得包含国家/地区的 1 列,以及包含 DAUS 两个月的以下列。这是我沙沙作响的查询:

 SELECT count(distinct uuid) m1, country
FROM user u1
WHERE month(date(dt)) = 12 
AND YEAR(date(dt)) = 2018

INNER JOIN (SELECT count(distinct uuid) m2, country
  FROM user
  WHERE month(date(dt)) = 11
        AND YEAR(date(dt)) = 2018 GROUP BY country
) t ON t.country = u1.country

GROUP BY country

这有什么问题?错误:mismatched input 'join' expecting {<eof>

2) 我更一般的问题是,在构建更复杂的查询时我应该如何思考?我已经编程多年,但我似乎总是发现自己被复杂的 SQL 查询卡住,并在错误消息后遇到错误消息(这似乎也几乎无法解释)。

感谢所有建议:)

【问题讨论】:

  • 您的第一个问题表明您不了解SQL的基本语法。我建议你问另一个问题,包括样本数据、期望的结果以及你想要做什么的解释。您提供的任何 SQL 都会有所帮助。
  • 查看您的部分/处理顺序的 SQL,它们不是有效的 SQL。您的加入位置不正确(必须在 where 和 group by 之前)并且 group by 必须在最后
  • 在编写 SQL 查询之前,您应该做的第一件事就是学习如何编写正确的语法。没有 dbms 将能够执行您的查询。
  • 关于 Q2:我已经编程多年这可能是您遇到 SQL 问题的原因 :-) 切换到所谓的 基于集合的思维 意味着忘记很多你以前做过的事情。顺便说一句,解释编程语言返回的错误消息并不容易......

标签: sql amazon-athena presto


【解决方案1】:

where 和 group by 应该放在 where 连接子句之后

    SELECT count(distinct uuid) m1, country
    FROM user u1
    INNER JOIN (SELECT count(distinct uuid) m2, country
      FROM user
      WHERE month(date(dt)) = 11
            AND YEAR(date(dt)) = 2018 GROUP BY country
    ) t ON t.country = u1.country
    WHERE month(date(dt)) = 12 
    AND YEAR(date(dt)) = 2018
    GROUP BY country

【讨论】:

  • 这实际上是错字 - 这仍然会为我产生错误:第 6:5 行:不匹配的输入 'join' 期望 {, '.', '[', 'group', ' order', 'have', 'limit', 'at', 'or', 'and', 'union', 'except', 'intersect', '+', '-', '*', '/' , '%', '||'}(服务:amazonathena;状态代码:400;错误代码:invalidrequestexception;请求 ID:1385cbc9-e45a-495f-93e6-cc037cda9eee)
【解决方案2】:

你想加入两个 Select 的结果:

SELECT t2.*, t.m2
FROM
 (   
   SELECT count(distinct uuid) m1, country
   FROM user u1
   WHERE month(date(dt)) = 12
     AND YEAR(date(dt)) = 2018
   GROUP BY country
 ) as t2
JOIN
 (
   SELECT count(distinct uuid) m2, country
   FROM user
   WHERE month(date(dt)) = 11
     AND YEAR(date(dt)) = 2018
   GROUP BY country
 ) as t
ON t.country = t2.country

但这将删除两个月都没有数据的国家/地区,然后您必须切换到 FULL OUTER JOIN。

在您的情况下,使用条件聚合要容易得多:

SELECT country
  ,count(distinct case when month(date(dt)) = 12 AND YEAR(date(dt)) = 2018 then uuid end) as m1
  ,count(distinct case when month(date(dt)) = 11 AND YEAR(date(dt)) = 2018 then uuid end) as m2
FROM user
GROUP BY country

【讨论】:

  • 非常感谢。尽管在这种情况下,第二种方法肯定更有意义,但这是我正在寻找的第一种方法,因此我可以从概念上理解如何构造查询。再次,非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 2021-07-10
  • 1970-01-01
相关资源
最近更新 更多