6

2008 R2の最新の非NULL値とNULL値を置き換えます NULL値、結果セットは私は(本質的に)コピーが最新の先行する行からの非ヌル値は、結果セットを生成することが結果セットにそれを変換するのResultSetシリーズ(SQL Server 2008 R2の)SQL Serverの

product timestamp   price 
------- ---------------- ----- 
    5678 2008-01-01 12:00 12.34 
    5678 2008-01-01 12:01 NULL 
    5678 2008-01-01 12:02 NULL 
    5678 2008-01-01 12:03 23.45 
    5678 2008-01-01 12:04 NULL 

PRODUCT_IDおよびタイムスタンプ)によって順序付けされますこれは次のようになります:

product timestamp   price 
------- ---------------- ----- 
    5678 2008-01-01 12:00 12.34 
    5678 2008-01-01 12:01 12.34 
    5678 2008-01-01 12:02 12.34 
    5678 2008-01-01 12:03 23.45 
    5678 2008-01-01 12:04 23.45 

私は(再びこれが唯一のSQL Server 2008 R2のために必要。)私はこれを行うことができます任意の集約/ウィンドウ関数を見つけることができません

私はのためにこれを行う分析、集計関数を見つけることを期待していました私、何かのような...

LAST_VALUE(price) OVER (PARTITION BY product_id ORDER BY timestamp) 

しかし、私はというよりも、前の行にウィンドウをバインドする(ウィンドウ内の「累積最新のnull以外の値を」行うにはどのような方法を見つけるように見えるはありませんパーティション全体)

テーブル値のユーザー定義関数の作成とは別に、私はこれを成し遂げるだろうか?


UPDATE:

どうやら、この機能は 'デナリ' CTPではなく、SQL Server 2008 R2で提供されています。

LAST_VALUE http://msdn.microsoft.com/en-us/library/hh231517%28v=SQL.110%29.aspx

私は(以来10gR2のは、少なくとも)これは、Oracleで利用可能だ、と私はローカル変数を使用して、MySQL 5.1では似た何かを行うことができ、それはSQL Server 2008で発売される予定。

http://download.oracle.com/docs/cd/E14072_01/server.112/e10592/functions083.htm

+0

あなたは2008 R2の機能をそれはデナリに利用できるわけではなくありません? –

答えて

8

あなたは次のことを試すことができます。

;WITH SortedData AS 
(
    SELECT 
     ProductID, TimeStamp, Price, 
     ROW_NUMBER() OVER(PARTITION BY ProductID ORDER BY TimeStamp DESC) AS 'RowNum' 
    FROM dbo.YourTable 
) 
UPDATE SortedData 
SET Price = (SELECT TOP 1 Price 
      FROM SortedData sd2 
     WHERE sd2.RowNum > SortedData.RowNum 
      AND sd2.Price IS NOT NULL) 
WHERE 
    SortedData.Price IS NULL 

は基本的には、CTEは、ソートされたリストを作成します。

*これを試してみてください**

-- Test Data 
DECLARE @YourTable TABLE(Product INT, Timestamp DATETIME, Price NUMERIC(16,4)) 

INSERT INTO @YourTable 
SELECT 5678, '20080101 12:00:00', 12.34 
UNION ALL 
SELECT 5678, '20080101 12:01:00', NULL 
UNION ALL 
SELECT 5678, '20080101 12:02:00', NULL 
UNION ALL 
SELECT 5678, '20080101 12:03:00', 23.45 
UNION ALL 
SELECT 5678, '20080101 12:04:00', NULL 

;WITH CTE AS 
(
    SELECT * 
    FROM @YourTable 
) 

-- Query 
SELECT A.Product, A.Timestamp, ISNULL(A.Price,B.Price) Price 
FROM CTE A 
OUTER APPLY ( SELECT TOP 1 * 
       FROM CTE 
       WHERE Product = A.Product AND Timestamp < A.Timestamp 
       AND Price IS NOT NULL 
       ORDER BY Product, Timestamp DESC) B 

--Results 
Product Timestamp Price 
5678 2008-01-01 12:00:00.000 12.3400 
5678 2008-01-01 12:01:00.000 12.3400 
5678 2008-01-01 12:02:00.000 12.3400 
5678 2008-01-01 12:03:00.000 23.4500 
5678 2008-01-01 12:04:00.000 23.4500 
+0

そのAPPLYキーワードは私にとって初めてのものです。私はこれを撃つだろう。ありがとう! – spencer7593

+0

@ spencer7593 - どうなるか教えてください。 – Lamak

+1

@ spencer7593 - また、このリンクの 'APPLY'演算子に関するドキュメントがあります:http://technet.microsoft.com/en-us/library/ms175156.aspx – Lamak

2

を更新しましたタイムスタンプ(降順)で - 新しい最初のest。 NULLが見つかるたびに、NOT NULL価格を含む次の行が見つかり、その値を使用して行がNULL価格で更新されます。

1

私は以下のデータを含むテーブルを持っています。給与列のすべてのNULLを以前の値に更新する場合は、NULL値を使用しません。

表:ここ

id name salary 
1 A  4000 
2 B 
3 C 
4 C 
5 D  2000 
6 E 
7 E 
8 F  1000 
9 G  2000 
10 G  3000 
11 G  5000 
12 G 

は、私の作品のクエリです。

select a.*,first_value(a.salary)over(partition by a.value order by a.id) as abc from 
(
    select *,sum(case when salary is null then 0 else 1 end)over(order by id) as value from test)a 

出力:

id name salary Value abc 
1 A  4000 1  4000 
2 B    1  4000 
3 C    1  4000 
4 C    1  4000 
5 D  2000 2  2000 
6 E    2  2000 
7 E    2  2000 
8 F  1000 3  1000 
9 G  2000 4  2000 
10 G  3000 5  3000 
11 G  5000 6  5000 
12 G    6  5000 
関連する問題