计算一个值在分区上发生变化的总计 运行
Calculating a running total of when a value changes over a partition
我无法弄清楚如何编写 window 函数来解决我的问题。我是 window 函数的新手,但我认为可以编写一个来满足我的需要。
问题陈述:
我想计算一个传输序列,显示人员何时根据相应的位置 ID 随着时间的推移更改位置。
示例数据(表 1)
+----------+------------+-----------+---------+
| PersonID | LocationID | Date | Time |
+----------+------------+-----------+---------+
| 12 | A | 6/17/2020 | 12:00PM |
+----------+------------+-----------+---------+
| 12 | A | 6/18/2020 | 1:00PM |
+----------+------------+-----------+---------+
| 12 | B | 6/18/2020 | 6:00AM |
+----------+------------+-----------+---------+
| 12 | C | 6/19/2020 | 3:00PM |
+----------+------------+-----------+---------+
| 13 | A | 6/16/2020 | 8:00AM |
+----------+------------+-----------+---------+
| 13 | A | 6/16/2020 | 11:00AM |
+----------+------------+-----------+---------+
| 13 | A | 6/16/2020 | 12:00AM |
+----------+------------+-----------+---------+
| 13 | B | 6/16/2020 | 4:00PM |
+----------+------------+-----------+---------+
预期结果
+----------+------------+-----------+---------+-------------------+
| PersonID | LocationID | Date | Time | Transfer Sequence |
+----------+------------+-----------+---------+-------------------+
| 12 | A | 6/17/2020 | 12:00PM | 1 |
+----------+------------+-----------+---------+-------------------+
| 12 | A | 6/18/2020 | 1:00PM | 1 |
+----------+------------+-----------+---------+-------------------+
| 12 | B | 6/18/2020 | 6:00AM | 2 |
+----------+------------+-----------+---------+-------------------+
| 12 | C | 6/19/2020 | 3:00PM | 3 |
+----------+------------+-----------+---------+-------------------+
| 13 | A | 6/16/2020 | 8:00AM | 1 |
+----------+------------+-----------+---------+-------------------+
| 13 | A | 6/16/2020 | 11:00AM | 1 |
+----------+------------+-----------+---------+-------------------+
| 13 | A | 6/16/2020 | 12:00AM | 1 |
+----------+------------+-----------+---------+-------------------+
| 13 | B | 6/16/2020 | 4:00PM | 2 |
+----------+------------+-----------+---------+-------------------+
我试过的
SELECT
[t1].[PersonID]
,[t1].[LocationID]
,[t1].[Date]
,[t1].[Time]
,DENSE_RANK()
OVER(
partition BY [t1].[PersonID], [t1].[LocationID]
ORDER BY [t1].[Date] ASC, [t1].[Time] ASC) AS
[Transfer Sequence]
FROM Table1 [t1]
不幸的是,我认为 DENSE_RANK() 正在分配排名,而不管 LocationID 的值是否已更改。我需要一个函数,它只会在 LocationID 发生变化时向序列中添加一个。
如有任何帮助,我们将不胜感激。
谢谢!
您想将 "adjacent" 行放在同一组中。 Straigt window 函数无法为您做到这一点 - 我们需要使用间隙和孤岛技术:
select
t.*,
sum(case when locationID = lagLocationID then 0 else 1 end)
over(partition by personID order by date, time)
as transfert_sequence
from (
select
t.*,
lag(locationID)
over(partition by personID order by date, time)
as lagLocationID
from mytable t
) t
我们的想法是计算一个 window 总和,每次 locationID 更改时该总和都会增加。
请注意,当一个人回到他们之前去过的地方时,这将正确处理这种情况。
我要做的(而且我确定这不是最好的方法)是创建第二个 table orderd,其中包含 PersonID、locationID、Date、time 和空字段用于传输序列(sequence) ,然后是光标:
DECLARE transaction CURSOR
FOR select PersonID, LocationID, Date, Time from table1;
然后循环:
OPEN CURSOR transaction
set @count = 0
set @person_saved = ""
set @location_saed = ""
FETCH NEXT FROM transaction INTO @person, @location, @date, @time
WHILE @@FETCH_STATUS = 0
BEGIN
if @person_saved <> @person -- changing personID, reset count
begin
set count = 0
set persone_saved = @person
end
if @location_saved <> @location. -- changing location, add count
begin
set @count = @count + 1
set @location_saved = @location
end
update table1 set sequence = @count where PersonId = @person and locationId = @location and date = @date and time = @time
FETCH NEXT FROM transaction INTO @person, @location, @date, @time
END
CLOSE transaction
DEALLOCATE transaction
我无法弄清楚如何编写 window 函数来解决我的问题。我是 window 函数的新手,但我认为可以编写一个来满足我的需要。
问题陈述:
我想计算一个传输序列,显示人员何时根据相应的位置 ID 随着时间的推移更改位置。
示例数据(表 1)
+----------+------------+-----------+---------+
| PersonID | LocationID | Date | Time |
+----------+------------+-----------+---------+
| 12 | A | 6/17/2020 | 12:00PM |
+----------+------------+-----------+---------+
| 12 | A | 6/18/2020 | 1:00PM |
+----------+------------+-----------+---------+
| 12 | B | 6/18/2020 | 6:00AM |
+----------+------------+-----------+---------+
| 12 | C | 6/19/2020 | 3:00PM |
+----------+------------+-----------+---------+
| 13 | A | 6/16/2020 | 8:00AM |
+----------+------------+-----------+---------+
| 13 | A | 6/16/2020 | 11:00AM |
+----------+------------+-----------+---------+
| 13 | A | 6/16/2020 | 12:00AM |
+----------+------------+-----------+---------+
| 13 | B | 6/16/2020 | 4:00PM |
+----------+------------+-----------+---------+
预期结果
+----------+------------+-----------+---------+-------------------+
| PersonID | LocationID | Date | Time | Transfer Sequence |
+----------+------------+-----------+---------+-------------------+
| 12 | A | 6/17/2020 | 12:00PM | 1 |
+----------+------------+-----------+---------+-------------------+
| 12 | A | 6/18/2020 | 1:00PM | 1 |
+----------+------------+-----------+---------+-------------------+
| 12 | B | 6/18/2020 | 6:00AM | 2 |
+----------+------------+-----------+---------+-------------------+
| 12 | C | 6/19/2020 | 3:00PM | 3 |
+----------+------------+-----------+---------+-------------------+
| 13 | A | 6/16/2020 | 8:00AM | 1 |
+----------+------------+-----------+---------+-------------------+
| 13 | A | 6/16/2020 | 11:00AM | 1 |
+----------+------------+-----------+---------+-------------------+
| 13 | A | 6/16/2020 | 12:00AM | 1 |
+----------+------------+-----------+---------+-------------------+
| 13 | B | 6/16/2020 | 4:00PM | 2 |
+----------+------------+-----------+---------+-------------------+
我试过的
SELECT
[t1].[PersonID]
,[t1].[LocationID]
,[t1].[Date]
,[t1].[Time]
,DENSE_RANK()
OVER(
partition BY [t1].[PersonID], [t1].[LocationID]
ORDER BY [t1].[Date] ASC, [t1].[Time] ASC) AS
[Transfer Sequence]
FROM Table1 [t1]
不幸的是,我认为 DENSE_RANK() 正在分配排名,而不管 LocationID 的值是否已更改。我需要一个函数,它只会在 LocationID 发生变化时向序列中添加一个。
如有任何帮助,我们将不胜感激。
谢谢!
您想将 "adjacent" 行放在同一组中。 Straigt window 函数无法为您做到这一点 - 我们需要使用间隙和孤岛技术:
select
t.*,
sum(case when locationID = lagLocationID then 0 else 1 end)
over(partition by personID order by date, time)
as transfert_sequence
from (
select
t.*,
lag(locationID)
over(partition by personID order by date, time)
as lagLocationID
from mytable t
) t
我们的想法是计算一个 window 总和,每次 locationID 更改时该总和都会增加。
请注意,当一个人回到他们之前去过的地方时,这将正确处理这种情况。
我要做的(而且我确定这不是最好的方法)是创建第二个 table orderd,其中包含 PersonID、locationID、Date、time 和空字段用于传输序列(sequence) ,然后是光标:
DECLARE transaction CURSOR
FOR select PersonID, LocationID, Date, Time from table1;
然后循环:
OPEN CURSOR transaction
set @count = 0
set @person_saved = ""
set @location_saed = ""
FETCH NEXT FROM transaction INTO @person, @location, @date, @time
WHILE @@FETCH_STATUS = 0
BEGIN
if @person_saved <> @person -- changing personID, reset count
begin
set count = 0
set persone_saved = @person
end
if @location_saved <> @location. -- changing location, add count
begin
set @count = @count + 1
set @location_saved = @location
end
update table1 set sequence = @count where PersonId = @person and locationId = @location and date = @date and time = @time
FETCH NEXT FROM transaction INTO @person, @location, @date, @time
END
CLOSE transaction
DEALLOCATE transaction