spe*_*593 7 sql-server aggregate-functions analytic-functions sql-server-2008-r2
对于SQL Server 2008 R2
我有一个看起来像这样的结果集(注意[price]是数字,下面的NULL表示一个NULL值,结果集按product_id和timestamp排序)
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
Run Code Online (Sandbox Code Playgroud)
我想将其转换为(基本上)从最新的前一行复制非空值的结果集,以生成如下所示的结果集:
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
Run Code Online (Sandbox Code Playgroud)
我没有找到允许我这样做的聚合/窗口函数(再次这只是SQL Server 2008 R2所需要的.)
我希望找到一个分析聚合函数来为我做这个,比如......
LAST_VALUE(price) OVER (PARTITION BY product_id ORDER BY timestamp)
Run Code Online (Sandbox Code Playgroud)
但我似乎没有找到任何方法在窗口中执行"累积最新的非空值"(将窗口绑定到前面的行,而不是整个分区)
除了创建一个表值用户定义的函数之外,是否有任何内置函数可以实现此目的?
更新:
显然,此功能在"Denali"CTP中可用,但在SQL Server 2008 R2中不可用.
LAST_VALUE http://msdn.microsoft.com/en-us/library/hh231517%28v=SQL.110%29.aspx
我只是期望它可以在SQL Server 2008中使用.它可以在Oracle中使用(至少10gR2),我可以在MySQL 5.1中使用局部变量做类似的事情.
http://download.oracle.com/docs/cd/E14072_01/server.112/e10592/functions083.htm
Lam*_*mak 10
您可以尝试以下方法:
*更新**
-- 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
Run Code Online (Sandbox Code Playgroud)
小智 6
我有一个包含以下数据的表。我想用以前的值更新工资列中的所有空值而不取空值。
桌子:
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
Run Code Online (Sandbox Code Playgroud)
这是对我有用的查询。
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
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11320 次 |
| 最近记录: |