如何在 Postgres 中构建一个函数来计算两个 "select count(*)" 查询的百分比?

how to build a function in Postgres that calculats Percentage from two "select count(*)" queries?

我正在尝试构建一个函数来返回具有特定条件的行的百分比。

这是我的尝试:

CREATE OR REPLACE FUNCTION osm_prozent ()
RETURNS integer AS $$
DECLARE 
      a integer;
      b integer;
      ergebnis integer;
BEGIN
  a = select into a count(*)
    from osm_street;
  b = select into b count(*)
    from osm_street
    where hausnummer like '%-%'
    or hausnummer like '% %' 
    or hausnummer like '%/%' 
    or hausnummer like '%;%'
    or hausnummer like '%,%'
    or hausnummer ~ '([a-z,A-Z])';  

  ergebnis = (b/a)*100;
  return ergebnis;
END;
$$ LANGUAGE plpgsql;

变量 a207000 变量 b11000. 最后我应该有类似 5.31%.

的东西

谁能帮忙正确写出这个函数?

您的正则表达式过滤器加上几个赞可以简化为单个正则表达式(另请注意,您的正则表达式通过添加括号增加了不必要的负载,a-z 和 A-Z 之间的逗号不是分隔符,而是匹配还有逗号,您还在类似比较列表中包含了 TWICE!)。一个更简单的函数代码是:

CREATE OR REPLACE FUNCTION osm_prozent () RETURNS double precision AS $$
  SELECT 100. * (SELECT COUNT(*) FROM osm_street WHERE hausnummer ~* '[a-z /;,-]') / (SELECT COUNT(*) FROM osm_street);
$$ LANGUAGE sql;

您可以进行两项明显的改进,按重要性排序:

  1. 让 table 传球 1 次,而不是传球 2 次
  2. 简化第二个查询的 where 条件

先处理第二项:

可以使用一个正则表达式测试将where条件更改为只有一个比较。这个表达式:

where hausnummer like '%-%'
or hausnummer like '% %' 
or hausnummer like '%/%'
or hausnummer like '%;%'
or hausnummer like '%,%'
or hausnummer ~ '([a-z,A-Z])'

可以简单地表示为:

where hausnummer ~ '[a-z,A-Z /;-]'

接下来,为了仅通过 table,在条件上使用 sum() 以在捕获 count(*) 的同时捕获命中数。使用上面的改进作为条件,你的查询可以变成:

select 100.0 * sum(case when hausnummer ~ '[a-z,A-Z /;-]' then 1 end) / count(*)
from osm_street

除非您需要一个存储过程,否则您现在可以完全放弃它,因为您只需一个简单的查询即可获得结果。

如果您迫切需要一个存储过程(不推荐),它只是上述查询的一个薄包装(不增加任何价值):

CREATE OR REPLACE FUNCTION osm_prozent () RETURNS double precision AS $$
BEGIN
  RETURN select 100.0 * sum(case when hausnummer ~ '[a-z,A-Z /;-]' then 1 end) / count(*) from osm_street;
END;
$$ LANGUAGE plpgsql;

请注意,我怀疑你最后的条件 hausnummer ~ '([a-z,A-Z])' 不是你想要的。首先,括号是多余的,可以在不改变含义的情况下将其删除,即它与 hausnummer ~ '[a-z,A-Z]' 相同,并且如果 hausnummber 包含字母或逗号则为真。

如果这不是您想要的,请对此答案发表评论,解释您真正想要的。