2011-02-06 10 views
0
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

これまでに書いたコードを投稿してください。人々は一般的にあなたのためのコードを書くのが好きではありません。それはそのままで、これは仕事の説明であり、質問ではありません。 –

+0

私は現在のコードで私の質問を編集しました – startEnd

+0

あなたは(有益な情報が提供されている)多くをアップヴォートすることができますし、それを受け入れるための答えに尋ねることができます(質問者の正しさの承認) – RichardTheKiwi

答えて

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 
+0

ありがとうございました。あなたの助けに感謝 – startEnd

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を割り当てます。rownumは、以前の価格データを現在の価格データと結合するために使用されるため、異なる方法が選択されています。