【问题标题】:Merging similar Athena (Presto) queries合并相似的 Athena (Presto) 查询
【发布时间】:2020-02-11 03:22:21
【问题描述】:

我是 SQL 和其他查询语言的新手,所以我对它们有一些疑问。

我在 Athena 中有以下两个查询,它们非常相似,但在一种情况下,传递了一个附加参数并使用了 INNER JOIN。第一个获取某个表的一列中有多少不同的值,第二个执行相同的操作,但使用连接的表连接两个表,并对另一列添加限制。

--Query #1
SELECT COUNT(DISTINCT(usertoken)) users
FROM "database"

WHERE country = ${country}
and serverdate between CAST('${fromdate}' As DATE) and CAST('${todate}' As DATE) 


--Query #2
SELECT COUNT(DISTINCT(usertoken)) users
FROM "database" op
INNER JOIN "location_0" cities
ON op.loc0id = cities.id

WHERE openings.country = ${country}
and openings.serverdate between CAST('${fromdate}' As DATE) and CAST('${todate}' As DATE)
and cities.id in (${cities_list})

${} 之间的参数是外部传递的,并且都是字符串类型,除了 ${cities_list},它是一个整数列表(日期转换为 DATE)。两者都可以正常工作且没有问题。

我的问题如下:我可以只使用一个查询来执行这两个操作,具体取决于 cities_list 的值吗?我在执行此查询之前检查此值是否为 Null,并根据它执行一个或另一个,但我希望只有一个查询能够执行这两种情况(因为大多数它们是相同的,我不想有多余的代码)。

TL;DR:我想将这两个查询合并为一个适用于两种情况的查询(cities_list 有一个值,或者是 Null),添加最后一个仅当某个参数不是 Null 时才产生条件(如果可能,如果参数不是 Null,则只执行 INNER JOIN)。

谢谢!

【问题讨论】:

    标签: sql count pivot presto amazon-athena


    【解决方案1】:

    你可以使用JOINCOUNT(DISTINCT),但你需要LEFT JOIN

    SELECT COUNT(DISTINCT op.usertoken) as users,
           COUNT(DISTINCT CASE WHEN cities.id in (${cities_list}) THEN op.usertoken END) as users_2
    FROM "database" op LEFT JOIN
         "location_0" cities
         ON op.loc0id = cities.id
    WHERE openings.country = ${country} AND
          openings.serverdate between CAST('${fromdate}' As DATE) and CAST('${todate}' As DATE);
    

    也就是说,如果JOIN 仅用于查找单个值,则很有可能根本不需要它:

    SELECT COUNT(DISTINCT op.usertoken) as users,
           COUNT(DISTINCT CASE WHEN op.loc0id in (${cities_list}) THEN op.usertoken END) as users_2
    FROM "database" op 
    WHERE openings.country = ${country} AND
          openings.serverdate between CAST('${fromdate}' As DATE) and CAST('${todate}' As DATE);
    

    【讨论】:

      【解决方案2】:

      你可以做条件聚合:

      SELECT 
          COUNT(DISTINCT usertoken) users1,
          COUNT(DISTINCT CASE WHEN ci.id in (${ci.list}) THEN usertoken END) users2
      FROM "database" op
      INNER JOIN "location_0" cities ci ON op.loc0id = ci.id
      WHERE 
          op.country = ${country}
          AND op.serverdate between CAST('${fromdate}' As DATE) and CAST('${todate}' As DATE)
      

      【讨论】:

        猜你喜欢
        • 2020-08-15
        • 2020-01-13
        • 1970-01-01
        • 1970-01-01
        • 2017-06-17
        • 2017-09-04
        • 2020-06-10
        • 2023-03-03
        • 2020-09-12
        相关资源
        最近更新 更多