a 테이블
PK_ID NAME NUMBERS AGE
1 김철 2,4,23,5 35
2 김철2 12,14,23,65 35
3 김철3 2,44,23,55 35
4 김철4 24,4,27,25 35
B 테이블
PK_ID NUMBER KWAMOK
1 23 국어
1 12 수학
1 -99 장연
1 2 사회
1 23 물리
1 44 과학
1 21 탐구
a 테이블에 NUMBERS안에 속해 있는 b 테이블에 잇는 데이타를 모두 블러오고 싶습니다
통 모르겠습니다
in으로 하니까 오류가 발생합니다
numBERS와 NUMBER 는, VARCHAR입나다
Comment 6
-
Terry
2016.02.02 17:20
-
문상연
2016.02.02 18:16
너무 고맙습니다 그런데 너무 기네요
정상적인 테이블 설계를 하신다면 어떻게 하시나요?
-
Terry
2016.02.02 19:09
보다 더 좋은 방법도 있겠지만..
상기 데이터는 A 라는 테이블과 NUMBERS 라는 컬럼이
1:N 의 관계입니다.
프로그램(클라이언트단) 에서 코드 데이터들을 문자열 결합하여
컬럼의 형태로 저장한걸로 보여지구요.
저라면 하기와 같이 테이블 2개로 분리합니다.
1. A 테이블
1) 컬럼 List ( PK_ID,NAME,AGE )
2. A_seg 테이블
1) 컬럼 List ( PK_ID,NUMBERS )
A.KEY 속성
A) PK_ID 와 NUMBERS 2개의 복합 PK 로 구성
B) A 테이블의 PK_ID 와 A_seg 테이블의 PK_ID 를 FK 로
A 테이블의 첫번째 샘플 데이터를 토대로 예시를 든다면 아래와 같이 되겠죠
Select '1','김철' ,'2,4,23,5' ,35 Union All
1. A 테이블 데이터
Select '1','김철',35
2. A_seg 테이블 데이터
Select '1','2'
Select '1','4'
Select '1','23'
Select '1','5'
상기의 시나리오는 A 테이블의 PK 가PK_ID 라는 가정하에서 진행된 겁니다.
데이터를 저런형태로 성격에 맞게 테이블 분리해서 넣어두면
차후 Select 시에 훨씬 간결해지고
처리하기도 수월해집니다.
참고만 하세요~
저도 초보라..이게 최선이 아닐수도 있다는 점 미리 밝힙니다..-,-;;;
-
문상연
2016.02.02 20:23
고맙습니다
많은 도움이 되었습니다
-
Terry
2016.02.02 19:25
위 덧글에 보태서
저런 형태로 테이블 분리했다고 가정시
차후 데이터 조회시 하기와 같이 되겠죠..
( A 테이블이 원본? 테이블. B는 과목이 들어간 테이블 이라고 가정시 )
1. Join 만으로 데이터 처리
Select a.PK_ID
,a.NAME
,b.NUMBERS
,c.KWAMOK
From A a
Inner Join A_seg b On a.PK_ID = b.PK_ID
Inner Join B c On b.NUMBERS = c.NUMBERS
--> 상기 쿼리는 1:N 이기에, A_seg, B 의 row 수만큼 데이터가 조회됨
만약 초기 형태대로 조회하려면?
하기와 같은 형태로 하시면 됩니다.
;with A(PK_ID,NAME,AGE) As
(
Select '1','김철',35
)
,A_seg(PK_ID,NUMBERS) As
(
Select '1','2' Union All
Select '1','4' Union All
Select '1','23' Union All
Select '1','5'
)
,B(PK_ID,NUMBERS,KWAMOK) As
(
Select '1','2' ,'국어' Union All
Select '1','4' ,'수학' Union All
Select '1','23' ,'물리' Union All
Select '1','5' ,'탐구'
)
,C(seq,PK_ID,NAME,AGE,NUMBERS,KWAMOK) As
(
Select ROW_NUMBER() over(partition By a.PK_ID Order By a.PK_ID,b.NUMBERS)
,a.PK_ID
,a.NAME
,a.AGE
,b.NUMBERS
,c.KWAMOK
From A a
Inner Join A_seg b On a.PK_ID = b.PK_ID
Inner Join B c On b.NUMBERS = c.NUMBERS
)
,D(seq,PK_ID,NAME,AGE,NUMBERS,KWAMOK) As
(
Select a.seq
,a.PK_ID
,a.NAME
,a.AGE
,Convert(varchar(max),a.NUMBERS)
,Convert(varchar(max),a.KWAMOK)
FROM C a
Where a.seq = 1
Union AllSelect a.seq
,a.PK_ID
,a.NAME
,a.AGE
,Convert(varchar(max),b.NUMBERS + ',' + a.NUMBERS)
,Convert(varchar(max),b.KWAMOK + ',' + a.KWAMOK)
FROM C a
Inner Join D b On a.seq = b.seq + 1
And a.PK_ID = b.PK_ID
)
Select a.PK_ID
,a.NAME
,a.NUMBERS
,a.KWAMOK
From D a
Where a.seq = (
Select MAX(b.seq)
From D b
Where b.PK_ID = a.PK_ID
)
-
minsouk
2016.02.04 13:41
직접 설계한 테이블이면 정규화 이론을 조금 살펴보고 1정규화 위반이 정당한지 판단해 봅니다.
넘이 만든거고 고칠수 없다면 CLR 이나 컴마로 구분된 데이터를 자르기를 SQLER 에서 찾아봅니다. 너무 많은 예제가 있을겁니다.
테이블 설계가 잘못된 듯한 느낌인데요^^;;
정상적인 설계라면
일단 a 테이블에 대해서
Numbers 라는 항목들을 저장할 수 있는
seg 테이블이 있어야 맞는듯해보이네요..-,-;;
일단 데이터는 나오게끔 처리는 했습니다..
실력이 부족해서 쿼리가 좀 복잡합니다 ^^;
하기 쿼리 참고하시고, 분석하시면 되지 않을까 싶네요..
---쿼리시작---
;with tblA(PK_ID,NAME,NUMBERS,AGE) As
(
Select '1','김철' ,'2,4,23,5' ,35 Union All
Select '2','김철2','12,14,23,65',35 Union All
Select '3','김철3','2,44,23,55' ,35 Union All
Select '4','김철4','24,4,27,25' ,35
)
,tblB(PK_ID,NUMBERS,KWAMOK) As
(
Select '1','23' ,'국어' Union All
Select '1','12' ,'수학' Union All
Select '1','-99','장연' Union All
Select '1','2' ,'사회' Union All
--Select '1','23' ,'물리' Union All
Select '1','44' ,'과학' Union All
Select '1','21' ,'탐구'
)
,tblC(seq,PK_ID,NAME,NUMBERSo,NUMBERSl,NUMBERS) As
(
Select 1
,a.PK_ID
,a.NAME
,a.NUMBERS
,SUBSTRING(a.NUMBERS,(
Case When IsNull(CharIndex(',',a.NUMBERS),0) = 0 Then 0
Else IsNull(CharIndex(',',a.NUMBERS),0) +1
End
)
,
(
Case When IsNull(CharIndex(',',a.NUMBERS),0) = 0 Then 0
Else LEN(a.NUMBERS)
End
)
)
,SUBSTRING(a.NUMBERS,1,(
Case When IsNull(CharIndex(',',a.NUMBERS),0) = 0 Then Len(a.NUMBERS)
Else IsNull(CharIndex(',',a.NUMBERS),0) -1
End
)
)
From tblA a
Union All
Select a.seq + 1
,a.PK_ID
,a.NAME
,a.NUMBERSo
,SUBSTRING(a.NUMBERSl,(
Case When IsNull(CharIndex(',',a.NUMBERSl),0) = 0 Then 0
Else IsNull(CharIndex(',',a.NUMBERSl),0) +1
End
)
,
(
Case When IsNull(CharIndex(',',a.NUMBERSl),0) = 0 Then 0
Else LEN(a.NUMBERSl)
End
)
)
,SUBSTRING(a.NUMBERSl,1,(
Case When IsNull(CharIndex(',',a.NUMBERSl),0) = 0 Then Len(a.NUMBERSl)
Else IsNull(CharIndex(',',a.NUMBERSl),0) -1
End
)
)
From tblC a
Where IsNull(a.NUMBERSl,'') <> ''
)
,tblCC(seq,PK_ID,NAME,NUMBERSo,NUMBERSl,NUMBERS) As
(
Select Convert(Integer,ROW_NUMBER() Over( Partition By a.PK_ID,a.NAME Order By a.PK_ID,a.NAME,a.NUMBERS))
,a.PK_ID
,a.NAME
,a.NUMBERSo
,a.NUMBERSl
,a.NUMBERS
From tblC a
Where Exists ( Select 'x' From tblB b Where a.NUMBERS = b.NUMBERS )
)
,tblE(seq,PK_ID,NAME,NUMBERS,KWAMOK,NUM) As
(
Select 1
,a.PK_ID
,a.NAME
,Convert(varchar(max),a.NUMBERS)
,Convert(varchar(max),b.KWAMOK)
,a.NUMBERS
From tblCC a
Inner Join
tblB b
On a.NUMBERS = b.NUMBERS
Where a.seq = 1
Union All
Select a.seq
,a.PK_ID
,a.NAME
,Convert(varchar(max),c.NUMBERS + ',' + a.NUMBERS)
,Convert(varchar(max),c.KWAMOK + ',' + b.KWAMOK)
,a.NUMBERS
From tblCC a
Inner Join
tblB b
On a.NUMBERS = b.NUMBERS
Inner Join
tblE c
On a.seq = c.seq + 1
And a.PK_ID = c.PK_ID
And a.NAME = c.NAME
)
Select a.PK_ID
,a.NAME
,a.NUMBERS As 원본NUMBERS
,b.NUMBERS As 존재하는NUMBERS
,b.KWAMOK As 존재하는KWAMOK
From tblA a
Left Outer Join
(
Select a.PK_ID
,a.NAME
,MAX(a.NUMBERS) As NUMBERS
,MAX(a.KWAMOK) As KWAMOK
From tblE a
Group By a.PK_ID
,a.NAME
) b
On a.PK_ID = b.PK_ID
And a.NAME = b.NAME
---쿼리끝---