Cuando realizo "SELECT * FROM table" obtuve resultados como los siguientes:
1 item1 data1
2 item1 data2
3 item2 data3
4 item3 data4
Como puede ver, hay registros duplicados de la columna2 (el elemento1 está duplicado). Entonces, ¿cómo podría obtener un resultado como este?
1 item1 data1
2 item2 data3
3 item3 data4
Solo se devuelve un registro del duplicado, junto con el resto de los registros únicos.
Respuestas:
Con la
distinct
palabra clave con nombres de columna única y múltiple, obtiene registros distintos:SELECT DISTINCT column 1, column 2, ... FROM table_name;
fuente
Si solo necesita eliminar duplicados, utilice
DISTINCT
.GROUP BY
debe usarse para aplicar operadores agregados a cada grupoGRUPO POR V DISTINTO
fuente
Depende de la fila que quieras devolver para cada artículo único. Sus datos parecen indicar el valor mínimo de datos, por lo que en este caso para SQL Server.
SELECT item, min(data) FROM table GROUP BY item
fuente
Hay 4 métodos que puede utilizar:
Considere la siguiente muestra
TABLE
con datos de prueba:/** 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
Opción 1: SELECT DISTINCT
Esta es la forma más simple y directa, pero también la más limitada:
SELECT DISTINCT word, num FROM dupes ORDER BY word, num; /* word|num| ----|---| aaa |100| bbb |200| bbb |400| ccc |300| ddd |400| */
Opción 2: AGRUPAR POR
Agrupación le permite añadir los datos agregados, como el
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| */
Opción 3: subconsulta
Con una subconsulta, primero puede identificar las filas duplicadas para ignorarlas y luego filtrarlas en la consulta externa con la
WHERE NOT IN (subquery)
construcción:/** 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| */
Opción 4: Expresión de tabla común con ROW_NUMBER ()
En Common Table Expression (CTE), seleccione ROW_NUMBER (), dividido por la columna de grupo y ordenado en el orden deseado. Luego SELECCIONE solo los registros que tienen
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| */
fuente
solo use la unión interna porque el grupo por no funcionará con varias columnas que digan que no están contenidas en una función 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;
fuente
Encuentro que si no puedo usar DISTINCT por algún motivo, GROUP BY funcionará.
fuente
Para obtener todas las columnas en su resultado, debe colocar algo como:
SELECT distinct a, Table.* FROM Table
colocará a como la primera columna y el resto serán TODAS las columnas en el mismo orden que su definición. Es decir, se repetirá la columna a .
fuente
select distinct * from ...
Seleccione Eff_st de (seleccione EFF_ST, ROW_NUMBER () sobre (PARTITION BY eff_st) XYZ - de ABC.CODE_DIM
) donde XYZ = 1 pedido por EFF_ST recupera solo las primeras 5 filas
fuente