T-SQL Subquery Max (Fecha) y Joins
Estoy tratando de unir varias tablas, pero una de las tablas tiene varios registros para un partido con fechas diferentes. Quiero obtener el registro con la fecha más reciente.
Aquí hay algunas tablas de ejemplo:
Table: MyParts
Partid Partnumber Description
1 ABC-123 Pipe
2 ABC-124 Handle
3 ABC-125 Light
Table: MyPrices
Partid Price PriceDate
1 $1 1/1/2005
1 $2 1/1/2007
1 $3 1/1/2009
2 $2 1/1/2005
2 $4 1/1/2006
2 $5 1/1/2008
3 $10 1/1/2008
3 $12 1/1/2009
Si solo quisiera encontrar el precio más reciente para una parte determinada, podría hacer:
SELECT * FROM MyPrice WHERE PriceDate = (SELECT MAX(PriceDate)
FROM MyPrice WHERE Partid = 1)
Sin embargo, quiero hacer una unión primero y obtener el precio correcto para todas las partes, no solo una. Esto es lo que he intentado:
SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE
MyPart.PriceDate = (SELECT MAX(PriceDate) FROM MyPrice)
Los resultados son erróneos como toma la fecha de precio más alto de toda la tabla.
SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE
MyPart.PriceDate = (SELECT MAX(PriceDate) FROM MyPrice WHERE MyPrice.Partid =
MyParts.Partid)
Que se equivoca.
Qué puedo hacer para obtener los resultados que quiero.
10 answers
Prueba esto:
Select *,
Price = (Select top 1 Price
From MyPrices
where PartID = mp.PartID
order by PriceDate desc
)
from MyParts mp
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-18 19:29:31
Aquí hay otra manera de hacerlo sin subconsultas. Este método a menudo superará a otros, por lo que vale la pena probar ambos métodos para ver cuál da el mejor rendimiento.
SELECT
PRT.PartID,
PRT.PartNumber,
PRT.Description,
PRC1.Price,
PRC1.PriceDate
FROM
MyParts PRT
LEFT OUTER JOIN MyPrices PRC1 ON
PRC1.PartID = PRT.PartID
LEFT OUTER JOIN MyPrices PRC2 ON
PRC2.PartID = PRC1.PartID AND
PRC2.PriceDate > PRC1.PriceDate
WHERE
PRC2.PartID IS NULL
Esto dará múltiples resultados si tiene dos precios con el mismo precio EXACTO (la mayoría de las otras soluciones harán lo mismo). Además, no hay nada que explique la fecha del último precio en el futuro. Es posible que desee considerar una verificación para eso, independientemente del método que termine utilizando.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-18 21:00:20
Intente unirse a la subconsulta a de MyPrice
para recuperar MAX(PriceDate)
:
SELECT a.*, MyPriceDate.Price, MyPriceDate.PriceDate
FROM MyParts a
INNER JOIN (
SELECT Partid, MAX(PriceDate) AS MaxPriceDate
FROM MyPrice
GROUP BY Partid
) dt ON a.Partid = dt.Partid
INNER JOIN MyPrice ON dt.Partid = MyPrice.Partid
AND a.PriceDate = dt.MaxPriceDate
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-27 17:42:39
En 2005 use ROW_NUMBER()
:
SELECT * FROM
( SELECT p.*,
ROW_NUMBER() OVER(PARTITION BY Partid ORDER BY PriceDate DESC) AS rn
FROM MyPrice AS p ) AS t
WHERE rn=1
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-29 08:28:48
Algo como esto
SELECT *
FROM MyParts
LEFT JOIN
(
SELECT MAX(PriceDate), PartID FROM MyPrice group by PartID
) myprice
ON MyParts.Partid = MyPrice.Partid
Si conoce su partido o puede restringirlo, póngalo dentro de la combinación.
SELECT myprice.partid, myprice.partdate, myprice2.Price, *
FROM MyParts
LEFT JOIN
(
SELECT MAX(PriceDate), PartID FROM MyPrice group by PartID
) myprice
ON MyParts.Partid = MyPrice.Partid
Inner Join MyPrice myprice2
on myprice2.pricedate = myprice.pricedate
and myprice2.partid = myprice.partid
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-18 18:55:06
SELECT
*
FROM
(SELECT MAX(PriceDate) AS MaxP, Partid FROM MyPrices GROUP BY Partid) MaxP
JOIN
MyPrices MP On MaxP.Partid = MP.Partid AND MaxP.MaxP = MP.PriceDate
JOIN
MyParts P ON MP.Partid = P.Partid
Primero debe obtener la última fecha de precios para el partido (un agregado estándar), luego volver a unírsela para obtener los precios (que no pueden estar en el agregado), seguido de obtener los detalles de la parte.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-18 18:38:08
Únase a la tabla de precios y luego seleccione la entrada para el último día:
select pa.partid, pa.Partnumber, max(pr.price)
from myparts pa
inner join myprices pr on pr.partid = pa.partid
where pr.PriceDate = (
select max(PriceDate)
from myprices
where partid = pa.partid
)
El max() es en caso de que haya varios precios por día; estoy asumiendo que te gustaría mostrar el más alto. Si tu tabla de precios tiene una columna id, puedes evitar max() y simplificar como:
select pa.partid, pa.Partnumber, pr.price
from myparts pa
inner join myprices pr on pr.partid = pa.partid
where pr.priceid = (
select max(priceid)
from myprices
where partid = pa.partid
)
P.d. Utilice la solución de wcm en su lugar!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-18 18:49:52
Todas las demás respuestas deben funcionar, pero usando la misma sintaxis (y entendiendo por qué el error)
SELECT * FROM MyParts LEFT JOIN MyPrice ON MyParts.Partid = MyPrice.Partid WHERE
MyPart.PriceDate = (SELECT MAX(MyPrice2.PriceDate) FROM MyPrice as MyPrice2
WHERE MyPrice2.Partid = MyParts.Partid)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-18 18:45:11
Por favor, intente el siguiente ejemplo de código:
select t1.*, t2.partprice, t2.partdate
from myparts t1
join myprices t2
on t1.partid = t2.partid
where partdate =
(select max(partdate) from myprices t3
where t3.partid = t2.partid group by partid)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-08 08:08:24
Para MySQL, por favor encuentre la siguiente consulta:
select * from (select PartID, max(Pricedate) max_pricedate from MyPrices group bu partid) as a
inner join MyParts b on
(a.partid = b.partid and a.max_pricedate = b.pricedate)
Dentro de la subconsulta obtiene max pricedate para cada partyid de MyPrices entonces, unión interna con MyParts usando partid y el max_pricedate
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-25 00:36:29