基于上一个值计算运行计数器的SQL查询
我有一个表,有vDateTime,Category列。 我想创建一个列,根据以前的类别值递增计数。i、 e如果当前类别与前一个计数器相同,则计数器将递增,否则将重置为1。 我使用的是密集排列,但如果前一个值与当前值不同,如何重置该值基于上一个值计算运行计数器的SQL查询,sql,sql-server,Sql,Sql Server,我有一个表,有vDateTime,Category列。 我想创建一个列,根据以前的类别值递增计数。i、 e如果当前类别与前一个计数器相同,则计数器将递增,否则将重置为1。 我使用的是密集排列,但如果前一个值与当前值不同,如何重置该值 SELECT vDateTime, Category, DENSE_RANK()over(Partition by Category order by vDateTime, Category) as Rank FROM tblA ORDER BY vDateTi
SELECT vDateTime, Category,
DENSE_RANK()over(Partition by Category order by vDateTime, Category) as Rank
FROM tblA
ORDER BY vDateTime, Category
这是一个缺口和孤岛问题。我建议行数的差异:
select a.*,
row_number() over (partition by category, (seqnum_2 - seqnum) order by vDateTime) as expected_output
from (select a.*,
row_number() over (order by vDateTime) as seqnum,
row_number() over (partition by category order by vDateTime) as seqnum_2,
from tbla
) a
order by vDateTime, Category;
您可以尝试使用窗口函数LAG和SUM的另一种可能方法: 表:
CREATE TABLE Data (
vDateTime datetime,
Category varchar(10)
)
INSERT INTO Data
(vDateTime, Category)
VALUES
('2010-04-27T16:12:00', 'KCLK'),
('2010-06-15T17:40:00', 'KCLE'),
('2010-07-12T10:29:00', 'KCLK'),
('2010-08-13T10:41:00', 'KCLK'),
('2010-08-13T11:33:00', 'KCLE'),
('2010-08-17T15:37:00', 'KCLE'),
('2010-09-01T11:10:00', 'KCLE'),
('2010-09-17T10:37:00', 'KCLE'),
('2010-09-21T12:22:00', 'KCLE'),
('2010-09-27T15:38:00', 'KCLE'),
('2010-09-28T14:11:00', 'KXAMC'),
('2010-10-08T11:18:00', 'KCLK'),
('2010-10-08T15:45:00', 'KCLE')
声明:
;WITH ChangesCTE AS (
SELECT
vDateTime, category,
CASE WHEN LAG(Category) OVER (ORDER BY vDateTime) = Category THEN 0 ELSE 1 END AS [Change]
FROM Data
), GroupsCTE AS (
SELECT
vDateTime, category,
SUM([Change]) OVER (ORDER BY vDateTime) AS [Group]
FROM ChangesCTE
)
SELECT
vDateTime, category,
ROW_NUMBER() OVER (PARTITION BY [Group] ORDER BY vDateTime) AS rn
FROM GroupsCTE
一种选择是使用滞后分析函数一次,然后对分析函数求和两次
with tblB as
(
select Category, vDateTime,
lag(Category) over (order by vDateTime) as lg
from tblA
), tblC as
(
select Category, vDateTime,
case
when category != lg then
1
else
sum(case when category = lg then 0 else 1 end) over ( order by vDateTime )
end as Rank
from tblB
)
select Category, vDateTime,
sum(case when rank = 1 then 0 else 1 end) over
( partition by rank order by vDateTime ) + 1 as Rank
from tblC
order by vDateTime
请以text.4/27/2010 16:12 KCLK 1 6/15/2010 17:40 KCL1 7/12/2010 10:29 KCLK 2 8/13/2010 10:41 KCLK 3 8/13/2010 11:33 KCL2 8/17/2010 15:37 KCL3 9/1/2010 11:10 KCL4 9/17/2010 10:37 KCL5 9/21/2010 12:22 KCL6 9/27/2010 15:38 KCL7 9/28/2010 14:11 KXAMC 1 10/8/2010 11:18 KCLK 4 10/8:45的形式发布样本数据