我需要计算一个日期范围内的滚动总和。为了说明,使用AdventureWorks 示例数据库,以下假设语法将完全满足我的需要:
SELECT
TH.ProductID,
TH.TransactionDate,
TH.ActualCost,
RollingSum45 = SUM(TH.ActualCost) OVER (
PARTITION BY TH.ProductID
ORDER BY TH.TransactionDate
RANGE BETWEEN
INTERVAL 45 DAY PRECEDING
AND CURRENT ROW)
FROM Production.TransactionHistory AS TH
ORDER BY
TH.ProductID,
TH.TransactionDate,
TH.ReferenceOrderID;
Run Code Online (Sandbox Code Playgroud)
遗憾的是,RANGE窗口框架范围目前在 SQL Server 中不允许间隔。
我知道我可以使用子查询和常规(非窗口)聚合编写解决方案:
SELECT
TH.ProductID,
TH.TransactionDate,
TH.ActualCost,
RollingSum45 =
(
SELECT SUM(TH2.ActualCost)
FROM Production.TransactionHistory AS TH2
WHERE
TH2.ProductID = TH.ProductID
AND TH2.TransactionDate <= TH.TransactionDate
AND TH2.TransactionDate >= DATEADD(DAY, -45, TH.TransactionDate)
)
FROM Production.TransactionHistory AS TH
ORDER BY
TH.ProductID,
TH.TransactionDate, …Run Code Online (Sandbox Code Playgroud) performance sql-server t-sql sql-server-2012 window-functions query-performance
好像MySQL不支持窗口函数。
例如简单的:COUNT(*) OVER() AS cnt不起作用。
我不确定这是否也适用于商业版本(我认为社区版本是有限的子集)。
如果没有,如何解决这一缺失的功能?
在SQL Server 2008中,我使用RANK() OVER (PARTITION BY Col2 ORDER BY Col3 DESC)与返回的数据集RANK。但是我每个分区有数百条记录,所以我将从等级 1、2、3......999 中获取值。但我只想RANKs在每个PARTITION.
例子:
ID Name Score Subject
1 Joe 100 Math
2 Jim 99 Math
3 Tim 98 Math
4 Joe 99 History
5 Jim 100 History
6 Tim 89 History
7 Joe 80 Geography
8 Tim 100 Geography
9 Jim 99 Geography
Run Code Online (Sandbox Code Playgroud)
我希望结果是:
SELECT Subject, Name, RANK() OVER (PARTITION BY Subject ORDER BY Score DESC)
FROM Table
Run Code Online (Sandbox Code Playgroud)
Subject Name Rank …Run Code Online (Sandbox Code Playgroud) 我有一些这样的数字表(状态是免费的或分配的)
id_set 号码状态 ----------------------- 1 000001 已分配 1 000002 免费 1 000003 已分配 1 000004 免费 1 000005 免费 1 000006 已分配 1 000007 已分配 1 000008 免费 1 000009 免费 1 000010 免费 1 000011 已分配 1 000012 已分配 1 000013 已分配 1 000014 免费 1 000015 已分配
我需要找到“n”个连续数字,因此对于 n = 3,查询将返回
1 000008 免费 1 000009 免费 1 000010 免费
它应该只返回每个 id_set 的第一个可能的组(实际上,它只会为每个查询的 id_set 执行)
我正在检查 WINDOW 函数,尝试了一些类似的查询COUNT(id_number) OVER (PARTITION BY id_set ROWS UNBOUNDED PRECEDING),但这就是我得到的:) 我想不出逻辑,如何在 …
我正在尝试将查询从 Oracle 迁移到 SQL Server 2014。
这是我在 Oracle 中运行良好的查询:
select
count(distinct A) over (partition by B) / count(*) over() as A_B
from MyTable
Run Code Online (Sandbox Code Playgroud)
这是我尝试在 SQL Server 2014 中运行此查询后遇到的错误。
Use of DISTINCT is not allowed with the OVER clause
Run Code Online (Sandbox Code Playgroud)
有谁知道是什么问题?在 SQL Server 中可以进行这种查询吗?请指教。
我需要一些窗口函数方面的帮助。我知道你可以计算一个窗口内的总和和一个窗口内的运行总数。但是是否可以计算先前的运行总计,即不包括当前行的运行总计?
我假设您需要使用ROWorRANGE参数。我知道有一个CURRENT ROW选项,但我需要CURRENT ROW - 1,这是无效的语法。我对这些ROW和RANGE论点的了解有限,因此将不胜感激地收到任何帮助。
我知道这个问题有很多解决方案,但我希望了解ROW,RANGE参数,并且我认为可以用这些来解决问题。我已经包含了一种可能的方法来计算以前的运行总数,但我想知道是否有更好的方法:
USE AdventureWorks2012
SELECT s.SalesOrderID
, s.SalesOrderDetailID
, s.OrderQty
, SUM(s.OrderQty) OVER (PARTITION BY SalesOrderID) AS RunningTotal
, SUM(s.OrderQty) OVER (PARTITION BY SalesOrderID
ORDER BY SalesOrderDetailID) - s.OrderQty AS PreviousRunningTotal
-- Sudo code - I know this does not work
--, SUM(s.OrderQty) OVER (PARTITION BY SalesOrderID
-- ORDER BY SalesOrderDetailID
-- ROWS BETWEEN UNBOUNDED PRECEDING
-- AND CURRENT …Run Code Online (Sandbox Code Playgroud) 考虑一个记录访问的表
create table visits (
person varchar(10),
ts timestamp,
somevalue varchar(10)
)
Run Code Online (Sandbox Code Playgroud)
考虑这个示例数据(时间戳简化为计数器)
ts| person | somevalue
-------------------------
1 | bob |null
2 | bob |null
3 | jim |null
4 | bob | A
5 | bob | null
6 | bob | B
7 | jim | X
8 | jim | Y
9 | jim | null
Run Code Online (Sandbox Code Playgroud)
我试图将这个人的最后一个非空值传递到他未来的所有访问中,直到该值发生变化(即成为下一个非空值)。
预期结果集如下所示:
ts| person | somevalue | carry-forward
-----------------------------------------------
1 | bob |null | null
2 | bob |null | …Run Code Online (Sandbox Code Playgroud) 我有20M行的表,每一行有3列:time,id,和value。对于每个id和time,value状态都有一个。我想知道time特定id.
我使用了两种方法来实现这一点。一种方法是使用加入和另一种方法是使用功能导致的窗口/滞后与聚簇索引time和id。
我通过执行时间比较了这两种方法的性能。join方法需要16.3秒,窗口函数方法需要20秒,不包括创建索引的时间。这让我感到惊讶,因为窗口函数似乎是先进的,而连接方法是蛮力的。
下面是这两种方法的代码:
创建索引
create clustered index id_time
on tab1 (id,time)
Run Code Online (Sandbox Code Playgroud)
select a1.id,a1.time
a1.value as value,
b1.value as value_lag,
c1.value as value_lead
into tab2
from tab1 a1
left join tab1 b1
on a1.id = b1.id
and a1.time-1= b1.time
left join tab1 c1
on a1.id = c1.id
and a1.time+1 = c1.time
Run Code Online (Sandbox Code Playgroud)
使用SET STATISTICS TIME, IO ON以下方法生成的 IO …
performance join sql-server window-functions sql-server-2016 query-performance
我有以下输入:
id | value
----+-------
1 | 136
2 | NULL
3 | 650
4 | NULL
5 | NULL
6 | NULL
7 | 954
8 | NULL
9 | 104
10 | NULL
Run Code Online (Sandbox Code Playgroud)
我希望得到以下结果:
id | value
----+-------
1 | 136
2 | 136
3 | 650
4 | 650
5 | 650
6 | 650
7 | 954
8 | 954
9 | 104
10 | 104
Run Code Online (Sandbox Code Playgroud)
简单的解决方案是用<关系连接表,然后选择 a 中的MAX值GROUP BY: …
我有一个我认为可以使用窗口函数解决的情况,但我不确定。
想象一下下表
CREATE TABLE tmp
( date timestamp,
id_type integer
) ;
INSERT INTO tmp
( date, id_type )
VALUES
( '2017-01-10 07:19:21.0', 3 ),
( '2017-01-10 07:19:22.0', 3 ),
( '2017-01-10 07:19:23.1', 3 ),
( '2017-01-10 07:19:24.1', 3 ),
( '2017-01-10 07:19:25.0', 3 ),
( '2017-01-10 07:19:26.0', 5 ),
( '2017-01-10 07:19:27.1', 3 ),
( '2017-01-10 07:19:28.0', 5 ),
( '2017-01-10 07:19:29.0', 5 ),
( '2017-01-10 07:19:30.1', 3 ),
( '2017-01-10 07:19:31.0', 5 ),
( '2017-01-10 07:19:32.0', 3 ), …Run Code Online (Sandbox Code Playgroud) postgresql window-functions group-by gaps-and-islands postgresql-8.4
window-functions ×10
sql-server ×6
postgresql ×3
t-sql ×3
group-by ×2
performance ×2
join ×1
mysql ×1
null ×1
rank ×1