【问题标题】:Running count SQL server运行计数 SQL 服务器
【发布时间】:2021-05-13 22:30:18
【问题描述】:

谁能帮我计算 SQL Server 中的行数

Id Date   Trend 
A 15-1-20 Uptrend
A 14-1-20 Uptrend
A 13-1-20 Uptrend
A 12-1-20 NULL
A 11-1-20 Uptrend
A 10-1-20 Uptrend
A 09-1-20 NULL

预期结果

Id Date   Trend    Counttrend
A 15-1-20 Uptrend      3
A 14-1-20 Uptrend      2
A 13-1-20 Uptrend      1
A 12-1-20 NULL        NULL
A 11-1-20 Uptrend      2
A 10-1-20 Uptrend      1
A 09-1-20 NULL        NULL


CREATE TABLE #TREND (ID Varchar(2),[DATE] Date ,TREND Varchar(10))

INSERT INTO #trend
  ( ID, [DATE], TREND )
VALUES
  ('A', '01-15-2020', 'Uptrend'), 
  ('A', '01-14-2020', 'Uptrend'), 
  ('A', '01-13-20', 'Uptrend'),
  ('A', '01-12-20', NULL),
  ('A', '01-11-20', NULL),
  ('A', '01-10-20', 'Uptrend'),
  ('A', '01-09-20', 'Uptrend');

【问题讨论】:

  • 什么DBMS?
  • 微软 SQL 服务器
  • 请向我们展示您的尝试。也许试试row_number()
  • 我试过 row_number 但它是一起计数的。如果值为空,我想要结果,那么计数应该重新开始。
  • 向我们展示您的尝试。您可能需要调整分区。如果您以 DDL+DML 的形式提供示例数据,我们可以更轻松地为您提供帮助。

标签: sql sql-server tsql count cumulative-sum


【解决方案1】:

试试这个:

SELECT src.Id, src.[Date], src.Trend, 
  CASE
    WHEN Trend IS NULL THEN NULL
    ELSE ROW_NUMBER() OVER (PARTITION BY Id, Trend, MasterSeq-SubSeq ORDER BY [Date])
  END AS TrendCnt
FROM (
  SELECT *,  
    ROW_NUMBER() OVER(PARTITION BY Id ORDER BY [Date]) As MasterSeq,
    ROW_NUMBER() OVER(PARTITION BY Id, Trend ORDER BY [Date]) +1 As SubSeq
    FROM aaa
) src
ORDER BY [Date] DESC;

【讨论】:

  • 非常感谢您的帮助。欣赏它:D 它的工作原理
  • 不客气。请接受我的回答作为解决方案。
【解决方案2】:

你没有明确指定你想要的逻辑。您似乎想要自最近的 NULL 日期以来的天数。您可以使用窗口函数轻松计算:

select t.*,
       (case when trend is not null
             then datediff(day,
                           max(case when trend is null then date end) over (order by date),
                           date)
        end)
from trend t
order by date desc;

Here 是一个 dbfiddle,与您的问题中的结果相匹配。

【讨论】:

  • 我还想在 null 之后再次计算上升趋势。很抱歉没有明确说明逻辑。
  • @ajaytilak 。 . .这就是它的作用。它完全返回问题中指定的结果。
  • 另一个有趣的选择,+1!
【解决方案3】:

对于实现相同结果的稍微不同的方式:

with cte as (
    select *
      -- Find the null transitions so we can row number them
      , sum(case when Trend is null then 1 else 0 end) over (order by [Date] asc) RowBreak
    from @Test
)
select *
  -- filter out the case when Trend is null
  , case when Trend is not null then row_number() over (partition by RowBreak, Trend order by [Date] asc) else null end
from cte
order by [Date] desc;

【讨论】:

  • 有趣的选择,+1!
  • 有趣。感谢您提供替代解决方案@daleK
猜你喜欢
  • 2021-06-11
  • 1970-01-01
  • 2010-09-16
  • 1970-01-01
  • 1970-01-01
  • 2017-11-21
  • 2010-09-11
  • 1970-01-01
  • 2019-07-03
相关资源
最近更新 更多