【问题标题】:SQL - Difference between values between dates using GuidsSQL - 使用指南的日期之间的值之间的差异
【发布时间】:2015-10-02 18:05:14
【问题描述】:

我有一张这样的桌子:

[日期]、[guid]、[值(整数)]

数据如下:

10/1, id1, 10
10/1, id2, 5
10/2, id1, 12
10/2, id2, 14
10/3, id1, 11

我想回来:

10/1, id1, 2
10/1, id2, 9
10/2, id1, -1

相同ID的匹配,抓取第二天(不是下一个日期)的值,使用过去的值,减去。

所以 10/1, id1, 2 是通过

10/1, id1, 10
10/2, id1, 12 

所以我们返回第一天,10/1,和id,id1,12-10的值=2。

我将如何通过 SQL 执行此操作?

谢谢!

【问题讨论】:

  • 您使用的是哪个 DBMS?后格雷斯?甲骨文?
  • Date diff 总是 1 还是只是每个 id 的下一个日期?
  • 如果是 SqlServer,请同时包括 2008、2012、2014 年
  • 您说 id1 和 id2 是 GUID。我们是否也有一个关键的身份字段,以便我们可以知道哪个是何时创建的?如果 [value field] 存储为给定日期的第二个条目的负数,则这将是一个简单的 SUM,其中包含 GROUP BY[date], [guid]。没有它,我们将需要构建逻辑来确定应该翻转哪个标志。在您的示例中,请查看:10/1, id1, 1010/1, id1, 12,它们应该是 10/1, id1, 2 的摘要行我们怎么知道它应该是 12-10 = 2 而不是 10-12 = -2 没有订单?
  • 年份:2012 年,11.0.5343 无密钥标识。微软 SQL 服务器

标签: sql date guid between


【解决方案1】:

未经测试。 将 t1 中的所有值加入到协同子查询中,该子查询的唯一目的是为每个 guid 找到比该 guid 上的日期更高的下一个最小日期。然后再次加入整个值集并限制为仅识别的 guid 和 min 日期,使用此 t3 值从初始 t1 设置值中减去。

SELECT t1.date, t1.guid, t3.value-t1.value
FROM tableName t1
INNER JOIN (SELECT min(t2.Date) minDate, t2.GUID 
            FROM TableName t2
            WHERE t2.Date> t1.date  
            GROUP BY t2.GUID ) B
 on B.GUID = t1.guid
INNER JOIN tableName t3
 on t3.GUID= T1.guid
and t3.date = b.mindate

这里的假设是 guid 和 date 是唯一的一对,所有记录都不重复。

【讨论】:

    【解决方案2】:

    这里还有一个基于您提供的内容。这可能就是您正在查看的内容

    declare @test table 
    (
        dateId date,
        gguid uniqueidentifier,
        value int 
    )
    
    insert into @test(dateId,gguid,value)
    Values('10/1/2015','1DFE73AF-7940-4CDC-A22F-92DA8DEF7B6E', 10),
    ('10/1/2015', '6A057D92-7279-4E34-8ADC-870E45B5D49A', 5),
    ('10/2/2015', '1DFE73AF-7940-4CDC-A22F-92DA8DEF7B6E', 12),
    ('10/2/2015', '6A057D92-7279-4E34-8ADC-870E45B5D49A', 14),
    ('10/3/2015', '1DFE73AF-7940-4CDC-A22F-92DA8DEF7B6E', 11);
    
    with test
    as
    (
    select dateId,gguid,value 
    ,RANK() over (partition by gguid order by dateId) as RNK
    from @test
    ) select T.dateId,T.gguid,T.value, IsNull(T.value-X.value,0) as lastday  from test T left join (select dateId,gguid,value, RNK+1 as RNK from test)  AS X
    on  X.gguid = t.gguid and T.RNK = X.RNK
    

    【讨论】:

      【解决方案3】:

      在 SQL Server 2012+ 中,您将使用 lead()

      如果你想要所有五行,你会这样做:

      select d.*, lead(value) over (partition by id order by date) as next_value
      from data d;
      

      对于您的特定输出,您需要一个子查询:

      select d.id, d.date, d.next_value
      from (select d.*, lead(value) over (partition by id order by date) as next_value
            from data d
           ) d
      where next_value is not null;
      

      【讨论】:

        【解决方案4】:

        你应该使用LAG()

        Sql Fiddle Demo

        SELECT [Date], [guid], [value],  
               LAG([value],1, null) OVER (PARTITION BY [guid] ORDER BY [Date]) as previousValue
        FROM Table1
        

        输出

        忽略PreviousValue IS NULL所在的行,然后计算Value - PreviousValue

        |       Date | guid | value | previousValue |
        |------------|------|-------|---------------|
        | 2001-10-01 |  id1 |    10 |        (null) |
        | 2001-10-02 |  id1 |    12 |            10 |
        | 2001-10-03 |  id1 |    11 |            12 |
        | 2001-10-01 |  id2 |     5 |        (null) |
        | 2001-10-02 |  id2 |    14 |             5 |
        

        全部打包

        SELECT [Date], [guid], [value] - previousValue as [value]
        FROM (
          SELECT [Date], [guid], [value],  
                 LAG([value],1, null) OVER (PARTITION BY [guid] ORDER BY [Date]) as previousValue
          FROM Table1
        ) T
        WHERE T.previousValue IS NOT NULL
        ORDER BY [Date], [guid]
        

        【讨论】:

          猜你喜欢
          • 2023-03-08
          • 1970-01-01
          • 2015-06-21
          • 2011-02-01
          • 1970-01-01
          • 2012-02-04
          • 2019-07-19
          • 1970-01-01
          • 2021-10-21
          相关资源
          最近更新 更多