2012-02-04 5 views
4

나는 하나의 이벤트에 대해 true (출석), false (비 출석) 및 NULL에 해당하는 배열 요소를 계산합니다. PostgreSQL 카운트 어레이 값

는 편집 :

난 그냥 내가 PSQL에서 생각대로 배열

userconfirm bool[] 

이 충분하다

너무 단순하고 행동하지 않는 것을 깨달았다. 그러나, 나는 여전히 true/false/null 값을 계산하는 것과 같은 문제가 있습니다. 이 새로운 제약 조건과 일치하도록 아래 질문을 편집하려고 시도합니다. 오류가 있으면 사과드립니다.


나는 userconfirm[314] = true이 참석 해당 사용자 번호 (314)를 의미 할 것 같은

userconfirm bool[] 

으로 열 수 있습니다. (false = 참석하지 않음, NULL = 읽지 않음/etc).

이 기능에 가장 적합한 솔루션 (사용자가 이벤트 참석 여부를 알리는 방법)이 확실하지 않지만이 열의 집계 함수에 문제가 있습니다.

select count(*) from foo where id = 6 AND true = ANY (userconfirm); 

이것은 단지 1을 반환하며 "계산 배열"이라는 단어를 사용하면 아무 것도 유용하지 않습니다.

단일 이벤트에 대해 서로 다른 값을 계산하려면 어떻게해야합니까?

답변

2

당신이처럼 SELECT에 unnest를 사용할 수 있습니다

=> select id, (select sum(case b when 't' then 1 else 0 end) from unnest(bits) as dt(b)) as trues from bools; 
id | trues 
----+------- 
    1 |  2 
    2 |  1 
    3 |  0 
    4 |  3 
    5 |  2 

:

=> select * from bools; 
id |  bits  
----+-------------- 
    1 | {t,t,f} 
    2 | {t,f} 
    3 | {f,f} 
    4 | {t,t,t} 
    5 | {f,t,t,NULL} 

당신이 얻을 것이 주어진

예를 들어
select whatever, 
     (select sum(case b when 't' then 1 else 0 end) from unnest(userconfirm) as dt(b)) 
from your_table 
-- ... 

, 너무 못생긴 경우, 기능 :

create function count_trues_in(boolean[]) returns bigint as $$ 
    select sum(case b when 't' then 1 else 0 end) 
    from unnest($1) as dt(b) 
$$ language sql; 

과 꽤 최대 쿼리 사용

=> select id, count_trues_in(bits) as trues from bools; 
id | trues 
----+------- 
    1 |  2 
    2 |  1 
    3 |  0 
    4 |  3 
    5 |  2 
+0

그게 효과가있는 것 같습니다.그리고 나는 그 반대의 것을 얻기 위해 그것을 반대로 할 수 있습니다. 나는 당신이 사실 인 인덱스 목록을 얻는 방법을 알지 못한다고 생각하지 않습니까? 예 : 1434를 반환해라. – TLP

+0

@TLP : 당신은'unnest'와'generate_series'의 조합으로 할 수 있다고 생각합니다; 'unnest'는 배열을 열고'generate_series'는 인덱스 번호를 제공합니다. 그런 다음 다시 배열 할 'array_agg'. –

+0

@TLP : 아니면 인덱스를 제공하기 위해'rank() over'하십시오. –

1

당신은 array_length 기능의 결과를 SUM 수 :

SELECT SUM(array_length(userconfirm, 2)) WHERE id = 6; 
+1

미안 해요, 난 그냥 내 질문에 실현이 변경되었습니다. 배열은 내가 생각한 것처럼 작동하지 않는다. 대신'bool []'을 사용하고 있습니다. 배열 길이를 합산하는 것은 올바른 해결책이 아닌 것 같습니다. 두 개의 null이 아닌 값이있는 배열의 합계가 293이됩니다. – TLP

0

이 하나의 트릭 (unnest)을 수행 할 수 있습니다.

postgres=# with y(res) as (
postgres(#    with x(a) as (
postgres(#      values (ARRAY[true,true,false]) 
postgres(#      union all 
postgres(#      values (ARRAY[true,null,false]) 
postgres(#    ) 
postgres(#    select unnest(a) as res 
postgres(#    from x 
postgres(#  ) 
postgres-# select count(*) 
postgres-# from y 
postgres-# where res; 
count 
------- 
    3 
(1 row) 


postgres=# 
+0

이것은 매우 복잡해 보입니다. 그리고 어떻게 이것을 내 식탁에 적용할까요? 나는 두 개의 배열을 비교하지 않고 하나의 배열을 하나의 값과 비교하려고합니다. – TLP

+0

unnest 함수는 배열을 테이블 구조 (y 하위 쿼리)로 분해합니다. 단일 열 테이블로 변환 된 배열에서 조건을 평가하는 SQL 쿼리에서 count (*)를 사용할 수 있습니다. res = true에 대한 체킹은 res에 대한 체킹과 같습니다. –