Tengo esta consulta SQL:
SELECT
us.userid,
us.username,
CONVERT(VARCHAR(10), s.created, 101) AS LastLoginDate
FROM
users us
INNER JOIN
session s ON us.userid = s.userid
WHERE
supergroupid = 145577
ORDER BY
us.userid DESC
Ahora, dado que hay varias entradas de sesión en la tabla de sesión por usuario, obtengo múltiples resultados (duplicados) por usuario.
¿Cómo puedo obtener solo la entrada más reciente creada en la tabla de sesión por usuario, solo una entrada junto con los otros datos de la tabla de usuarios?
7 respuestas
Esto ha sido preguntado y respondido cientos de veces. Pero fue más fácil codificar una solución que encontrar un duplicado. Además, realmente no debe formatear su fecha en su consulta. Eso debe hacerse en la capa de presentación.
select *
from
(
SELECT us.userId, us.userName, CONVERT(VARCHAR(10),s.created, 101) as LastLoginDate
, RowNum = ROW_NUMBER() over (partition by us.userId order by s.created desc)
FROM users us
inner join session s
on us.userId = s.userId
where superGroupId = 145577
) x
where x.RowNum = 1
order by x.userid desc
Con esta consulta:
SELECT userId, MAX(created) as LastLoginDate
FROM session
GROUP BY userId
Obtienes la última fecha de inicio de sesión para cada usuario.
Luego únala a la tabla users
:
SELECT us.userId, us.userName, CONVERT(VARCHAR(10), s.LastLoginDate, 101) as LastLoginDate
FROM users us INNER JOIN (
SELECT userId, MAX(created) as LastLoginDate
FROM session
GROUP BY userId
) s on s.userId = us.userId
WHERE superGroupId = 145577
ORDER BY us.userid desc
Puede realizar una subconsulta que devuelve la sesión más reciente para cada usuario y unirse de esa manera:
SELECT us.userId, us.userName, CONVERT(VARCHAR(10),s.created, 101) as LastLoginDate
FROM users us
INNER JOIN
(
SELECT s.userId, s.created, ROW_NUMBER OVER(PARTITION BY s.userId ORDER BY s.created DESC) AS [RowNum]
FROM session AS s
) s
on us.userId = s.userId
where superGroupId = 145577 AND s.[RowNum] = 1
order by us.userid desc
Si desea la fecha / hora de la sesión más reciente, use max()
. ¡Pero antes la conversión a una cadena!
select us.userId, us.userName, convert(varchar(10), max(s.created), 101) as LastLoginDate
from users us inner join
session s
on us.userId = s.userId
where superGroupId = 145577
group by us.userid, us.userName;
Puede rank
cada sesión y luego filtrar en la última.
Hemos detectado un problema desconocido.
SELECT * FROM (
SELECT DENSE_RANK() OVER (PARTITION BY US.USERID ORDER BY LASTLOGINDATE DESC) RNK
)
WHERE RNK = 1
Como nadie lo mencionó todavía, realmente me gusta usar una expresión de tabla común (CTE) que creo que ayuda con la legibilidad.
;WITH ctelastlogin (userid, lastlogindate)
AS (SELECT userid,
Max(created)
FROM session
GROUP BY userid)
SELECT us.userid,
us.username,
CONVERT(VARCHAR(10), cte.lastlogindate, 101) AS LastLoginDate
FROM users us
INNER JOIN ctelastlogin cte
ON cte.userid = us.userid
WHERE supergroupid = 145577
ORDER BY us.userid DESC
Creo que un Group By con un Max () en la fecha funcionaría:
SELECT us.userId, us.userName, MAX(CONVERT(VARCHAR(10),s.created, 101)) as LastLoginDate
FROM users us
inner join session s
on us.userId = s.userId
where superGroupId = 145577
group by us.userId, us.userName
order by us.userid desc
Nuevas preguntas
sql
El lenguaje de consulta estructurado (SQL) es un lenguaje para consultar bases de datos. Las preguntas deben incluir ejemplos de código, estructura de tabla, datos de muestra y una etiqueta para la implementación de DBMS (por ejemplo, MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2, etc.) que se utiliza. Si su pregunta se relaciona únicamente con un DBMS específico (usa extensiones / características específicas), use la etiqueta de ese DBMS en su lugar. Las respuestas a las preguntas etiquetadas con SQL deben usar SQL estándar ISO / IEC.