traer - seleccionar valores maximos sql
Cómo seleccionar solo las primeras filas para cada valor único de una columna (4)
En SQL 2k5 +, puede hacer algo como:
;with cte as (
select CName, AddressLine,
rank() over (partition by CName order by AddressLine) as [r]
from MyTable
)
select CName, AddressLine
from cte
where [r] = 1
Digamos que tengo una tabla de direcciones de clientes:
CName | AddressLine
-------------------------------
John Smith | 123 Nowheresville
Jane Doe | 456 Evergreen Terrace
John Smith | 999 Somewhereelse
Joe Bloggs | 1 Second Ave
En la tabla, un cliente como John Smith puede tener varias direcciones. Necesito que la consulta de selección para esta tabla devuelva solo la primera fila donde haya duplicados en ''CName''. Para esta tabla, debe devolver todas las filas, excepto la tercera (o 1ra); cualquiera de esas dos direcciones está bien, pero solo se puede devolver una. ¿Hay alguna palabra clave que pueda agregar a la consulta SELECT para filtrar en función de si el servidor ya ha visto el valor de la columna antes?
Puede usar row_number()
para obtener el número de fila de la fila. Utiliza el comando over
- la cláusula partition by
especifica cuándo reiniciar la numeración y el order by
seleccionando en qué ordenar el número de fila. Incluso si agrega un order by
hasta el final de la consulta, se conservará el orden en el comando de over
al numerar.
select *
from mytable
where row_number() over(partition by Name order by AddressLine) = 1
Puede usar la row_numer() over(partition by ...)
manera:
select * from
(
select *
, ROW_NUMBER() OVER(PARTITION BY CName ORDER BY AddressLine) AS row
from myTable
) as a
where row = 1
Lo que hace es crear una columna llamada row
, que es un contador que se incrementa cada vez que ve el mismo CName
, e indexa esas ocurrencias por AddressLine
. Al imponer where row = 1
, uno puede seleccionar el CName
cuya AddressLine
viene primero en orden alfabético. Si el order by
desc
era, entonces escogería el CName
cuya AddressLine
viene en orden alfabético por última vez.
Una respuesta muy simple si dices que no te importa qué dirección se usa.
SELECT
CName, MIN(AddressLine)
FROM
MyTable
GROUP BY
CName
Si quiere la primera según, digamos, una columna "insertada", entonces es una consulta diferente
SELECT
M.CName, M.AddressLine,
FROM
(
SELECT
CName, MIN(Inserted) AS First
FROM
MyTable
GROUP BY
CName
) foo
JOIN
MyTable M ON foo.CName = M.CName AND foo.First = M.Inserted