database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
ㆍPostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
PostgreSQL Q&A 8334 게시물 읽기
No. 8334
중복함수 , 아무래 해도 안되서 질문드립니다..
작성자
souler(souler)
작성일
2009-07-27 14:31
조회수
7,208
INSERT INTO tablecom (1, 2, 3)
VALUES (generate_series(1,80), 5, generate_series(5,400));

위 쿼리문을 사용해서 아래처럼 삽입형태를 구현할 수 있을 줄 알았는데, 안되는군요.

왜 안되는걸까요?

1 | 2 | 3
--------
1 | 5 | 5
2 | 5 | 10
3 | 5 | 15
4 | 5 | 20

.. | .. | ..

80 | 5 | 400

에러내용은 다음과 같습니다.

ERROR:  duplicate key value violates unique constraint "tablecom_pkey"

********** 에러 **********

ERROR: duplicate key value violates unique constraint "tablecom_pkey"
SQL 상태:23505

 

이 글에 대한 댓글이 총 16건 있습니다.

에러 메시지를 보면 unique constraint 제약조건 위반이라 나와있습니다.

tablecom_pkey 제약조건은 이름으로 유추해보건대 tablecom 테이블의 PK인것 같습니다.


1) 해당 테이블의 PK가 어떻게 잡혀있는지 확인하시고,

2) 사용하신 INSERT 문이 생성하는 데이터가 테이블에 이미 있는 데이터와 중복되지 않는지

확인해보시기 바랍니다.

xxx님이 2009-07-28 16:35에 작성한 댓글입니다. Edit

답변감사합니다.
저게 프라이머리키가 맞습니다. 아무래도 데이터가 중복입력되는 것 같은데,
제가 중복함수 generate_series 이걸 잘못 쓴거 같습니다.

아래의 이 결과가 나오려면

1 | 2 | 3
--------
1 | 5 | 5
2 | 5 | 10
3 | 5 | 15
4 | 5 | 20

.. | .. | ..

80 | 5 | 400

중복함수를 어떻게 써야하는지 모르곘습니다.

제, 짧은 지식으로 아래와 같이 썻는데 안되는 것 같아요. 조언좀 해주세요 ^^;

INSERT INTO tablecom (1, 2, 3)
VALUES (generate_series(1,80), 5, generate_series(5,400));

souler(souler)님이 2009-07-28 18:46에 작성한 댓글입니다.

8.4 라면 with 를 활용하면 될거 같습니다.




WITH RECURSIVE t (c1, c2, c3) as (

  values (1,5,5)

  UNION ALL

  select c1 + 1, c2, (c1 + 1) * c2 from t

  where c1 < 80

)

select * from t;



아니면 그냥 심플하게



select t as c1, 5 as c2, t * 5 as c3

from generate_series(1, 80) as t;




tyro님이 2009-07-28 22:09에 작성한 댓글입니다.
이 댓글은 2009-07-28 22:18에 마지막으로 수정되었습니다. Edit

고맙습니다! 일단, 노트북이라 확인은 못해보지만
감사합니다 ^^; 해보고 다시 하겠습니다.

souler(souler)님이 2009-07-28 22:42에 작성한 댓글입니다.

tyro 님이 말씀해주신

select t as c1, 5 as c2, t * 5 as c3

 

from generate_series(1, 80) as t;


문을 이용하니까 원하는 결과를 보여주네요.


그런데, 저 select 문을 insert 로 실제 데이터 입력하는 방법이 뭡니까?

souler(souler)님이 2009-07-29 08:47에 작성한 댓글입니다.

insert into ... select 구문을 사용하시면 됩니다.

tyro님이 2009-07-29 18:09에 작성한 댓글입니다. Edit

이렇게 하니까 되네요.

INSERT INTO T (C1, C2, C3)
SELECT T AS C1, 5 AS C2, T * 5 AS C3
FROM generate_series(1, 80) AS T;

감사합니다. 책에서 배운적이 있는데 실제로 사용하려니
이렇게 어렵네요. 아무튼 잘 배웠습니다. 감사합니다..

 

souler(souler)님이 2009-07-29 20:18에 작성한 댓글입니다.

이런! 실패했습니다.


1. 
WITH RECURSIVE t (c1, c2, c3) as (
  values (1,5,5)
  UNION ALL
  select c1 + 1, c2, (c1 + 1) * c2 from t
  where c1 < 80
  )
 select * from t;

1번 쿼리를 이용하면 첫번째 과정에서는 잘나옵니다.
80까지는 

1;5;5
2;5;10
3;5;15
.........
80;5;400

그러나 81부터 하려니

81;10;5
82;10;820
83;10;830
84;10;840

저렇게 되네요..

2. 
INSERT INTO T (C1, C2, C3)
SELECT T AS C1, 5 AS C2, T * 5 AS C3
FROM generate_series(1, 80) AS T;



1;5;5
2;5;10
3;5;15
.........
80;5;400

2번 쿼리도 마찬가지로 80까지는 잘 표시됩니다..

그러나 81부터.. 왠일인지 400 부터는 더해버리네요.

81;10;405
82;10;410
83;10;415
84;10;420
85;10;425
souler(souler)님이 2009-07-30 12:13에 작성한 댓글입니다.

81 부터 어떻게 쿼리를 날렸는지 두가지 다 쿼리문을 보여주세요


