SQL로 고유 한 레코드를 선택하는 방법
"SELECT * FROM table"을 수행하면 다음과 같은 결과가 나타납니다.
1 item1 data1
2 item1 data2
3 item2 data3
4 item3 data4
보시다시피 column2에서 dup 레코드가 있습니다 (item1은 dupped). 그래서 어떻게하면 다음과 같은 결과를 얻을 수 있습니까?
1 item1 data1
2 item2 data3
3 item3 data4
나머지 고유 레코드와 함께 중복에서 하나의 레코드 만 반환됩니다.
SELECT DISTINCT
또는 사용 GROUP BY
하여이를 수행 할 수 있습니다 .
SELECT DISTINCT a, c
FROM table_c
또는
SELECT a, b
FROM table_c
GROUP BY a, b
GROUP BY
COUNT()
또는 같은 집계 함수를 사용하려는 경우 더 유용합니다.SUM()
SELECT a, b, count(*)
FROM table_c
GROUP BY a, b
SELECT a, b, sum(d)
FROM table_c
GROUP BY a, b
중복 항목 만 제거해야하는 경우 DISTINCT
. GROUP BY
집계 연산자를 각 그룹에 적용하는 데 사용해야합니다.
각 고유 항목에 대해 반환하려는 행에 따라 다릅니다. 귀하의 데이터는 SQL Server에 대한이 인스턴스에서 최소 데이터 값을 나타내는 것 같습니다.
SELECT item, min(data)
FROM table
GROUP BY item
group by는 집계 함수에 포함되지 않은 여러 열에서 작동하지 않기 때문에 내부 조인을 사용하십시오.
SELECT a.*
FROM yourtable a
INNER JOIN
(SELECT yourcolumn,
MIN(id) as id
FROM yourtable
GROUP BY yourcolumn
) AS b
ON a.yourcolumn= b.yourcolumn
AND a.id = b.id;
다음과 같은 4 가지 방법을 사용할 수 있습니다.
- 뚜렷한
- 그룹화
- 하위 쿼리
- ROW_NUMBER ()를 사용하는 CTE (공통 테이블 식)
TABLE
테스트 데이터가 있는 다음 샘플 을 고려하십시오 .
/** Create test table */
CREATE TEMPORARY TABLE dupes(word text, num int, id int);
/** Add test data with duplicates */
INSERT INTO dupes(word, num, id)
VALUES ('aaa', 100, 1)
,('bbb', 200, 2)
,('ccc', 300, 3)
,('bbb', 400, 4)
,('bbb', 200, 5) -- duplicate
,('ccc', 300, 6) -- duplicate
,('ddd', 400, 7)
,('bbb', 400, 8) -- duplicate
,('aaa', 100, 9) -- duplicate
,('ccc', 300, 10); -- duplicate
옵션 1 : DISTINCT 선택
이것은 가장 간단하고 간단하지만 가장 제한적인 방법이기도합니다.
SELECT DISTINCT word, num
FROM dupes
ORDER BY word, num;
/*
word|num|
----|---|
aaa |100|
bbb |200|
bbb |400|
ccc |300|
ddd |400|
*/
옵션 2 : GROUP BY
그룹화 당신이 같이 집계 데이터를 추가 할 수 있습니다 min(id)
, max(id)
, count(*)
, 등 :
SELECT word, num, min(id), max(id), count(*)
FROM dupes
GROUP BY word, num
ORDER BY word, num;
/*
word|num|min|max|count|
----|---|---|---|-----|
aaa |100| 1| 9| 2|
bbb |200| 2| 5| 2|
bbb |400| 4| 8| 2|
ccc |300| 3| 10| 3|
ddd |400| 7| 7| 1|
*/
옵션 3 : 하위 쿼리
하위 쿼리를 사용하여 먼저 무시할 중복 행을 식별 한 다음 WHERE NOT IN (subquery)
구문 을 사용하여 외부 쿼리에서 필터링 할 수 있습니다 .
/** Find the higher id values of duplicates, distinct only added for clarity */
SELECT distinct d2.id
FROM dupes d1
INNER JOIN dupes d2 ON d2.word=d1.word AND d2.num=d1.num
WHERE d2.id > d1.id
/*
id|
--|
5|
6|
8|
9|
10|
*/
/** Use the previous query in a subquery to exclude the dupliates with higher id values */
SELECT *
FROM dupes
WHERE id NOT IN (
SELECT d2.id
FROM dupes d1
INNER JOIN dupes d2 ON d2.word=d1.word AND d2.num=d1.num
WHERE d2.id > d1.id
)
ORDER BY word, num;
/*
word|num|id|
----|---|--|
aaa |100| 1|
bbb |200| 2|
bbb |400| 4|
ccc |300| 3|
ddd |400| 7|
*/
옵션 4 : ROW_NUMBER ()를 사용하는 공통 테이블 표현식
In the Common Table Expression (CTE), select the ROW_NUMBER(), partitioned by the group column and ordered in the desired order. Then SELECT only the records that have ROW_NUMBER() = 1
:
WITH CTE AS (
SELECT *
,row_number() OVER(PARTITION BY word, num ORDER BY id) AS row_num
FROM dupes
)
SELECT word, num, id
FROM cte
WHERE row_num = 1
ORDER BY word, num;
/*
word|num|id|
----|---|--|
aaa |100| 1|
bbb |200| 2|
bbb |400| 4|
ccc |300| 3|
ddd |400| 7|
*/
I find that if I can't use DISTINCT for any reason, then GROUP BY will work.
To get all the columns in your result you need to place something as:
SELECT distinct a, Table.* FROM Table
it will place a as the first column and the rest will be ALL of the columns in the same order as your definition. This is, column a will be repeated.
Select Eff_st from ( select EFF_ST,ROW_NUMBER() over(PARTITION BY eff_st) XYZ - from ABC.CODE_DIM
) where XYZ= 1 order by EFF_ST fetch first 5 row only
참고URL : https://stackoverflow.com/questions/1641718/how-to-select-unique-records-by-sql
'Programing' 카테고리의 다른 글
외부 파일 또는 어셈블리에서 WPF 스타일 또는 기타 정적 리소스로드 (0) | 2020.11.15 |
---|---|
MsBuild에서 PDB 파일 생성 비활성화 (0) | 2020.11.15 |
Linux에서 분할 오류를 포착하는 방법은 무엇입니까? (0) | 2020.11.15 |
MOQ-다른 인터페이스로 캐스팅해야하는 인터페이스를 모의하는 방법은 무엇입니까? (0) | 2020.11.15 |
jQuery : 이벤트 핸들러 함수에서 이벤트 객체를 인수로 전달하지 않고 가져 오는 방법은 무엇입니까? (0) | 2020.11.15 |