[SQL] 요소 번호의 PostgreSQL unnest ()
SQL요소 번호의 PostgreSQL unnest ()
I 분리 값 열이있는 경우, I가 unnest () 함수를 사용할 수있다 :
myTable
id | elements
---+------------
1 |ab,cd,efg,hi
2 |jk,lm,no,pq
3 |rstuv,wxyz
select id, unnest(string_to_array(elements, ',')) AS elem
from myTable
id | elem
---+-----
1 | ab
1 | cd
1 | efg
1 | hi
2 | jk
...
어떻게 요소 번호를 포함 할 수 있습니까? 즉 :
id | elem | nr
---+------+---
1 | ab | 1
1 | cd | 2
1 | efg | 3
1 | hi | 4
2 | jk | 1
...
나는 소스 문자열에있는 각 요소의 원래 위치를 원한다. 나는 윈도우 함수 (ROW_NUMBER () 등의 순위 ())을 시도했지만 그들은 소스 테이블의 같은 행에 있기 때문에 난 항상 어쩌면 1.거야?
나는 그것이 나쁜 테이블 디자인 알고있다. 난 그냥 그것을 해결하기 위해 노력하고있어 내 것이 아니합니다.
해결법
-
==============================
1.집합을 반환하는 기능을 함께 사용의 순서와 :
집합을 반환하는 기능을 함께 사용의 순서와 :
9.3+ PG의 횡 기능을 조합하고 pgSQL의-해커에이 스레드에있어서, 상기 쿼리가 지금과 같이 쓸 수있다 :
SELECT t.id, a.elem, a.nr FROM tbl AS t LEFT JOIN LATERAL unnest(string_to_array(t.elements, ',')) WITH ORDINALITY AS a(elem, nr) ON TRUE;
왼쪽은 모든 행 왼쪽 테이블의 TRUE 보존 ON ... 가입하는 경우에도 올바른 반환하지 행에 대한 테이블 식입니다. 그 더 관심 있다면 당신은 측면 가입 암시 십자가 형태로 자세한 이하, 그렇지 않으면 해당 이것을 사용할 수 있습니다 :
SELECT t.id, a.elem, a.nr FROM tbl t, unnest(string_to_array(t.elements, ',')) WITH ORDINALITY a(elem, nr);
또는 간단 (배열 열 인 편곡) 실제 배열을 기반으로하는 경우 :
SELECT t.id, a.elem, a.nr FROM tbl t, unnest(t.arr) WITH ORDINALITY a(elem, nr);
심지어 최소한의 구문 :
SELECT id, a, ordinality FROM tbl, unnest(arr) WITH ORDINALITY a;
A는 자동으로 테이블과 컬럼 별명입니다. 추가 된 순서와 컬럼의 기본 이름에 순서입니다. 그러나 명시 적으로 열 별칭과 테이블 자격 열을 추가하는 것이 좋습니다 (안전, 청소기)입니다.
와 ROW_NUMBER () OVER (ELEM BY 아이디 ORDER BY PARTITION) 당신은 정렬 순서가 아닌 문자열의 원래 순서 위치의 서수에 따라 번호를 얻을.
당신은 단순히 순서에 의해 생략 할 수있다 :
SELECT *, row_number() OVER (PARTITION by id) AS nr FROM (SELECT id, regexp_split_to_table(elements, ',') AS elem FROM tbl) t;
이 정상적으로 작동하고 나는 그것이 간단한 쿼리에서 휴식 본 적이 있지만, PostgreSQL는 ORDER BY없이 행의 순서에 관하여 아무것도 주장하지 않습니다. 이 때문에 구현 세부 사항 작업에 발생합니다.
빈 구분 된 문자열에서 요소의 순서 번호를 보장하려면 :
SELECT id, arr[nr] AS elem, nr FROM ( SELECT *, generate_subscripts(arr, 1) AS nr FROM (SELECT id, string_to_array(elements, ' ') AS arr FROM tbl) t ) sub;
또는 간단 실제 배열을 기반으로하는 경우 :
SELECT id, arr[nr] AS elem, nr FROM (SELECT *, generate_subscripts(arr, 1) AS nr FROM tbl) t;
dba.SE에 대답 관련 :
이러한 기능 중 어느 것도 아직 사용할 수 없습니다 : RETURNS 표, generate_subscripts (), unnest (), array_length (). 하지만이 작동합니다 :
CREATE FUNCTION f_unnest_ord(anyarray, OUT val anyelement, OUT ordinality integer) RETURNS SETOF record LANGUAGE sql IMMUTABLE AS 'SELECT $1[i], i - array_lower($1,1) + 1 FROM generate_series(array_lower($1,1), array_upper($1,1)) i';
배열 인덱스 요소의 서수의 위치와 다를 수 있음을 특히 참고. 확장 기능이 데모를 고려하십시오
CREATE FUNCTION f_unnest_ord_idx(anyarray, OUT val anyelement, OUT ordinality int, OUT idx int) RETURNS SETOF record LANGUAGE sql IMMUTABLE AS 'SELECT $1[i], i - array_lower($1,1) + 1, i FROM generate_series(array_lower($1,1), array_upper($1,1)) i'; SELECT id, arr, (rec).* FROM ( SELECT *, f_unnest_ord_idx(arr) AS rec FROM (VALUES (1, '{a,b,c}'::text[]) -- short for: '[1:3]={a,b,c}' , (2, '[5:7]={a,b,c}') , (3, '[-9:-7]={a,b,c}') ) t(id, arr) ) sub; id | arr | val | ordinality | idx ----+-----------------+-----+------------+----- 1 | {a,b,c} | a | 1 | 1 1 | {a,b,c} | b | 2 | 2 1 | {a,b,c} | c | 3 | 3 2 | [5:7]={a,b,c} | a | 1 | 5 2 | [5:7]={a,b,c} | b | 2 | 6 2 | [5:7]={a,b,c} | c | 3 | 7 3 | [-9:-7]={a,b,c} | a | 1 | -9 3 | [-9:-7]={a,b,c} | b | 2 | -8 3 | [-9:-7]={a,b,c} | c | 3 | -7
비교:
-
==============================
2.시험:
시험:
select v.*, row_number() over (partition by id order by elem) rn from (select id, unnest(string_to_array(elements, ',')) AS elem from myTable) v
-
==============================
3.사용 첨자 생성 기능. http://www.postgresql.org/docs/current/static/functions-srf.html#FUNCTIONS-SRF-SUBSCRIPTS
사용 첨자 생성 기능. http://www.postgresql.org/docs/current/static/functions-srf.html#FUNCTIONS-SRF-SUBSCRIPTS
예를 들면 :
SELECT id , elements[i] AS elem , i AS nr FROM ( SELECT id , elements , generate_subscripts(elements, 1) AS i FROM ( SELECT id , string_to_array(elements, ',') AS elements FROM myTable ) AS foo ) bar ;
더 간단하게 :
SELECT id , unnest(elements) AS elem , generate_subscripts(elements, 1) AS nr FROM ( SELECT id , string_to_array(elements, ',') AS elements FROM myTable ) AS foo ;
-
==============================
4.요소의 순서가 중요하지 않은 경우, 당신은 할 수
요소의 순서가 중요하지 않은 경우, 당신은 할 수
select id, elem, row_number() over (partition by id) as nr from ( select id, unnest(string_to_array(elements, ',')) AS elem from myTable ) a
-
==============================
5.페이지의 V8.4 전에 이전 버전의 사용자 정의 unnest을 ()가 필요합니다. 우리는 인덱스로 요소를 반환하는이 오래된 기능을 적용 할 수 있습니다 :
페이지의 V8.4 전에 이전 버전의 사용자 정의 unnest을 ()가 필요합니다. 우리는 인덱스로 요소를 반환하는이 오래된 기능을 적용 할 수 있습니다 :
CREATE FUNCTION unnest2(anyarray) RETURNS TABLE(v anyelement, i integer) AS $BODY$ SELECT $1[i], i FROM generate_series(array_lower($1,1), array_upper($1,1)) i; $BODY$ LANGUAGE sql IMMUTABLE;
from https://stackoverflow.com/questions/8760419/postgresql-unnest-with-element-number by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SQL, 숫자의 보조 테이블 (0) | 2020.03.07 |
---|---|
[SQL] 는 SQL 서버에서 어떻게 물건과 'XML 경로에 대한'작업 (0) | 2020.03.07 |
[SQL] MySQL의에서 동일한 열 값이 행을 반환하는 방법 (0) | 2020.03.07 |
[SQL] 최대 절전 모드를 사용하는 경우 어떻게 매개 변수 값을 쿼리 문자열을 인쇄 (0) | 2020.03.07 |
[SQL] 변수로 테이블 이름 (0) | 2020.03.07 |