ejemplos - manual de postgresql 10 en español pdf
¿Cómo selecciono solo la última entrada en una tabla? (5)
select p.projectName, t.ThingName
from projects p
join projectThingLink l on l.projectId = p.projectId
join thing t on t.thingId = l.thingId
where l.createdDate =
( select max(l2.createdDate)
from projectThingLink l2
where l2.thingId = l.thingId
);
NOTA: corregido después del comentario
Tengo una base de datos SQLServer de 3 tablas.
Project
ProjectID
ProjectName
Thing
ThingID
ThingName
ProjectThingLink
ProjectID
ThingID
CreatedDate
Cuando se asigna una cosa a un proyecto, se ingresa una entrada en la tabla ProjectThingLink. Las cosas pueden moverse entre Proyectos. CreatedDate se usa para saber qué proyecto se ha movido por última vez.
Estoy tratando de crear una lista de todos los proyectos con los que las cosas están actualmente vinculadas, pero mi cerebro está fallando.
¿Hay una manera fácil de hacer esto?
Esto casi siempre le dará un mejor rendimiento que el método de subconsulta. Básicamente, está buscando la fila que no tiene otras filas más allá de la fila en lugar de buscar la fila con la fecha más grande:
SELECT
P.ProjectID,
P.ProjectName,
T.ThingID,
T.ThingName
FROM
dbo.Projects P
INNER JOIN dbo.ProjectThingLinks PTL1 ON
PTL1.ProjectID = P.ProjectID
LEFT OUTER JOIN dbo.ProjectThingLinks PTL2 ON
PTL2.ProjectID = ThingID = PTL1.ThingID AND
PTL2.CreatedDate > PTL1.CreatedDate
INNER JOIN dbo.Things T ON
T.ThingID = PTL1.ThingID
WHERE
PTL2.ThingID IS NULL
Una vez que decida sobre las reglas de su negocio para manejar dos filas que tienen valores CreatedDate idénticos, es posible que deba ajustar la consulta.
Además, como nota al margen, una tabla llamada "Cosas" suele ser una buena señal de un problema con el diseño de su base de datos. Las tablas deben representar distintas entidades de la vida real. Ese tipo de generalidad generalmente generará problemas en el futuro. Si se trata de recursos, probablemente compartan ciertos atributos más allá de solo un nombre. Tal vez su caso es muy especial, pero probablemente no. ;)
Prueba esto:
select p.ProjectID, p.Name, t.ThingID, t.ThingName, l.CreatedDate
from Project p
inner join (
select ProjectID, max(CreatedDate) as CreatedDate
from ProjectThingLink
group by ProjectID
) lm on p.ProjectID = l.ProjectID
inner join ProjectThingLink l on lm.ProjectID = l.ProjectID and lm.CreatedDate = l.CreatedDate
inner joing Thing t on l.ThingID = t.ThingID
Puedes simplemente hacer
SELECT Project.projectId, Project.ProjectName, ThingName
FROM Project INNER JOIN ProjectThingLink
ON Project.ProjectID = ProjectThingLink.ProjectID INNER JOIN
Thing ON ProjectThingLink.ThingID = Thing.ThingID
Will obtendrá una lista de cada proyecto con todo lo relacionado a él de esta manera:
1 | Proyecto1 | Alguna cosa
1 | Proyecto1 | Esta cosa
2 | Proyecto2 | Esa cosa
select * from project
inner join (select projectid,
max(createdate) as maxdate
from projectThingLink
group by projectid) as a
on projectid = a.projectid and createDate = a.maxDate