Quando eu executo "SELECT * FROM table", obtive resultados como abaixo:
1 item1 data1
2 item1 data2
3 item2 data3
4 item3 data4
Como você pode ver, existem registros dup da coluna2 (item1 são duplicados). Então, como eu poderia obter resultados como este:
1 item1 data1
2 item2 data3
3 item3 data4
Apenas um registro é retornado da duplicata, junto com o restante dos registros exclusivos.
Respostas:
Com a
distinct
palavra-chave com nomes de coluna única e múltipla, você obtém registros distintos:SELECT DISTINCT column 1, column 2, ... FROM table_name;
fonte
Se você só precisa remover duplicatas, use
DISTINCT
.GROUP BY
deve ser usado para aplicar operadores agregados a cada grupoGROUP BY v DISTINCT
fonte
Depende de qual linha você deseja devolver para cada item exclusivo. Seus dados parecem indicar o valor mínimo dos dados, nesta instância do SQL Server.
SELECT item, min(data) FROM table GROUP BY item
fonte
Existem 4 métodos que você pode usar:
Considere o seguinte exemplo
TABLE
com dados de teste:/** 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
Opção 1: SELECIONE DISTINTO
Esta é a maneira mais simples e direta, mas também a mais limitada:
SELECT DISTINCT word, num FROM dupes ORDER BY word, num; /* word|num| ----|---| aaa |100| bbb |200| bbb |400| ccc |300| ddd |400| */
Opção 2: GROUP BY
Agrupamento permite que você adicione dados agregados, como o
min(id)
,max(id)
,count(*)
, etc: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| */
Opção 3: subconsulta
Usando uma subconsulta, você pode primeiro identificar as linhas duplicadas a serem ignoradas e, em seguida, filtrá-las na consulta externa com a
WHERE NOT IN (subquery)
construção:/** 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| */
Opção 4: Expressão de tabela comum com ROW_NUMBER ()
Na Expressão de Tabela Comum (CTE), selecione ROW_NUMBER (), particionado pela coluna do grupo e ordenado na ordem desejada. Em seguida, SELECIONE apenas os registros que possuem
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| */
fonte
apenas use a junção interna porque agrupar por não funcionará com várias colunas dizendo que não está contido em nenhuma função agregada.
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;
fonte
Acho que, se não conseguir usar o DISTINCT por algum motivo, o GROUP BY funcionará.
fonte
Para obter todas as colunas em seu resultado, você precisa colocar algo como:
SELECT distinct a, Table.* FROM Table
ele colocará um como a primeira coluna e o resto será TODAS as colunas na mesma ordem de sua definição. Ou seja, a coluna a será repetida.
fonte
select distinct * from ...
Selecione Eff_st de (selecione EFF_ST, ROW_NUMBER () sobre (PARTITION BY eff_st) XYZ - de ABC.CODE_DIM
) onde XYZ = 1 pedido por EFF_ST busca as primeiras 5 linhas apenas
fonte