我在表格中有一些类似于此的数据:
Item Date Price A 8/29/2012 $3 B 8/29/2012 $23 C 8/29/2012 $10 A 8/30/2012 $4 B 8/30/2012 $25 C 8/30/2012 $11 A 8/31/2012 $3 B 8/31/2012 $22 C 8/31/2012 $8 A 9/01/2012 $3 B 9/01/2012 $26 C 9/01/2012 $9 A 9/02/2012 $3 B 9/02/2012 $24 C 9/02/2012 $9
我需要编写一个查询,确定A的价格没有变化 自2012年8月30日起,自C 9/2012以来,C项的价格没有变化 返回两者的经过天数(我们正在寻找物品 不动的价格)。我不能使用CTE,或游标,或单独创建 由于Web报告的限制,临时表(select into等) 这个sql需要运行的工具。我只能使用'基本'单通道选择查询 (子查询会起作用)。有没有人对如何有任何狡猾的想法 实现这个??
我的第一次尝试是按物品和价格分组,其中价格与价格相同
最新价格having count > 2
,确定最短约会和做日期
在min date和getdate之间。然而,这仅仅标识了第一个实例
这个价格,它没有考虑任何可能有的后续行
不同的价格。希望这是有道理的。
答案 0 :(得分:2)
*已更新with fiddle:*
这会有用吗?
SELECT ct.Item,
ct.Price,
datediff(day, max(yt.[Date]), ct.[Date]) AS ChangeDays
FROM
(SELECT Item, max(Date) as LastDate FROM YourTable GROUP BY Item) maxdata
INNER JOIN YourTable ct on ct.Item = maxdata.Item and ct.[Date] = maxdata.LastDate
INNER JOIN YourTable yt on yt.Item = ct.Item and yt.[Date] < ct.[Date] and yt.Price <> ct.Price
GROUP BY ct.Item, ct.Price, ct.[Date]
答案 1 :(得分:2)
我已经给出了两种类型的年龄,并说明了表中只存在一次的项目(它们没有旧日期)。请告诉我们这有多接近。
更新:我必须更正“PriceAgeToNow”中的日期计算,并且我还尝试过滤掉仅有1天新价格的记录。这是SQL Fiddle。
-- Get the age of the current price
select *
, datediff(d, c.OldDate, getdate()) as PriceAgeToNow
, datediff(d, c.OldDate, c.NewDate) as PriceAgeToNewestDate
from (
select *
-- Get max date of former price
, isnull(
(select max(Date) from PricingTable where Item = b.Item and Date < b.NewDate and Price != b.NewPrice), b.NewDate
) as OldDate
from (
-- Get current price
select *
, (select Price from PricingTable where Item = a.Item and Date = a.NewDate) as NewPrice
from (
-- Get current date
select Item
, max(Date) as NewDate
from PricingTable
group by Item
) a
) b
) c
-- Attempt to filter out price changes that have only lasted 1 day
where datediff(d, c.OldDate, c.NewDate) > 1
答案 2 :(得分:2)
我倾向于使用最适合的Windows功能。并且,在这种情况下,有一个有趣的技巧来查找相同的事物序列。在所有数据上枚举它们(带有row_number),按项目分区并按日期排序。然后在所有数据上枚举它们,按项目和价格进行分区,并按日期排序。
对于A,你会得到
A 8/29 $3 1 1
A 8/30 $4 2 1
A 8/31 $3 3 2
A 9/1 $3 4 3
A 9/3 $3 5 4
对于在数据中保持不变的任何价格序列,最后两列之间的差异是不变的。然后我们可以使用它来查找该序列何时开始。以下查询采用此方法:
select item, price, (id_seqnum - ipd_seqnum) as groupid, min(date) as mindate
from (select p.*,
row_number() over (partition by item order by date) id_seqnum,
row_number() over (partition by item, price order by date) as ipd_seqnum,
max(date) over (partition by item) as maxdate
from prices p
) t
group by item, price, (id_seqnum - ipd_seqnum)
having max(date) = max(maxdate)
它还会找到每个项目的最大日期,然后选择具有最大日期的分组。