acertijo SQL, cómo seleccionar fecha límite para la parte, pero sólo 1 fila por cada parte (única)
-
01-10-2019 - |
Pregunta
Estoy tratando de envolver mi cabeza en torno a éste esta mañana.
Estoy tratando de mostrar el estado inventory
de piezas (de nuestros productos) y de esta consulta sólo se vuelve compleja si trato de devolver todas partes.
Déjame ponerlo hacia fuera:
-
inventoryReport
sola tabla - Tengo una lista distinta de las partes X Deseo pantalla, el resultado de los cuales debe ser X # de filas (1 fila por parte mostrando última inscripción en el inventario).
- Mesa se compone de entradas fechadas de cambios en el inventario (por lo que sólo necesita la entrada de fecha
LATEST
por cada parte). - todos los datos contenidos en esta tabla única, por lo que no se une necesario.
En la actualidad para 1 sola parte, es bastante simple y que puede lograr esto haciendo lo siguiente SQL (para darle una idea):
SELECT TOP (1) ldDate, ptProdLine, inPart, inSite, inAbc, ptUm, inQtyOh + inQtyNonet AS in_qty_oh, inQtyAvail, inQtyNonet, ldCustConsignQty, inSuppConsignQty
FROM inventoryReport
WHERE (ldPart = 'ABC123')
ORDER BY ldDate DESC
que me pone mi fila superior 1, de manera sencilla por parte, sin embargo necesito para mostrar todos X (digamos 30 partes). Así que necesito 30 filas, con ese resultado. Por supuesto, la solución sencilla sería la de bucle x # de llamadas SQL en mi código (pero sería costoso) y que sería suficiente, pero para este propósito me encantaría trabajar este SQL un poco más para reducir el X # devuelve la llamada a la db (si no es necesario) hasta sólo 1 consulta.
Por lo que puedo ver aquí Necesito hacer un seguimiento de la última fecha por artículo de alguna manera en la búsqueda de mi conjunto de resultados.
Me gustaría hacer una última instancia
WHERE ldPart in ('ABC123', 'BFD21', 'AA123', etc)
para limitar las piezas que necesito. Con suerte hice mi pregunta bastante clara. Déjeme saber si usted tiene una idea. No puedo hacer un DISTINCT
que las filas no son los mismos, las necesidades de fecha a ser la última, y ??necesito un máximo de X filas.
Los pensamientos? Estoy atascado ...
Solución
Editar : Asegúrese de probar el rendimiento de cada solución. Como se ha señalado en esta pregunta , el método CTE puede superar usando ROW_NUMBER.
;with cteMaxDate as (
select ldPart, max(ldDate) as MaxDate
from inventoryReport
group by ldPart
)
SELECT md.MaxDate, ir.ptProdLine, ir.inPart, ir.inSite, ir.inAbc, ir.ptUm, ir.inQtyOh + ir.inQtyNonet AS in_qty_oh, ir.inQtyAvail, ir.inQtyNonet, ir.ldCustConsignQty, ir.inSuppConsignQty
FROM cteMaxDate md
INNER JOIN inventoryReport ir
on md.ldPart = ir.ldPart
and md.MaxDate = ir.ldDate
Otros consejos
SELECT *
FROM (SELECT i.*,
ROW_NUMBER() OVER(PARTITION BY ldPart ORDER BY ldDate DESC) r
FROM inventoryReport i
WHERE ldPart in ('ABC123', 'BFD21', 'AA123', etc)
)
WHERE r = 1
Es necesario unirse en una sub-consulta:
SELECT i.ldPart, x.LastDate, i.inAbc
FROM inventoryReport i
INNER JOIN (Select ldPart, Max(ldDate) As LastDate FROM inventoryReport GROUP BY ldPart) x
on i.ldPart = x.ldPart and i.ldDate = x.LastDate