columnas - restriccion check sql server
SQL/mysql-¿Selecciona distintas/UNIQUE pero devuelve todas las columnas? (15)
Agregue GRUPO POR para el campo en el que desea verificar si hay duplicados que su consulta pueda parecer
SELECT field1, field2, field3, ...... FROM table GROUP BY field1
campo1 será verificado para excluir registros duplicados
o puede consultar como
SELECT * FROM table GROUP BY field1
Los registros duplicados de field1 están excluidos de SELECT
SELECT DISTINCT field1, field2, field3, ...... FROM table
Estoy tratando de cumplir con la siguiente declaración de SQL, pero quiero que devuelva todas las columnas, ¿es esto posible? Algo como:
SELECT DISTINCT field1, * from table
Desde la formulación de su pregunta, entiendo que desea seleccionar los valores distintos para un campo determinado y que cada uno de esos valores tenga todos los demás valores de columna en la misma fila. La mayoría de los DBMS no lo permitirán ni con DISTINCT
ni con GROUP BY
, porque el resultado no está determinado.
Piénselo así: si su field1
ocurre más de una vez, se field2
qué valor de field2
(dado que tiene el mismo valor para field1
en dos filas pero dos valores distintos de field2
en esas dos filas).
Sin embargo, puede usar funciones agregadas (explícitamente para cada campo que desee mostrar) y usar GROUP BY
lugar de DISTINCT
:
SELECT field1, MAX(field2), COUNT(field3), SUM(field4), .... FROM table GROUP BY field1
Esa es una muy buena pregunta. Ya he leído algunas respuestas útiles aquí, pero probablemente pueda agregar una explicación más precisa.
Reducir el número de resultados de consulta con una instrucción GROUP BY es fácil siempre y cuando no consulte información adicional. Supongamos que tiene la siguiente tabla ''ubicaciones''.
--country-- --city--
France Lyon
Poland Krakow
France Paris
France Marseille
Italy Milano
Ahora la consulta
SELECT country FROM locations
GROUP BY country
resultará en:
--country--
France
Poland
Italy
Sin embargo, la siguiente consulta
SELECT country, city FROM locations
GROUP BY country
... arroja un error en MS SQL, porque ¿cómo podría saber su computadora cuál de las tres ciudades francesas "Lyon", "París" o "Marsella" quiere leer en el campo a la derecha de "Francia"?
Para corregir la segunda consulta, debe agregar esta información. Una forma de hacer esto es usar las funciones MAX () o MIN (), seleccionando el valor mayor o menor entre todos los candidatos. MAX () y MIN () no solo son aplicables a valores numéricos, sino que también comparan el orden alfabético de los valores de cadena.
SELECT country, MAX(city) FROM locations
GROUP BY country
resultará en:
--country-- --city--
France Paris
Poland Krakow
Italy Milano
o:
SELECT country, MIN(city) FROM locations
GROUP BY country
resultará en:
--country-- --city--
France Lyon
Poland Krakow
Italy Milano
Estas funciones son una buena solución siempre que esté bien con la selección de su valor desde los extremos del orden alfabético (o numérico). Pero ¿y si este no es el caso? Supongamos que necesita un valor con una cierta característica, por ejemplo, comenzando con la letra ''M''. Ahora las cosas se complican.
La única solución que pude encontrar hasta ahora es poner toda su consulta en una subconsulta y construir la columna adicional con ayuda de las manos:
SELECT
countrylist.*,
(SELECT TOP 1 city
FROM locations
WHERE
country = countrylist.country
AND city like ''M%''
)
FROM
(SELECT country FROM locations
GROUP BY country) countrylist
resultará en:
--country-- --city--
France Marseille
Poland NULL
Italy Milano
Estás buscando un grupo por:
select *
from table
group by field1
Que ocasionalmente se puede escribir con un distintivo en la declaración:
select distinct on field1 *
from table
Sin embargo, en la mayoría de las plataformas, ninguno de los anteriores funcionará porque el comportamiento en las otras columnas no está especificado. (El primero funciona en MySQL, si eso es lo que estás usando).
Puede obtener los distintos campos y seguir seleccionando una única fila arbitraria cada vez.
En algunas plataformas (por ejemplo, PostgreSQL, Oracle, T-SQL), esto se puede hacer directamente usando las funciones de la ventana:
select *
from (
select *,
row_number() over (partition by field1 order by field2) as row_number
from table
) as rows
where row_number = 1
En otros (MySQL, SQLite), deberá escribir subconsultas que lo harán unirse a la tabla completa con ella misma ( example ), por lo que no se recomienda.
Gran pregunta @aryaxt: puedes decir que fue una gran pregunta porque la hiciste hace 5 años y hoy me topé con ella, ¡tratando de encontrar la respuesta!
Intenté editar la respuesta aceptada para incluir esto, pero en caso de que mi edición no aparezca en:
Si su tabla no era tan grande, y suponiendo que su clave principal era un entero de incremento automático, podría hacer algo como esto:
SELECT
table.*
FROM table
--be able to take out dupes later
LEFT JOIN (
SELECT field, MAX(id) as id
FROM table
GROUP BY field
) as noDupes on noDupes.id = table.id
WHERE
//this will result in only the last instance being seen
noDupes.id is not NULL
Para SQL Server, puede usar las funciones dense_rank y de ventanas adicionales para obtener todas las filas Y columnas con valores duplicados en columnas específicas. Aquí hay un ejemplo...
with t as (
select col1 = ''a'', col2 = ''b'', col3 = ''c'', other = ''r1'' union all
select col1 = ''c'', col2 = ''b'', col3 = ''a'', other = ''r2'' union all
select col1 = ''a'', col2 = ''b'', col3 = ''c'', other = ''r3'' union all
select col1 = ''a'', col2 = ''b'', col3 = ''c'', other = ''r4'' union all
select col1 = ''c'', col2 = ''b'', col3 = ''a'', other = ''r5'' union all
select col1 = ''a'', col2 = ''a'', col3 = ''a'', other = ''r6''
), tdr as (
select
*,
total_dr_rows = count(*) over(partition by dr)
from (
select
*,
dr = dense_rank() over(order by col1, col2, col3),
dr_rn = row_number() over(partition by col1, col2, col3 order by other)
from
t
) x
)
select * from tdr where total_dr_rows > 1
Esto es hacer un recuento de filas para cada combinación distinta de col1, col2 y col3.
Puedes hacerlo con una cláusula WITH
.
Por ejemplo:
WITH c AS (SELECT DISTINCT a, b, c FROM tableName)
SELECT * FROM tableName r, c WHERE c.rowid=r.rowid AND c.a=r.a AND c.b=r.b AND c.c=r.c
Esto también le permite seleccionar solo las filas seleccionadas en la consulta de cláusulas WITH
.
SELECT DISTINCT FIELD1, FIELD2, FIELD3 FROM TABLE1 funciona si los valores de las tres columnas son únicos en la tabla.
Si, por ejemplo, tiene varios valores idénticos para el nombre, pero el apellido y otra información en las columnas seleccionadas es diferente, el registro se incluirá en el conjunto de resultados.
Se puede hacer por consulta interna.
$query = "SELECT *
FROM (SELECT field
FROM table
ORDER BY id DESC) as rows
GROUP BY field";
Si entendí tu problema correctamente, es similar a uno que acabo de tener. Desea poder limitar la usabilidad de DISTINCT a un campo específico, en lugar de aplicarlo a todos los datos.
Si usa GROUP BY sin una función agregada, cualquiera que sea el campo que GROUP BY será su archivo DISTINCT.
Si realiza su consulta:
SELECT * from table GROUP BY field1;
Mostrará todos los resultados basados en una sola instancia de field1.
Por ejemplo, si tiene una tabla con nombre, dirección y ciudad. Una sola persona tiene varias direcciones registradas, pero solo desea una única dirección para la persona, puede consultar de la siguiente manera:
SELECT * FROM persons GROUP BY name;
El resultado será que solo aparecerá una instancia de ese nombre con su dirección, y la otra se omitirá de la tabla resultante. Precaución: si sus archivos tienen valores atómicos como primer nombre, último nombre que desea agrupar por ambos.
SELECT * FROM persons GROUP BY lastName, firstName;
porque si dos personas tienen el mismo apellido y usted solo se agrupa por apellido, una de esas personas se omitirá de los resultados. Necesitas tener esas cosas en consideración. Espero que esto ayude.
Simplemente incluya todos sus campos en la cláusula GROUP BY.
Sugeriría usar
SELECT * from table where field1 in
(
select distinct field1 from table
)
de esta manera, si tiene el mismo valor en el campo 1 en varias filas, se devolverán todos los registros.
SELECT c2.field1 ,
field2
FROM (SELECT DISTINCT
field1
FROM dbo.TABLE AS C
) AS c1
JOIN dbo.TABLE AS c2 ON c1.field1 = c2.field1
SELECT *
FROM tblname
GROUP BY duplicate_values
ORDER BY ex.VISITED_ON DESC
LIMIT 0 , 30
En ORDER BY
acabo de poner el ejemplo aquí, también puede agregar el campo ID en este
SELECT * from table where field in (SELECT distinct field from table)