如何从两行中获取计算
How to get calculations from two rows
我最近开始学习SQL,想知道是否可以进行如下计算。
我的 table 基本上是这样的:
id Date Fill_nbr
1 01/01/2015 30
1 02/05/2015 30
1 03/02/2015 30
1 07/01/2015 30
1 07/26/2015 30
2 03/01/2015 30
....
我想创建一个 table 这样的:
id Date Fill_nbr Date_last Gap First
1 01/01/2015 30 01/30/2015 0 1
1 02/05/2015 30 03/04/2015 5 0
1 03/02/2015 30 03/31/2015 0 0
1 07/01/2015 30 07/30/2015 91 1
1 07/26/2015 30 08/24/2015 0 0
2 03/01/2015 30 03/30/2015 0 1
....
第 'Date_last' 列的规则是 Date_last = 日期 + fill_nbr,这很容易得到。
对我来说困难的部分是 'Gap' 部分。规则是:
- Gap='Date' - “Date_last”的最后一条记录。
例如,第二行的间隙计算为 Gap=02/05/2015-
2015 年 1 月 30 日;
- 每个人的第一条记录差距=0 或计算出的差距<0;
第 'First' 列的规则:
- First=1 表示每个人的第一条记录,或者当差距>60 时。
- 否则,第一个=0;
看起来这个问题已经被放弃了,因为重要的细节仍然缺失...认为至少找到一个解决方案会很有趣。以下解决方案适用于 SQL Server 2012 或更高版本,因为它使用 LAG
.
SELECT
id,
[Date],
Fill_nbr,
(CASE WHEN LAG (DATEADD(DD, Fill_nbr - 1, [Date]), 1, NULL) OVER (
PARTITION BY id ORDER BY [Date]) > [Date] THEN 0 ELSE
COALESCE(DATEDIFF(DD, LAG (DATEADD(DD, Fill_nbr - 1, [Date]), 1, NULL) OVER (
PARTITION BY id ORDER BY [Date]), [Date]) - 1, 0) END) AS Gap,
DATEADD(DD, Fill_nbr - 1, [Date]) AS Date_last,
CASE WHEN DATEPART(DD, [Date]) = 1 THEN 1 ELSE 0 END AS [First]
FROM Records
SQL Fiddle: http://sqlfiddle.com/#!6/a9b68/8
谢谢杰森!我发现 LAG 或 LEAD 函数可以解决这个问题。所以这是我的解决方案,与您的类似。再次感谢您的意见!
select
id,
date,
fill_nbr,
date + fill_nbr - 1 AS date_last,
LAG(date_last) OVER (PARTITION BY id OREDER by id, date) LagV,
date - LagV - 1 as gap,
ROW_NUMBER() OVER(PARTITION BY id IRDER BY id, date) AS rk,
CASE
WHEN (gap>30 or rk=1) then '1'
ELSE '0'
END AS first
FROM table;
我最近开始学习SQL,想知道是否可以进行如下计算。
我的 table 基本上是这样的:
id Date Fill_nbr
1 01/01/2015 30
1 02/05/2015 30
1 03/02/2015 30
1 07/01/2015 30
1 07/26/2015 30
2 03/01/2015 30
....
我想创建一个 table 这样的:
id Date Fill_nbr Date_last Gap First
1 01/01/2015 30 01/30/2015 0 1
1 02/05/2015 30 03/04/2015 5 0
1 03/02/2015 30 03/31/2015 0 0
1 07/01/2015 30 07/30/2015 91 1
1 07/26/2015 30 08/24/2015 0 0
2 03/01/2015 30 03/30/2015 0 1
....
第 'Date_last' 列的规则是 Date_last = 日期 + fill_nbr,这很容易得到。
对我来说困难的部分是 'Gap' 部分。规则是:
- Gap='Date' - “Date_last”的最后一条记录。 例如,第二行的间隙计算为 Gap=02/05/2015- 2015 年 1 月 30 日;
- 每个人的第一条记录差距=0 或计算出的差距<0;
第 'First' 列的规则:
- First=1 表示每个人的第一条记录,或者当差距>60 时。
- 否则,第一个=0;
看起来这个问题已经被放弃了,因为重要的细节仍然缺失...认为至少找到一个解决方案会很有趣。以下解决方案适用于 SQL Server 2012 或更高版本,因为它使用 LAG
.
SELECT
id,
[Date],
Fill_nbr,
(CASE WHEN LAG (DATEADD(DD, Fill_nbr - 1, [Date]), 1, NULL) OVER (
PARTITION BY id ORDER BY [Date]) > [Date] THEN 0 ELSE
COALESCE(DATEDIFF(DD, LAG (DATEADD(DD, Fill_nbr - 1, [Date]), 1, NULL) OVER (
PARTITION BY id ORDER BY [Date]), [Date]) - 1, 0) END) AS Gap,
DATEADD(DD, Fill_nbr - 1, [Date]) AS Date_last,
CASE WHEN DATEPART(DD, [Date]) = 1 THEN 1 ELSE 0 END AS [First]
FROM Records
SQL Fiddle: http://sqlfiddle.com/#!6/a9b68/8
谢谢杰森!我发现 LAG 或 LEAD 函数可以解决这个问题。所以这是我的解决方案,与您的类似。再次感谢您的意见!
select
id,
date,
fill_nbr,
date + fill_nbr - 1 AS date_last,
LAG(date_last) OVER (PARTITION BY id OREDER by id, date) LagV,
date - LagV - 1 as gap,
ROW_NUMBER() OVER(PARTITION BY id IRDER BY id, date) AS rk,
CASE
WHEN (gap>30 or rk=1) then '1'
ELSE '0'
END AS first
FROM table;