【问题标题】:Comparing current Month and previous Month's rows on a column, SQL Server 2012比较列上的当前月份和上个月的行,SQL Server 2012
【发布时间】:2015-08-09 10:42:42
【问题描述】:

对于一个我不完全确定如何在 SQL Server 2012 中解决的问题,我需要一些指导和帮助。我认为 LAGLEAD 函数可能有用,但我不确定。

这是我的数据现在的样子:

=========================================
YearMonth   LocationCode    Active      
=========================================
201405      123              0  
201406      123              2  
201409      211              1
201410      211              0
201411      214              0
201412      214              3

我们有一个YearMonth 列显示每个locationCode 的状态,还有一个Active int 表示每个LocationCode 的质量

目标:

我的目标是比较当前的YearMonth(我们称之为201406)和之前的Yearmonth(我们称之为201405)的LocationCode

一个例子:

=========================================
YearMonth   LocationCode    Active      
=========================================
201405      123              0  
201406      123              2  

基本上,我想弄清楚的是如何在名为Active 的列上将当前月份的行 (201406) 与上个月的行 (201405) 进行比较。

如果当前月份的行 Active 列不为零且上个月的 Active 为零,则我们将当前月份的行推断为“新”(1) 否则 (0)。

下面是一个例子:

==================================================
YearMonth   LocationCode    Active   New    
===================================================
201405      123              0        0 
201406      123              2        1
201409      211              1        0
201410      211              0        0
201411      214              0        0
201412      214              3        1  

我该如何解决这个问题?

【问题讨论】:

  • 我对 ROW_NUMBER() 有许多变体,第一次看该行和 Active 为零,第二行为非零,但在许多情况下并没有正确显示。由于活动在某个月可能是 1 而其他不是,这就是为什么我热衷于对当前和上个月进行一些比较技术。

标签: sql sql-server-2012 lead


【解决方案1】:

我认为您可以使用这样的查询:

SELECT *,
    CASE 
        WHEN Active <> 0 AND 
             ISNULL(LAG(Active) OVER (PARTITION BY LocationCode ORDER BY YearMonth), 0) = 0 THEN 1 
        ELSE 0 
    END As New
FROM yourTable;

[SQL Fiddle Demo]

【讨论】:

  • 你测试过这个吗?看起来有些条件应该颠倒过来。
  • 是的,当然条件应该颠倒)
  • @Bulat 哎呀我明白了,谢谢;)。
  • 没问题,我不确定new是否可以为同一个locationcode设置多次。
【解决方案2】:

您可以像这样使用ROW_NUMBER() OVER 执行此操作:

WITH RankedCodesHistory AS (
 SELECT 
   YearMonth,
   LocationCode,
   Active,
   ROW_NUMBER() OVER (PARTITION BY LocationCode, CASE WHEN Active > 0 THEN 1 ELSE 0 END 
                    ORDER BY LocationCode, YearMonth, Active) rn
 FROM CodesHistory)
SELECT 
  YearMonth,
  LocationCode,
  Active,
  CASE WHEN Active > 0 AND rn = 1 THEN 1 ELSE 0 END AS New
FROM RankedCodesHistory

SQL Fiddle

我已经在 Fiddle 中扩展了您的数据样本,以演示如果 Active 回到零并第二次变为正数会发生什么 --- 在这种情况下,上面的代码不会将相应的行设置为新的。

【讨论】:

  • 感谢您的建议。您认为有一种方法可以解决此问题的 LAG 和 LEAD 功能吗?您的解决方案很好,但我这边的问题是我将拥有数百万的行。这就是为什么我有兴趣只比较两个月,即上个月的列与本月的记录。我喜欢你的解决方案,因为它让我更深入地了解了我如何用你的策略解决其他问题。谢谢布拉特。
  • 现在@shA.t 用正确的条件更新了他的答案,它对你有用吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-23
  • 1970-01-01
  • 2019-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多