使用 OVER PARTITION BY 的问题
Problems using OVER PARTITION BY
我在使用 ROW_NUMBER() OVER (PARTITION BY ...).
时遇到了一些问题
我有以下table
StartTime | EndTime | ContractStart
----------+---------+--------------
10:00 | 12:00 | 2015-03-02
11:00 | 22:00 | 2014-01-02
10:00 | 12:00 | 2015-03-02
10:00 | 12:00 | 2014-01-02
此人的工作合同始于 2014-01-02
。该合同中的某些内容发生了变化,他在 2015-03-02
获得了一份新合同。现在我想总结一下新合同的工作时间。我的代码是:
SELECT
SUM(DATEDIFF(Minute, table.StartTime, table.EndTime))
FROM
(SELECT
*,
ROW_NUMBER() OVER (PARTITION BY ContractStart
ORDER BY ContractStart DESC) AS seqnum
FROM table) table
WHERE
seqnum = 1
我实际上认为代码会将 table 分成两个分区。一个包含每份合同的数据。现在每个分区都有一个数字。由于我设置了 ORDER BY ContractStart DESC
,最新的合约位于我在查询的 Where Clause
中选择的第一个分区中。我的结果总是 0
并且我不知道代码有什么问题。谁能告诉我代码有什么问题以及为什么它没有产生我想要的结果。
另一种方法(取决于您想要的输出)。
SELECT ContractStart, SUM(DATEDIFF(Minute, StartTime, EndTime)) AS WorkingTime
FROM yourtable
GROUP BY ContractStart
输出:
ContractStart WorkingTime
January, 02 2014 00:00:00 780
March, 02 2015 00:00:00 240
SQL Fiddle: http://sqlfiddle.com/#!3/7d539/4/0
我还假设这将是更大查询(包括某种员工 ID)的一部分,可以包含在选择和分组依据中。
伪
SELECT e.id, c.ContractStart, SUM(DATEDIFF(Minute, c.StartTime, c.EndTime)) AS WorkingTime
FROM contracts c
INNER JOIN employee e ON c.employeeid = e.id
GROUP BY e.id, c.ContractStart
好吧,您确实按 ContractStart
对数据进行了分区,当然。但是行号实际上并没有告诉你任何有用的信息:
StartTime|EndTime|ContractStart|seqnum
10:00 |12:00 |2015-03-02 |1
11:00 |22:00 |2014-01-02 |1
10:00 |12:00 |2015-03-02 |2
10:00 |12:00 |2014-01-02 |2
您实际上不需要窗口函数 - 您只需要一个简单的 group by
:
select
top 1
sum(datediff(Minute, StartTime, EndTime))
from [table]
group by [ContractStart]
order by [ContractStart] desc
我在使用 ROW_NUMBER() OVER (PARTITION BY ...).
我有以下table
StartTime | EndTime | ContractStart
----------+---------+--------------
10:00 | 12:00 | 2015-03-02
11:00 | 22:00 | 2014-01-02
10:00 | 12:00 | 2015-03-02
10:00 | 12:00 | 2014-01-02
此人的工作合同始于 2014-01-02
。该合同中的某些内容发生了变化,他在 2015-03-02
获得了一份新合同。现在我想总结一下新合同的工作时间。我的代码是:
SELECT
SUM(DATEDIFF(Minute, table.StartTime, table.EndTime))
FROM
(SELECT
*,
ROW_NUMBER() OVER (PARTITION BY ContractStart
ORDER BY ContractStart DESC) AS seqnum
FROM table) table
WHERE
seqnum = 1
我实际上认为代码会将 table 分成两个分区。一个包含每份合同的数据。现在每个分区都有一个数字。由于我设置了 ORDER BY ContractStart DESC
,最新的合约位于我在查询的 Where Clause
中选择的第一个分区中。我的结果总是 0
并且我不知道代码有什么问题。谁能告诉我代码有什么问题以及为什么它没有产生我想要的结果。
另一种方法(取决于您想要的输出)。
SELECT ContractStart, SUM(DATEDIFF(Minute, StartTime, EndTime)) AS WorkingTime
FROM yourtable
GROUP BY ContractStart
输出:
ContractStart WorkingTime
January, 02 2014 00:00:00 780
March, 02 2015 00:00:00 240
SQL Fiddle: http://sqlfiddle.com/#!3/7d539/4/0
我还假设这将是更大查询(包括某种员工 ID)的一部分,可以包含在选择和分组依据中。
伪
SELECT e.id, c.ContractStart, SUM(DATEDIFF(Minute, c.StartTime, c.EndTime)) AS WorkingTime
FROM contracts c
INNER JOIN employee e ON c.employeeid = e.id
GROUP BY e.id, c.ContractStart
好吧,您确实按 ContractStart
对数据进行了分区,当然。但是行号实际上并没有告诉你任何有用的信息:
StartTime|EndTime|ContractStart|seqnum
10:00 |12:00 |2015-03-02 |1
11:00 |22:00 |2014-01-02 |1
10:00 |12:00 |2015-03-02 |2
10:00 |12:00 |2014-01-02 |2
您实际上不需要窗口函数 - 您只需要一个简单的 group by
:
select
top 1
sum(datediff(Minute, StartTime, EndTime))
from [table]
group by [ContractStart]
order by [ContractStart] desc