그리고 어떻게 나와야 하는지 예제 결과물도요

tyro님이 2009-07-30 13:06에 작성한 댓글입니다.
이 댓글은 2009-07-30 13:07에 마지막으로 수정되었습니다. Edit
1. 쿼리문 설명

INSERT INTO T (C1, C2, C3)
SELECT T AS C1, 5 AS C2, T * 5 AS C3
FROM generate_series(1, 80) AS T;

C 1,2,3 은 컬럼 1,2,3 을 말하는 것이고 T는 테이블입니다.
tyro 님이 가르쳐주신 것 중에서 두번째를 사용해볼께요.

2. 쿼리의 목적

C1 | C2 | C3

1  | 5  | 5
2  | 5  | 10
3  | 5  | 15

..

80  | 5  | 400

C1 은 말대로 ID값입니다. 1부터 행 번호가 매겨지는 것이라고 생각하면 되실거에요.

C2는 X 좌표값으로 80 행 마다 5씩 증가되는 값이에요.

1->80 까지는 5, 81->160 까지는 10 이렇게 말이에요.

C3는 Y 좌표값으로  1 행 마다 5씩 증가되는 값이에요.

1->80 이렇게 한블럭에 5~400 하나의 좌표를 구성하는거죠?.. 이렇게?

5,(5~400)  
10,(5~400)
15,(5~400)
20,(5~400)

3. 81 이후의 쿼리값

INSERT INTO T (C1, C2, C3)
SELECT T AS C1, 5 AS C2, T * 5 AS C3
FROM generate_series(1, 80) AS T;

위의 쿼리를 이용해서 80까지 입력을 하게 됩니다.

그 후에는 이렇게 해서 160 까지를 해보았습니다.

INSERT INTO T (C1, C2, C3)
SELECT T AS C1, 10 AS C2, T * 5 AS C3
FROM generate_series(81, 160) AS T;

그러니, 5부터 다시 시작해야 될 C3 가 기존의 400에 5씩 더해서

입력이 되더군요. 이렇게?

81;10;405
82;10;410
.............

정중히 다시 부탁드리겠습니다. 감사합니다.
souler(souler)님이 2009-07-30 13:35에 작성한 댓글입니다.

그럼 c3 만 틀린거군요..


그냥  - 400 을 뒤에 붙이시면 될거 같습니다.

tyro님이 2009-07-30 21:06에 작성한 댓글입니다. Edit

허걱..그럼 400부터 80000 까지 200번을 일일이...수정하면서 인서트 해야된다는 말이군요..


200번이야 뭐..-_-

souler(souler)님이 2009-07-31 07:40에 작성한 댓글입니다.

흐흐

내용이 잼있어서 souler님이 원하시는대로 되게 쿼리를 수정해봤습니다.



select t as c1, 5 as c2, (t % 80) * 5 + ( (t / 80) * 400 ) as c3

from generate_series(1, 80) as t;


맞는지 확인해보세여 ^^:

김병석(byung82)님이 2009-08-04 00:25에 작성한 댓글입니다.

그래도, 400 다음 81 행 부터는 5가 아닌 405 로 삽입되네요.

이 문제의 해결 법은 없는 것인가!

souler(souler)님이 2009-08-04 09:08에 작성한 댓글입니다.

내용을다시 읽어서


1-80 은 출력이 1, 5, (5 ~400);

81-160은 81, 10, (5~400);


이렇게 계속되는거라면


select t as c1,

case when t % 80 = 0

then (t/80) * 5 else (((t / 80)+1) * 5 ) end as c2,

case when t % 80 = 0

then 80 * 5 else (t % 80) * 5 end as c3

from generate_series(161, 240) as t;



^^:


그럼

김병석(byung82)님이 2009-08-04 11:41에 작성한 댓글입니다.
이 댓글은 2009-08-04 16:47에 마지막으로 수정되었습니다.

아까 오후에 확인하고, 어 또안되네.. 이런 실망감을 안고 
다시 댓글을 달려던 참이였습니다.

이런, 목에 걸린 십년 묵은 가시가 빠진듯한 기분이에요.
방금 해보니 성공적입니다.

언제쯤 이런 문제를 혼자 해결할 수 있으려나..
수학이 부족해서.... 이런 계산 어려워요 !

정말고마워요. 병석님, 사랑합니다. 하하;

souler(souler)님이 2009-08-04 21:12에 작성한 댓글입니다.
이 댓글은 2009-08-04 21:13에 마지막으로 수정되었습니다.
[Top]
No.
제목
작성자
작성일
조회
8379쿼리문 연산자에 대해서 [1]
souler
2009-08-04
6441
8360스키마별로 디비용량
조빠
2009-07-31
6501
8359날짜 변형관련 질문입니다. 부탁드립니다.~(__)굽신 [3]
초급개발자
2009-07-30
6804
8334중복함수 , 아무래 해도 안되서 질문드립니다.. [16]
souler
2009-07-27
7208
8333select 에서 가져온 값을.. [1]
빡테
2009-07-27
6233
8332select문을 사용하여 값을 int와 u_short형으로 가지고 오려고 합니다.. [1]
초보자
2009-07-27
6759
8325테이블을 어떻게만들어야될지... [2]
초보
2009-07-26
6528
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.021초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다