Declare @sec_temp table
(
sec_no varchar(10),
amount money,
price_date date
)
insert @sec_temp
values
('123ABC', 25, '2011-01-20'),
('123ABC', 25, '2011-01-19'),
('123ABC', 25, '2011-01-18'),
('123ABC', 20, '2011-01-17'),
('123ABC', 20, '2011-01-15'),
('123ABC', 22, '2011-01-13'),
('456DEF', 22, '2011-01-13'),
('456DEF', 30, '2011-01-11')
问题:T-SQL查询获取项目的先前价格,与当前价格的差异和先前价格的日期。 “先前价格”定义为项目金额在当前金额之前发生变化的日期
结果:
**sec_no current_Amount Current_Price_Date No_of_days_at_Current_price prior_amount prior_price_date No_of_days_at_prior_price**
123ABC 20 2011-01-20 19 20 2011-01-15 3
456DEF 22 2011-01-13 24 30 2011-01-11 2
当前代码(获取current_price_date和current_amount的数据):
(感谢cyberkiwi)
select
sec_no,
amount,
No_of_days_at_price = 1 + DATEDIFF(d, min(price_date), max(price_date))
from (
select *,
ROW_NUMBER() over (partition by sec_no order by price_date desc) rn,
ROW_NUMBER() over (partition by sec_no, amount order by price_date desc) rn2
from @sec_temp
) X
WHERE rn=rn2
group by sec_no, amount
答案 0 :(得分:3)
select
X.sec_no,
Current_Amount = X.amount,
Current_Price_Date = X.price_date,
No_of_days_at_current_price = DATEDIFF(d, X.price_date, getdate()),
prior_amount = Y.amount,
prior_price_date = Y.price_date,
No_of_days_at_prior_price = DATEDIFF(d, Y.price_date, X.price_date)
from (
select *,
ROW_NUMBER() over (partition by sec_no order by price_date desc) rn
from @sec_temp
) X
outer apply (
select top(1) b.* from @sec_temp b
where b.price_date < X.price_date and b.amount != X.amount
and b.sec_no = X.sec_no
order by b.price_date desc
) Y
WHERE rn=1
答案 1 :(得分:0)
另一种解决方案:
WITH grouped AS (
SELECT
*,
price_duration = max_price_date - min_price_date + 1,
rownum = ROW_NUMBER() OVER (PARTITION BY sec_no ORDER BY max_price_date DESC)
FROM (
SELECT
sec_no,
amount,
min_price_date = MIN(price_date),
max_price_date = MAX(price_date)
FROM @sec_temp
GROUP BY sec_no, amount
) s
)
SELECT
g1.sec_no,
current_Amount = g1.amount,
Current_Price_Date = g1.max_price_date,
No_of_days_at_Current_price = g1.price_duration,
prior_amount = g2.amount,
prior_price_date = g2.min_date_time,
No_of_days_at_prior_price = g2.price_duration
FROM grouped AS g1
LEFT JOIN grouped AS g2 ON g1.sec_no = g2.sec_no AND g2.rownum = 2
WHERE g1.rownum = 1
ORDER BY g1.sec_no
如您所见,number of days
的计算方式与当前脚本的完成方式略有不同。基本上它是相似的,它只是在分组后分配rownums ,而不是在查询之前。选择了不同的方式,因为rownums还用于将先前的价格数据与当前价格数据相结合。