如何在PostgreSQL中计算具有条件的数组的记录

时间:2017-01-25 10:21:22

标签: sql arrays postgresql loops conditional-statements

我有例如带有

的表“员工”
last_name :: character varying
handed_texts :: text[]

其中text是自己的数据类型,带有“(”Date“,title / not_exist)”。

x:=({},1,2,...)

时可能有x个条目

示例:

jones , {"(2017-01-01, stars_in_univ)", "(2017-01-01, not_exist)",   "(2017-01-02, unemployed ants)"}
tomes , {"(2017-01-01, not_exist)", "(2017-01-08, shared_minds)"}

我现在的问题:我想计算每个名字的现有文本。 我试过例如类似的东西:

SELECT last_name, handed_texts,
       CASE
           WHEN handed_texts IS NULL THEN 0
           ELSE
               FOREACH i IN ARRAY handed_texts
               DECLARE c integer;
               SET c = 0;
               LOOP
                   IF i NOT LIKE '%not_exist%' THEN c+1 ELSE c END IF
                 return c
              END LOOP
      END AS counted_texts
FROM employee

我知道声明是完全错误的,但我找不到任何方式以我的系统接受的方式声明变量,所以我只是在我认为应该声明的地方写了它。 我试图计算的另一种方法是创建一个新的数组,我只是将正确/想要的记录放入并使用array_length,但这似乎比上面的更加灾难。

3 个答案:

答案 0 :(得分:1)

我不能保证它是有效率的,但如果你不再重新聚合,那么这似乎是可能的:

with exploded as (
  select last_name, unnest (handed_texts) as handed
  from employee
)
select
  last_name, array_agg (handed) as handed_texts
from exploded
where
  handed not like '%not_exist%'
group by last_name

那就是说,如果你把hand_texts变成了自己的表:

create table handed_texts (
   last_name varchar,
   title_date date,
   title_name text
)

并且在last_name上进行了加入,我认为它可以提供更清晰的解决方案。

答案 1 :(得分:0)

您可以将其转换为字符串,并使用标准LIKE构造:

select last_name, count(*) 
from (select last_name, array_to_string(handed_texts,',','') t
      from employee e2) a
where a.t like '%not_exist%
group by last_name;

抱歉,我的rextester

翻译错过了

答案 2 :(得分:0)

此处unnest功能可能很有用。您可以像这样使用它:

SELECT e.id, COUNT(texts.id)
FROM employee AS e
LEFT JOIN (
    -- this "unfolds" all arrays as if they were a single table of all texts of all employees
    SELECT id, UNNEST(handed_texts) AS handed_texts
    FROM employee
) AS texts ON texts.id = e.id
WHERE ... -- any condition on single array element being now in texts "table"
GROUP BY e.id