ファイズ、
次のクエリはどうですか。私が理解している限り、それはあなたが望むことをします。コメントは各ステップを説明します。オンライン ブックで CTE を参照してください。この例は、SQL 2008 の新しい MERGE コマンドを使用するように変更することもできます.
/* Test Data & Table */ DECLARE @Customers TABLE (Dates datetime, Customer integer, Value integer) INSERT INTO @Customers VALUES ('20100101', 1, 12), ('20100101', 2, NULL), ('20100101', 3, 32), ('20100101', 4, 42), ('20100101', 5, 15), ('20100102', 1, NULL), ('20100102', 2, NULL), ('20100102', 3, 39), ('20100102', 4, NULL), ('20100102', 5, 16), ('20100103', 1, 13), ('20100103', 2, 24), ('20100103', 3, NULL), ('20100103', 4, NULL), ('20100103', 5, 21), ('20100104', 1, 14), ('20100104', 2, NULL), ('20100104', 3, NULL), ('20100104', 4, 65), ('20100104', 5, 23) ; /* CustCTE - This gives us a RowNum to allow us to build the recursive CTE CleanCust */ WITH CustCTE AS (SELECT Customer, Value, Dates, ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY Dates) RowNum FROM @Customers), /* CleanCust - A recursive CTE. This runs down the list of values for each customer, checking the Value column, if it is null it gets the previous non NULL value.*/ CleanCust AS (SELECT Customer, ISNULL(Value, 0) Value, /* Ensure we start with no NULL values for each customer */ Dates, RowNum FROM CustCte cur WHERE RowNum = 1 UNION ALL SELECT Curr.Customer, ISNULL(Curr.Value, prev.Value) Value, Curr.Dates, Curr.RowNum FROM CustCte curr INNER JOIN CleanCust prev ON curr.Customer = prev.Customer AND curr.RowNum = prev.RowNum + 1) /* Update the base table using the result set from the recursive CTE */ UPDATE trg SET Value = src.Value FROM @Customers trg INNER JOIN CleanCust src ON trg.Customer = src.Customer AND trg.Dates = src.Dates /* Display the results */ SELECT * FROM @Customers
プレ>