SQL 计数匹配

SQL Count Matches

我有一个包含 191 个值的列表,我想将它们与列进行比较。我最终想要计算在我的主列表 (matches/(non-matches + NULL)) 中具有值的行的百分比。

我知道我可以做类似下面的事情,但我想知道这是否是最有效的方法?是否可以创建一个存储值的数组并对此进行检查?不确定 best practice 给出的方法是什么 我有 191 个值要检查?

我希望避免将 191 csv 放入参数中,因为这是对 formatting/readability 的打击。有没有办法将这些值存储在数组或临时 table 中,这样我就可以将一个速记变量放入实际查询中?或者无论要检查多少个值,使用下面的 method/average 方法仍然是最好的方法吗?

SELECT
    SUM(CASE WHEN COALESCE(field, '') IN (COMMA SEPARATED VALUES) THEN 1 ELSE 0 END) as matches,
    COUNT(COALESCE(field)) as total_rows
FROM table

此外,我相信 COUNT(*)COUNT(1)NULL 字段视而不见,所以任何人都可以确认使用 COUNT(COALESCE(FIELD)) 是否确保计数包括字段中的空值?

我想你只是想要:

SELECT AVG(CASE WHEN field IN (COMMA SEPARATED VALUES) THEN 1.0 ELSE 0 END) as match_ratio
FROM table

一个选项使用 avg():

select avg(case when field in (<<csv list>>) then 1.0 else 0 end) rows_ratio
from mytable

使用数组传递值可能更简单:

select avg(case when contains(<< array of values>>, field) then 1.0 else 0 end) rows_ratio
from mytable

Presto 不支持临时 table,但您可以使用内联 table(WITH 子句结合 VALUES)来提高查询的可读性以避免在聚合表达式中包含一长串值。

然后,您可以通过执行以下操作来计算匹配数。请注意使用 FILTER 以提高可读性。

count(*) FILTER (WHERE field IN (SELECT value FROM data))

这是一个完整的例子:

WITH data(value) as (VALUES
   'value1',
   'value2',
   ...
)
SELECT
    count(*) AS total_rows,
    count(*) FILTER (WHERE field IN (SELECT value FROM data)) AS matches
FROM t