合并类似的雅典娜(Presto)查询



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

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

--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(。

谢谢!

您可以执行条件聚合:

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)

您可以使用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);

最新更新