Fai*_*aiz 10 sql t-sql sql-server-2008
我需要在不使用循环和相关子查询的情况下使用SQL生成下表中的"required"列.这在SQL 2008中是否可行?
Date Customer Value Required Rule
20100101 1 12 12
20100101 2 0 If no value assign 0
20100101 3 32 32
20100101 4 42 42
20100101 5 15 15
20100102 1 12 Take last known value
20100102 2 0 Take last known value
20100102 3 39 39
20100102 4 42 Take last known value
20100102 5 16 16
20100103 1 13 13
20100103 2 24 24
20100103 3 39 Take last known value
20100103 4 42 Take last known value
20100103 5 21 21
20100104 1 14 14
20100104 2 24 Take last known value
20100104 3 39 Take last known value
20100104 4 65 65
20100104 5 23 23
Run Code Online (Sandbox Code Playgroud)
基本上我正在为该客户填充具有最后知道价值的空"值"单元格.请记住,最后一行可能没有有效值,因此您必须使用有效值从之前的行中选择它.
这是“最后一个非空谜题”,这是几个优雅的解决方案之一:
如果您的“稀疏”表SparseTable包含日期、客户、价值列,则:
with C as
(select *,
max(case when Value is not null then [Date] end)
over (partition by Customer order by [Date] rows unbounded preceding) as grp
from SparseTable
)
insert into FullTable
select *,
max(Value) over (partition by Customer, grp order by [Date] rows unbounded preceding) as Required
from C
Run Code Online (Sandbox Code Playgroud)
凡Value不能充满着它仍然是NULL,这样你就可以再
update FullTable set Required = 0 where Required is null
Run Code Online (Sandbox Code Playgroud)
法伊兹,
如果下面的查询怎么样,它根据我的理解做你想做的事情.评论解释了每一步.看看联机丛书上的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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
35243 次 |
| 最近记录: |