복붙노트

[SQL] 값의 그룹 별 사용자 정의 SERIAL / 자동 증가

SQL

값의 그룹 별 사용자 정의 SERIAL / 자동 증가

나는 종류의 블로그 시스템을 만들려고 노력 그리고 난 약간의 문제에 부딪쳤다.

간단히 내 문서 테이블에 3 열 거기에 넣어 :

id SERIAL,
category VARCHAR FK,
category_id INT

ID 열은 분명 PK이며 모든 물품에 대한 글로벌 식별자로서 사용된다.

분류 컬럼 카테고리 ..도이다.

CATEGORY_ID 그래서 현재 장소에 고유 한 (카테고리 CATEGORY_ID)가 제약 범주 내에서 고유 ID로 사용된다.

그러나 나는 또한 자동 증가에 CATEGORY_ID 원하는.

때마다 내가 같은 쿼리를 실행할 수 있도록 내가 원하는

INSERT INTO article(category) VALUES ('stackoverflow');

나는 CATEGORY_ID 열이 자동으로 '유래'카테고리의 최신 CATEGORY_ID에 따라 작성 될 수 싶습니다.

내 논리 코드에서이를 달성하는 것은 매우 쉽습니다. 난 그냥 최신 NUM을 선택하고 그 +1 삽입하지만 두 개의 쿼리를 포함한다. 나는 하나 개의 쿼리에이 모든 것을 할 수있는 SQL 솔루션을 찾고 있어요.

해결법

  1. ==============================

    1.이 접근하는 적어도 몇 가지 방법이 있습니다. 내 마음에 오는 첫 번째 :

    이 접근하는 적어도 몇 가지 방법이 있습니다. 내 마음에 오는 첫 번째 :

    각 행에 대해 실행되는 트리거 내, INSERT 명령문의 입력 값을 덮어 쓰기함으로써 CATEGORY_ID 항목에 대한 값을 할당한다.

    여기에 행동의 코드를 확인하기 위해 SQL 바이올린의

    간단한 테스트를 위해, 나는 각 범주에 대해 고유해야 카테고리와 자신의 아이디의 지주 문서 테이블을 만드는거야. 점을 제시하는 관련 아니에요 - 나는 제약 작성을 생략했다.

    create table article ( id serial, category varchar, category_id int )
    

    이미 그 자리에 자동 증가를 () 함수 generate_series를 사용하여 두 가지 범주에 대한 몇 가지 값을 삽입.

    insert into article(category, category_id)
      select 'stackoverflow', i from generate_series(1,1) i
      union all
      select 'stackexchange', i from generate_series(1,3) i
    

    트리거 기능을 작성, 그 MAX (CATEGORY_ID)을 선택하고 우리가 행을 삽입하고 카테고리 1에 의해 그 가치가 증가하고 INSERT 트리거가 처리되기 전에 (테이블에 실제 INSERT로 이동하기 전에 값을 오른쪽으로 덮어 쓰게 그).

    CREATE OR REPLACE FUNCTION category_increment()
    RETURNS trigger
    LANGUAGE plpgsql
    AS
    $$
    DECLARE
      v_category_inc int := 0;
    BEGIN
      SELECT MAX(category_id) + 1 INTO v_category_inc FROM article WHERE category = NEW.category;
      IF v_category_inc is null THEN
        NEW.category_id := 1;
      ELSE
        NEW.category_id := v_category_inc;
      END IF;
    RETURN NEW;
    END;
    $$ 
    

    트리거로서의 기능을 사용.

    CREATE TRIGGER trg_category_increment 
      BEFORE INSERT ON article 
      FOR EACH ROW EXECUTE PROCEDURE category_increment()
    

    기존의 범주와 존재하지 않는 것들에 대한 좀 더 값 (포스트 트리거 기기)를 삽입.

    INSERT INTO article(category) VALUES 
      ('stackoverflow'),
      ('stackexchange'),
      ('nonexisting');
    

    쿼리 데이터를 선택하는 데 사용 :

    select category, category_id From article order by 1,2
    

    초기 삽입 검색 결과 :

    category    category_id
    stackexchange   1
    stackexchange   2
    stackexchange   3
    stackoverflow   1
    

    최종 삽입 후 결과 :

    category    category_id
    nonexisting     1
    stackexchange   1
    stackexchange   2
    stackexchange   3
    stackexchange   4
    stackoverflow   1
    stackoverflow   2
    
  2. ==============================

    2.이것은 여러 번 요청을받은하고 일반적인 생각은 다중 사용자 환경에서 실패 할 수밖에 없다 - 그리고 블로그 시스템 사운드는 정확히 같은 케이스를 좋아한다.

    이것은 여러 번 요청을받은하고 일반적인 생각은 다중 사용자 환경에서 실패 할 수밖에 없다 - 그리고 블로그 시스템 사운드는 정확히 같은 케이스를 좋아한다.

    가장 좋은 대답은 그래서 :하지 마십시오. 다른 접근 방법을 고려한다.

    테이블에서 완전히 열 CATEGORY_ID 드롭 - 이미 저장하지 않을 정보를 다른 두 개의 열 (ID, 카테고리)를 저장하지 않습니다.

    귀하의 ID가 신뢰할 수있는 방식으로 이미 직렬 열 및 자동 증가이다.

    당신은, 카테고리 별 차이없이 CATEGORY_ID의 어떤 종류를해야하는 경우) (ROW_NUMBER와 즉석에서 그것을 생성 :

  3. ==============================

    3.PostgreSQL은이를 달성하기 위해 서열을 사용한다; 그것은 당신의 MySQL에서 사용되는 것과는 다른 접근 방식이다. 전체 참조 http://www.postgresql.org/docs/current/static/sql-createsequence.html를 살펴 보자.

    PostgreSQL은이를 달성하기 위해 서열을 사용한다; 그것은 당신의 MySQL에서 사용되는 것과는 다른 접근 방식이다. 전체 참조 http://www.postgresql.org/docs/current/static/sql-createsequence.html를 살펴 보자.

    기본적으로 당신은에 의해 시퀀스 (데이터베이스 개체)를 만들 :

    CREATE SEQUENCE serials;
    

    당신이 당신의 테이블에 추가 할 때 당신은해야합니다 :

    INSERT INTO mytable (name, id) VALUES ('The Name', NEXTVAL('serials')
    
  4. from https://stackoverflow.com/questions/34571125/custom-serial-autoincrement-per-group-of-values by cc-by-sa and MIT license