[SQL] 다른 열을 기준 서열의 PostgreSQL
SQL다른 열을 기준 서열의 PostgreSQL
내가 같은 테이블이 있다고 가정하자 :
Column | Type | Notes
---------+------------ +----------------------------------------------------------
id | integer | An ID that's FK to some other table
seq | integer | Each ID gets its own seq number
data | text | Just some text, totally irrelevant.
SEQ ID +가 결합 열쇠이다.
내가보고 싶은 것은 :
ID | SEQ | DATA
----+------ +----------------------------------------------
1 | 1 | Quick brown fox, lorem ipsum, lazy dog, etc etc.
1 | 2 | Quick brown fox, lorem ipsum, lazy dog, etc etc.
1 | 3 | Quick brown fox, lorem ipsum, lazy dog, etc etc.
1 | 4 | Quick brown fox, lorem ipsum, lazy dog, etc etc.
2 | 1 | Quick brown fox, lorem ipsum, lazy dog, etc etc.
3 | 1 | Quick brown fox, lorem ipsum, lazy dog, etc etc.
3 | 2 | Quick brown fox, lorem ipsum, lazy dog, etc etc.
3 | 3 | Quick brown fox, lorem ipsum, lazy dog, etc etc.
3 | 4 | Quick brown fox, lorem ipsum, lazy dog, etc etc.
당신이 볼 수 있듯이, ID와 서열의 조합은 고유합니다.
나는 확실하지 내 테이블을 설정하는 방법에있어 (또는 삽입 문을?)이 작업을 수행 할 수 있습니다. I 이드에 따라 서브 서열 인 서열 결과 삽입 ID 및 데이터 싶다.
해결법
-
==============================
1.문제 없어요! 우리는 두 개의 테이블, 사물과 물건을 만들 것입니다. 물건은 당신이 당신의 질문에 설명하는 테이블이 될 것, 사물은 참조하는 하나입니다 :
문제 없어요! 우리는 두 개의 테이블, 사물과 물건을 만들 것입니다. 물건은 당신이 당신의 질문에 설명하는 테이블이 될 것, 사물은 참조하는 하나입니다 :
CREATE TABLE things ( id serial primary key, name text ); CREATE TABLE stuff ( id integer references things, seq integer NOT NULL, notes text, primary key (id, seq) );
그리고 우리는 새로운 순서를 행이 만들어 질 때마다 생성됩니다 트리거와 함께 일을 설정합니다 :
CREATE FUNCTION make_thing_seq() RETURNS trigger LANGUAGE plpgsql AS $$ begin execute format('create sequence thing_seq_%s', NEW.id); return NEW; end $$; CREATE TRIGGER make_thing_seq AFTER INSERT ON things FOR EACH ROW EXECUTE PROCEDURE make_thing_seq();
이제 우리는 등 thing_seq_1, thing_seq_2, 등, 될 겁니다 ...
이제 물건을 다른 트리거 있도록 올바른 순서 각 시간을 사용 :
CREATE FUNCTION fill_in_stuff_seq() RETURNS trigger LANGUAGE plpgsql AS $$ begin NEW.seq := nextval('thing_seq_' || NEW.id); RETURN NEW; end $$; CREATE TRIGGER fill_in_stuff_seq BEFORE INSERT ON stuff FOR EACH ROW EXECUTE PROCEDURE fill_in_stuff_seq();
즉 행이 물건에 갈 때, ID 열에는 NEXTVAL에 전화를 올바른 순서를 찾는 데 사용되어 있는지 확인합니다.
여기 데모입니다 :
test=# insert into things (name) values ('Joe'); INSERT 0 1 test=# insert into things (name) values ('Bob'); INSERT 0 1 test=# select * from things; id | name ----+------ 1 | Joe 2 | Bob (2 rows) test=# \d List of relations Schema | Name | Type | Owner --------+---------------+----------+---------- public | stuff | table | jkominek public | thing_seq_1 | sequence | jkominek public | thing_seq_2 | sequence | jkominek public | things | table | jkominek public | things_id_seq | sequence | jkominek (5 rows) test=# insert into stuff (id, notes) values (1, 'Keychain'); INSERT 0 1 test=# insert into stuff (id, notes) values (1, 'Pet goat'); INSERT 0 1 test=# insert into stuff (id, notes) values (2, 'Family photo'); INSERT 0 1 test=# insert into stuff (id, notes) values (1, 'Redundant lawnmower'); INSERT 0 1 test=# select * from stuff; id | seq | notes ----+-----+--------------------- 1 | 1 | Keychain 1 | 2 | Pet goat 2 | 1 | Family photo 1 | 3 | Redundant lawnmower (4 rows) test=#
-
==============================
2.당신은 당신의 서열 값을 할당하는 윈도우 함수를 사용할 수 있습니다, 같은 :
당신은 당신의 서열 값을 할당하는 윈도우 함수를 사용할 수 있습니다, 같은 :
INSERT INTO YourTable (ID, SEQ, DATA) SELECT ID, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY DATA), DATA FROM YourSource
-
==============================
3.서열은 행이 삽입되는 순서를 반영 (또는 반영해야한다) 경우, 차라리 자동으로 입력됩니다 타임 스탬프를 사용하는 것 등) (ROW_NUMBER를 사용하여 행을 선택하면 즉석에서 일련 번호를 생성합니다 :
서열은 행이 삽입되는 순서를 반영 (또는 반영해야한다) 경우, 차라리 자동으로 입력됩니다 타임 스탬프를 사용하는 것 등) (ROW_NUMBER를 사용하여 행을 선택하면 즉석에서 일련 번호를 생성합니다 :
create table some_table ( id integer not null, inserted_at timestamp not null default current_timestamp, data text );
는 서열 열을 얻으려면, 당신은 할 수 있습니다 :
select id, row_number() over (partition by id order by inserted_at) as seq, data from some_table order by id, seq;
선택하지만 (특히 ID에 대한 인덱스, 배열)와 영구 서열 열을 사용하는 것에 비해 다소 느리게 될 것이다.
그건 당신이 중 하나가보기를 구체화하여, 또는 서열 열을 추가하고 정기적으로 업데이트로 볼 수 문제가 될 경우 (I는 성능상의 이유로 트리거에서이 작업을 수행 할 것입니다).
SQLFiddle 예 : http://sqlfiddle.com/#!15/db69b/1
-
==============================
4.그냥 추측.
그냥 추측.
INSERT INTO TABLE (ID, SEQ, DATA) VALUES ( IDVALUE, (SELECT max(SEQ) +1 FROM TABLE WHERE ID = IDVALUU), DATAVALUE );
-
==============================
5.다음은 표준 SQL을 사용하여 간단한 방법입니다 :
다음은 표준 SQL을 사용하여 간단한 방법입니다 :
INSERT INTO mytable (id, seq, data) SELECT << your desired ID >>, COUNT(*) + 1, 'Quick brown fox, lorem ipsum, lazy dog, etc etc.' FROM mytable WHERE id = << your desired ID (same as above) >>;
SQL 바이올린 데모를 참조하십시오.
(당신이 삽입 직후 같은 방법을 사용하여 행을 업데이트하는 트리거를 만드는 것이 좋습니다 수있는 비트 영리가되고 싶어합니다.)
-
==============================
6.나는 dynamicaly A가 트리 구조, 한 번에 모든 ID를 추가하지 저장할 같은 요구를했다. 이들의 수천이있을 수 있기 때문에 나는 각 그룹에 대해 순서 표를 사용하지 선호합니다. 이 경쟁 조건이 증명되어야한다, 그래서 그것은 집중적 인 멀티 프로세싱 환경에서 실행됩니다. 여기에 수준 1 삽입 fonction. 다른 레벨은 동일한 원리를 따릅니다.
나는 dynamicaly A가 트리 구조, 한 번에 모든 ID를 추가하지 저장할 같은 요구를했다. 이들의 수천이있을 수 있기 때문에 나는 각 그룹에 대해 순서 표를 사용하지 선호합니다. 이 경쟁 조건이 증명되어야한다, 그래서 그것은 집중적 인 멀티 프로세싱 환경에서 실행됩니다. 여기에 수준 1 삽입 fonction. 다른 레벨은 동일한 원리를 따릅니다.
각 그룹은 독립적으로 재사용 불가능한 ID를두고 순차적으로, 기능은 그룹 이름 및 하위 그룹의 이름을 수신하면 기존의 ID를 제공하거나 생성 및 새로운 ID를 반환한다. 나는 하나의 선택을 가지고 루프를 시도했지만 코드는 긴 및 열심히 읽기가 같습니다.
CREATE OR REPLACE FUNCTION getOrInsert(myGroupName TEXT, mySubGroupName TEXT) RETURNS INT AS $BODY$ DECLARE myId INT; BEGIN -- 1st try to get it if it already exists SELECT id INTO myId FROM myTable WHERE groupName=myGroupName AND subGroupName=mySubGroupName; IF NOT FOUND THEN -- Only 1 session can get it but others can read LOCK TABLE myTable IN SHARE ROW EXCLUSIVE MODE; -- 2nd try in case of race condition SELECT id INTO myId FROM myTable WHERE groupName=myGroupName AND subGroupName=mySubGroupName; IF NOT FOUND THEN -- Doesn't exist. Get next ID for this group. SELECT COALESCE(MAX(id), 0)+1 INTO myId FROM myTable WHERE groupName=myGroupName; INSERT INTO myTable (groupName, id, subGroupName) VALUES (myGroupName, myId, mySubGroupName); END IF; END IF; RETURN myId; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100;
그것을 시도하려면 :
CREATE TABLE myTable (GroupName TEXT, SubGroupName TEXT, id INT); SELECT getOrInsert('groupA', 'subgroupX'); -- Returns 1 ... SELECT * FROM myTable; groupname | subgroupname | id -----------+--------------+---- groupA | subgroupX | 1 groupA | subgroupY | 2 groupA | subgroupZ | 3 groupB | subgroupY | 1
-
==============================
7.PostgreSQL의 지원과 같은 고유의 열을 그룹화 :
PostgreSQL의 지원과 같은 고유의 열을 그룹화 :
CREATE TABLE example ( a integer, b integer, c integer, UNIQUE (a, c) );
PostgreSQL의 문서를 참조하십시오 - 5.3.3 항을
쉬운 :-)
-
==============================
8.나는 어떤 PostgreSQL을 특정 경험이없는,하지만 당신은 삽입 문에서 하위 쿼리를 사용할 수 있습니까? Mysqlish처럼 뭔가,
나는 어떤 PostgreSQL을 특정 경험이없는,하지만 당신은 삽입 문에서 하위 쿼리를 사용할 수 있습니까? Mysqlish처럼 뭔가,
INSERT INTO MYTABLE SET ID=4, SEQ=( SELECT MAX(SEQ)+1 FROM MYTABLE WHERE ID=4 ), DATA="Quick brown fox, lorem ipsum, lazy dog, etc etc."
from https://stackoverflow.com/questions/6821871/postgresql-sequence-based-on-another-column by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] JDBC를 사용하여 정수 열을 널 삽입 (0) | 2020.05.10 |
---|---|
[SQL] CASE WHEN 문 ORDER BY 절에 대한 (0) | 2020.05.10 |
[SQL] 집계 함수없이 SQL 서버에서 피벗 쿼리를 만드는 방법 (0) | 2020.05.10 |
[SQL] SQL Server와 같은 포함 괄호 문자 (0) | 2020.05.10 |
[SQL] SQL 독특한 VARCHAR 대소 문자 구분 질문 (0) | 2020.05.10 |