sql计数匹配

6ljaweal  于 2021-08-09  发布在  Java
关注(0)|答案(3)|浏览(365)

我有一个191个值的列表,我想和一个列进行比较。我最终想要得到在我的主列表中有值的%行的计数( matches/(non-matches + NULL) ).
我知道我可以做下面这样的事情,但我想知道这是不是最有效的方式?是否可以创建一个存储这些值的数组并对此进行检查?不知道是怎么回事 best practice 这样做的方法是给我191个值来检查?
我希望避免将191csv放入参数中,因为这是对格式/可读性的冲击。有没有一种方法可以将这些值存储在数组或临时表中,这样我就可以将一个简短的变量放到实际的查询中?或者,不管要检查多少个值,使用下面的方法/平均值方法仍然是最好的方法吗?

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)) 确保计数包含字段中的空值?

cnjp1d6j

cnjp1d6j1#

presto不支持临时表,但是可以通过使用内联表来提高查询的可读性( 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
slhcrj9b

slhcrj9b2#

我想你只是想:

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

3bygqnnd3#

一个选项使用 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

相关问题