【问题标题】:TSQL - Calculate difference between values from yesterday to today, SELF JOIN questionTSQL - 计算从昨天到今天的值之间的差异,SELF JOIN 问题
【发布时间】:2020-12-06 19:07:54
【问题描述】:

我已将来自各种在线答案的代码拼凑在一起以获得我想要的结果,但我不明白它为什么会起作用,我想知道 JOIN 在 RowNum + 1 处实际做了什么。

最初的问题是计算一个值从昨天到今天的百分比差异。我对自加入有点模糊,但我确实了解自加入。当我添加 RowNum 列时,这让我很困惑。


问题

请问T2.RowNum = T1.RowNum + 1 在self join中是做什么的?

IF OBJECT_ID('tempdb..#t1') IS NOT NULL DROP TABLE #t1

CREATE TABLE #T1 (
ProductTotal int
,CountDate date
)

INSERT INTO #t1
VALUES 
       (893911,'20200815')
      ,(888970,'20200816')
      ,(899999,'20200817')
      

WITH cte AS (
SELECT 
 ROW_NUMBER() OVER(ORDER BY CountDate) AS RowNum
,ProductTotal
,CountDate
FROM #t1
WHERE   CountDate > CAST(GETDATE () - 2 AS DATE)
)
SELECT 
    t1.RowNum
   ,t1.ProductTotal   
   ,CAST(((t1.ProductTotal - t2.ProductTotal) * 1.0 / t2.ProductTotal) * 100 AS DECIMAL(10,2))  AS ProductDiff
   ,t1.CountDate
FROM cte AS t1
LEFT JOIN cte t2 ON T2.RowNum = T1.RowNum + 1

【问题讨论】:

  • 这里有什么你不明白的地方? ROW_NUMBER 做什么,或者T2.RowNum = T1.RowNum + 1 如何工作?然而,就我个人而言,我会简单地使用 LAGLEAD 函数,而不是自加入,这会将扫描次数从 2 次降低到 1 次。
  • 嗨@Larnu,我了解 Row_Number 的工作原理,但我不明白 T2.RowNum = T1.RowNum + 1 的工作原理。谢谢!

标签: sql tsql sql-server-2014


【解决方案1】:

假设您每天都有价值,更好的方法是使用lag()

SELECT ProductTotal, CountDate,
       (ProductTotal - prev_ProductTotal) * 1.0 / ProductTotal
FROM (SELECT t.*, 
             LAG(ProductTotal) OVER (ORDER BY CountDate) as prev_ProductTotal
      FROM #t1 t
     ) t
WHERE CountDate > CAST(GETDATE () - 1 AS DATE)

【讨论】:

  • 谢谢@GordonLinoff。我以前没有见过这种结构。请问 t.* 在 FROM 子句的子查询中引用/做什么?
  • 对于所有关注这个问题的人,Gordon 回答了最终需要做什么(改变逻辑),Larnu 回答了具体问题。
【解决方案2】:

请注意,正如我所说,我完全同意 Gordon 的观点,LAG(或LEAD)是这里的正确答案。为了解释您在评论中提出的问题“我不明白 T2.RowNum = T1.RowNum + 1 的工作原理”:

JOIN 返回 ON 中的表达式为真的行。因为您有一个INNER JOIN,所以只显示来自JOIN 两侧的行,其中表达式的计算结果为True。对于LEFT JOIN,之前返回的任何先前都不会“丢失”。 (还有其他类型的连接。)

对于T2.RowNum = T1.RowNum + 1,这是基本数学。 2 匹配 1 (1+1),3 匹配 2 (2+1)... 100 匹配 99 (99 + 1)。因此,T1 中的数据根据​​ CTE 中定义的ROW_NUMBER 顺序与“之后”行匹配。在这种情况下,这将是 CountDate 的“下一个”值按升序排列的行。

【讨论】:

    猜你喜欢
    • 2020-12-04
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多