안녕하세요
여러가지 방법을 고민하는데 더이상 머리가 돌아가지 않아서 고민에 대한
해답을 요청 드립니다.
바쁘시지만 혹시라도 의견이 있으면 부탁드립니다.
(최대한 단순화 하여 예시 드리겠습니다. )
TABLE 1이라는 테이블에는 컬럼 NAME, A1,A2,A3,A4,A5,A6 , B1,B2,B3,B4,B5,B6 이 있습니다.
NAME 이 PK라고 보시면 됩니다.
A1,A2,A3,A4,A5,A6 에는 각각의 값이 있고 B1,B2,B3,B4,B5,B6에도 각각의 값이 있는데
A1,A2,A3,A5,A5,A6에 있는 각각의 값은 순서에 상관없이 B1,B2,B3,B4,B5,B6에도 있어야 합니다.
예를 들면
A1 = 1 , A2= 2, A3= 3, A4=4, A5=5 , A6= 6 인 경우 B1=6, B2=1, B3=2, B4=5, B5=4, B6= 3
이면 됩니다.
저도 나름 쿼리를 짜봤는데 중복된 경우에 예외인 경우가 계속 발생해서
이걸 조금 더 쉽게 쿼리를 짤 수 있는지 궁금합니다.
A1 = 1 , A2= 3, A3= 3, A4=4, A5=4, A6= 6 인 경우 B1=1, B2=3, B3=4, B4=6, B5=4, B6= 3 이면 조회되야하고
A1 = 1 , A2= 3, A3= 3, A4=4, A5=4, A6= 6 인 경우 B1=1, B2=4, B3=4, B4=6, B5=4, B6= 3 이면 조회되면 안됩니다.
즉 A에 같은 값이 존재하는 경우의 갯수는 B에도 같은 값이 존재하는 경우의 갯수가 동일 해야한다고 보면됩니다.
혹시 쉽게 쿼리를 짤 수 있는 방법이 있을까요 ?
제가 짰던 쿼리 예시 )
SELECT * FROM TABLE1
WHERE (A1=B1 OR A1=B2 OR A1=B3 OR A1=B4 OR A1=B5 OR A1=B6) AND
(A2=B1 OR A2=B2 OR A2=B3 OR A2=B4 OR A2=B5 OR A2=B6) AND
(A3=B1 OR A3=B2 OR A3=B3 OR A3=B4 OR A3=B5 OR A3=B6) AND
(A4=B1 OR A4=B2 OR A4=B3 OR A4=B4 OR A4=B5 OR A4=B6) AND
(A5=B1 OR A5=B2 OR A5=B3 OR A5=B4 OR A5=B5 OR A5=B6) AND
(A6=B1 OR A6=B2 OR A6=B3 OR A6=B4 OR A6=B5 OR A6=B6) AND
(B1=A1 OR B1=A2 OR B1=A3 OR B1=A4 OR B1=A5 OR B1=A6) AND
(B2=A1 OR B2=A2 OR B2=A3 OR B2=A4 OR B2=A5 OR B2=A6) AND
(B3=A1 OR B3=A2 OR B3=A3 OR B3=A4 OR B3=A5 OR B3=A6) AND
(B4=A1 OR B4=A2 OR B4=A3 OR B4=A4 OR B4=A5 OR B4=A6) AND
(B5=A1 OR B5=A2 OR B5=A3 OR B5=A4 OR B5=A5 OR B5=A6) AND
(B6=A1 OR B6=A2 OR B6=A3 OR B6=A4 OR B6=A5 OR B6=A6) AND
중복된 값이 있어서 당연히 안되더라구요 도움 부탁드려요 ㅠㅠ
Comment 2
-
이리
2021.09.06 10:00
-
abcdefg
2021.09.06 10:44
-- 데이터 구성
USE tempdb;
GO
CREATE TABLE #TABLE1
(
name VARCHAR(100) PRIMARY KEY
, A1 INT
, A2 INT
, A3 INT
, A4 INT
, A5 INT
, A6 INT
);
GO
CREATE TABLE #TABLE2
(
name VARCHAR(100) PRIMARY KEY
, A1 INT
, A2 INT
, A3 INT
, A4 INT
, A5 INT
, A6 INT
);
GO
INSERT INTO #TABLE1
VALUES ('a', 1, 3, 3, 4, 4, 6), ('b', 1, 3, 3, 4, 4, 6);
GO
INSERT INTO #TABLE2
VALUES ('a', 1, 3, 4, 6, 4, 3), ('b', 1, 4, 4, 6, 4, 3);
GO
-- 여기까지는 같음.
# function하나 만들기 (문자열을 받아 split, order, string_agg.)
create function f_order_string(@str nvarchar(max))
returns nvarchar(max)
begin
declare @ret nvarchar(max) = ''
select @ret = string_agg(value, '')
from (
select top 6 value from string_split(@str, ',')
order by 1
) x
return @ret
end
go
-- 데이터 비교
select *
from (
select
name,
dbo.f_order_string (cast(A1 as nvarchar) + ',' + cast(A2 as nvarchar) + ',' + cast(A3 as nvarchar) + ',' + cast(A4 as nvarchar) + ',' +cast(A5 as nvarchar) + ',' +cast(A6 as nvarchar)) as a_string
from #table1
) a
inner join (
select
name,
dbo.f_order_string (cast(A1 as nvarchar) + ',' + cast(A2 as nvarchar) + ',' + cast(A3 as nvarchar) + ',' + cast(A4 as nvarchar) + ',' +cast(A5 as nvarchar) + ',' +cast(A6 as nvarchar)) as a_string
from #table2
) b
on a.name = b.name
and a.a_string = b.a_string
cmd_comment_vote_user Upvote1 Downvote0 Comment Update Delete
일단 제가 생각한 방법은 UNPIVOT을 해서 값들을 정렬 후 비교해서 갯수를 세는 방법인데.. 복잡하네요;;
예시주신 data로 테스트는 해 보았는데 다른 조건이 있거나 문제가 있으면 다시 알려주세요
고수님들은 더 쉬운 방법이 있으면 답변 부탁 드립니다.
USE tempdb;
GO
CREATE TABLE #TABLE1
(
name VARCHAR(100) PRIMARY KEY
, A1 INT
, A2 INT
, A3 INT
, A4 INT
, A5 INT
, A6 INT
);
GO
CREATE TABLE #TABLE2
(
name VARCHAR(100) PRIMARY KEY
, A1 INT
, A2 INT
, A3 INT
, A4 INT
, A5 INT
, A6 INT
);
GO
INSERT INTO #TABLE1
VALUES ('a', 1, 3, 3, 4, 4, 6), ('b', 1, 3, 3, 4, 4, 6);
GO
INSERT INTO #TABLE2
VALUES ('a', 1, 3, 4, 6, 4, 3), ('b', 1, 4, 4, 6, 4, 3);
GO
CREATE TABLE #TABLE1_UNPVT
(
name VARCHAR(100)
, col SYSNAME
, value INT
, RN INT
);
GO
CREATE TABLE #TABLE2_UNPVT
(
name VARCHAR(100)
, col SYSNAME
, value INT
, RN INT
);
GO
INSERT INTO #TABLE1_UNPVT
SELECT name
, value
, Orders
, ROW_NUMBER() OVER(PARTITION BY name ORDER BY Orders) AS RN
FROM (
SELECT name
, A1
, A2
, A3
, A4
, A5
, A6
FROM #TABLE1
) AS P
UNPIVOT
(
Orders FOR value
IN (A1, A2, A3, A4, A5, A6)
) AS UNPVT
;
GO
INSERT INTO #TABLE2_UNPVT
SELECT name
, value
, Orders
, ROW_NUMBER() OVER(PARTITION BY name ORDER BY Orders) AS RN
FROM (
SELECT name
, A1
, A2
, A3
, A4
, A5
, A6
FROM #TABLE2
) AS P
UNPIVOT
(
Orders FOR value
IN (A1, A2, A3, A4, A5, A6)
) AS UNPVT
;
GO
SELECT *
FROM
(
SELECT T1.name
, T1.col
, T1.value
, COUNT(*) OVER(PARTITION BY T1.name) AS CNT
FROM #TABLE1_UNPVT AS T1
INNER JOIN #TABLE2_UNPVT AS T2
ON T1.name = T2.name
AND T1.RN = T2.RN
AND T1.value = T2.value
) AS T1
WHERE T1.CNT = 6
GO