2014-03-02 3 views
0

많은 (+1000) 열과 행 (~ 1M)이있는 테이블이 있습니다. 열은 값 1 또는 NULL입니다.Postgresql 행에 특정 값이있는 모든 열과 열 이름을 선택하십시오.

나는 특정 행 (사용자) 1.

테이블에 많은 열이 있기 때문에 값이 열 이름을 검색 극단적를 얻을 것이다 열을 지정하기위한 선택 할 수 있도록하려면 긴 쿼리.

+0

당신은에 행을 변환 할 수 있습니다 'hstore' 객체를 키와 값의 분리 된 배열에 넣고 값이 1 인 키만 반환합니다. –

+0

이것이 이상한 이유는 무엇입니까? 내 테이블은 스파 스 매트릭스로 변환 할 때 공간을 절약하기 위해 매우 넓습니다. –

+0

@ManuelG 목표는 의미가 있지만, SQL은 매우 나쁘다 (동적 컬럼 액세스). 그래서 당신은 공간을 절약하고, 해결하기에 다소 어려운 문제를 스스로에게주고 있습니다. 행을 사용하려면 기본적으로 키/값 형식으로 피벗 해제해야합니다. –

답변

0

SQL을 사용하면 열에 대한 동적 액세스 나 행을 하나의 집합으로 처리하는 것이 매우 어렵습니다. 이 방법이 더 쉽다면 좋겠지 만 SQL의 유형화 된 특성과 관계 개념은 잘 작동하지 않습니다. 현재 형태로 데이터 세트를 사용하는 것은 실망 스러울 것입니다. 대신 배열 json 또는 hstore을 저장하는 것이 좋습니다.

실제로이 특정 데이터 모델의 경우 비트 필드를 사용할 수 있습니다. bit(n) and bit varying(n)을 참조하십시오.

그래도 현재 모델 PostgreSQL 확장 기능으로 작업 쿼리를 만들 수 있습니다.

주어 샘플 :

CREATE TABLE blah (id serial primary key, a integer, b integer, c integer); 
INSERT INTO blah(a,b,c) VALUES (NULL, NULL, 1), (1, NULL, 1), (NULL, NULL, NULL), (1, 1, 1); 

I가 hstore (또는 최신 버전의 PostgreSQL 상기 JSON 함수에서의)을 사용하여 키/값 세트로 각 행을 피벗 것이다. SQL 자체는 동적으로 열에 액세스 할 수 없으므로 확장을 사용해야합니다. 그래서 :

SELECT id, hs FROM blah, LATERAL hstore(blah) hs; 

다음 세트에 hstore의 압축을 풉니 다

SELECT id, k, v FROM blah, LATERAL each(hstore(blah)) kv(k,v); 

...하는 당신의 기준과 일치 값을 필터링 할 수 있습니다 가리 킵니다. 모든 열이 text로 변환되어 있습니다, 그래서 당신은 그것을 다시 캐스팅 할 수 있습니다 :

SELECT id, k FROM blah, LATERAL each(hstore(blah)) kv(k,v) WHERE v::integer = 1; 

을 또한 일치에서 id를 제외해야하므로 :

regress=> SELECT id, k FROM blah, LATERAL each(hstore(blah)) kv(k,v) WHERE v::integer = 1 AND 
k <> 'id'; 
id | k 
----+--- 
    1 | c 
    2 | a 
    2 | c 
    4 | a 
    4 | b 
    4 | c 
(6 rows) 
관련 문제