2012-09-28 15 views
5

Tengo una combinación de 5 tablas para obtener las tareas publicadas por cada miembro que tiene alrededor de 15 columnas. Pero para el código de muestra, he tomado solo dos tablas de ellos.Cómo obtener la última fila de la tabla usando JOIN

SELECT TOP 5 
    dbo.MemberMst.MemberID, dbo.MemberMst.fname, 
    dbo.TaskMst.TaskMstID, dbo.TaskMst.OnDate, dbo.TaskMst.Description 
FROM 
    dbo.MemberMst 
LEFT JOIN 
    dbo.TaskMst ON dbo.MemberMst.MemberID = dbo.TaskMst.MemberID 

de salida es:

MemberID fname TaskMstID OnDate     Description 
3 Ursula  NULL   NULL      NULL 
84 Opeyemi 30   2012-09-18 00:00:00.000  asd 
85 test  21   2012-09-18 10:30:46.900  aaa 
85 test  22   2012-09-18 10:31:04.967  eeee 
85 test  23   2012-09-18 10:31:26.640  vvvv 

Aquí, en consulta anterior consigo 3 filas para MemberID=85 que ha publicado 3 tareas pero necesito una sola tarea a ese miembro que es la última. Cómo obtener la última tarea publicada por un miembro por lo que ese resultado sería: -

MemberID fname TaskMstID OnDate    Description 
3 Ursula  NULL  NULL     NULL 
84 Opeyemi 30  2012-09-18 00:00:00.000 asd 
85 test  23  2012-09-18 10:31:26.640 vvvv 

quiero decir simplemente sólo un registro por cada memberID que tienen tareas?

¡Ayuda apreciada ..!

Gracias de antemano ...!

Respuesta

4

Puesto que usted está utilizando SQL Server 2008, puede tomar ventaja de Window Functions.

intentar algo como esto:

SELECT c.MemberID, c.fname, c.TaskMstID, c.OnDate, c.Description 
FROM 
    (
     SELECT a.MemberID, a.fname, 
       b.TaskMstID, b.OnDate, b.Description, 
       ROW_NUMBER() OVER (Partition BY a.MemberID ORDER BY b.OnDate DESC) RN 
     FROM MemberMst a 
       LEFT JOIN TaskMst b 
        ON a.MemberID = b.MemberID 
    ) c 
WHERE c.RN = 1 
+0

siento decir @John, pero esto no funciona ...! Error: la columna 'MemberID' se ha especificado varias veces para 'a'. –

+1

@ SHEKHAR SHETE, en ese caso, especifique los nombres de las columnas explícitamente –

+1

@SHEKHARSHETE; debe especificar explícitamente los nombres de las columnas en la subconsulta. Voy a actualizar mi respuesta. –

1

usted apenas tiene que utilizar Group BY() Noel con MAX() Función

with CTE as(
    SELECT TOP 5 
     dbo.MemberMst.MemberID, 
     dbo.MemberMst.fname, 
     dbo.TaskMst.TaskMstID, 
     dbo.TaskMst.OnDate, 
     dbo.TaskMst.Description 
    FROM 
     dbo.MemberMst left 
     JOIN dbo.TaskMst 
     ON dbo.MemberMst.MemberID = dbo.TaskMst.MemberID) 

select dbo.MemberMst.MemberID, 
     dbo.MemberMst.fname, 
     dbo.TaskMst.TaskMstID, 
     max(dbo.TaskMst.OnDate) as OnDate, 
     dbo.TaskMst.Description 
from CTE 
group by MemberID 
+0

este tipo de sintaxis no funcionará en MSSQL. –

+0

@JohnWoo: He actualizado mi respuesta ... Por favor, compruebe –

3
;With Cte1 AS 
(

SELECT top 5 dbo.MemberMst.MemberID, dbo.MemberMst.fname, dbo.TaskMst.TaskMstID, dbo.TaskMst.OnDate, dbo.TaskMst.Description 
FROM dbo.MemberMst left JOIN 
dbo.TaskMst ON dbo.MemberMst.MemberID = dbo.TaskMst.MemberID 
), 
Cte2 As 
( SELECT Rn = Row_Number() Over(Partition by MemberId Order By OnDate Desc), * 
    From Cte1 

) 
Select * 
From Cte2 
Where Rn = 1 

deberíamos hacer la tarea para usted. Pruébalo.

+0

¿qué es esto CTE1, CTE2 PLZ explicar ... esto da error en SQLSERVER2008 ... –

+0

No debería recibir error..These son expresión de tabla común es introducir desde SQL Server 2005.B/t, lo que es el error que está ¿consiguiendo? –

+0

Error: sintaxis incorrecta cerca de 'Cte2'. soy nuevo en su PLZ explicar este tipo de sintaxis? –

1

Puede particionar por MemberID, a continuación, echar un rango sobre él y seleccionar solamente el artículo que mejor clasificado.

Más información sobre MSDN

Pruebe algo como esto

WITH MyCte AS 
(SELECT top 5 dbo.MemberMst.MemberID, dbo.MemberMst.fname, dbo.TaskMst.TaskMstID, dbo.TaskMst.OnDate, dbo.TaskMst.Description, 
     ROW_NUMBER() OVER (PARTITION BY dbo.MemberMst.MemberID ORDER BY dbo.TaskMst.OnDate DESC) AS RowNum 
FROM dbo.MemberMst 
left JOIN dbo.TaskMst ON dbo.MemberMst.MemberID = dbo.TaskMst.MemberID) 
SELECT * 
FROM MyCte 
WHERE RowNum > 0 

ACTUALIZACIÓN: cambiado a ROW_NUMBER() en lugar de RANK() para evitar el problema de múltiples filas con mismo rango.

Cuestiones relacionadas