【问题标题】:SQL - How to show the difference between multiple rows resultsSQL - 如何显示多行结果之间的差异
【发布时间】:2013-01-21 16:20:45
【问题描述】:

我有一个 SQL 2012 查询,结果如下:

IP_Country  ds          Percentage
-------------------------------------
Australia   01/01/2013  0.70155
Australia   02/01/2013  0.685
Australia   03/01/2013  0.663594
Australia   04/01/2013  0.737541
Australia   05/01/2013  0.688212
Australia   06/01/2013  0.665384
Australia   07/01/2013  0.620253
Australia   08/01/2013  0.697183

结果继续显示相同日期和不同百分比的不同国家。

我需要展示的是,这些百分比仅在同一国家/地区的日期之间变动。

因此,在 02/01 和 01/01 之间,差异为 0.02 - 我可以提取数据并在 excel 中执行此操作,但理想情况下,我希望结果随查询的移动而出现。

【问题讨论】:

  • 您将其标记为 MySQL,但您说您有一个 SQL 2012 查询,您使用的是什么数据库?
  • 抱歉 - 它的 MS SQL Server 2012,使用服务器管理工​​作室。
  • 没问题,我们只是想确保您有合适的用户查看您的问题。 :)
  • 0.701550.685 之间的区别是 0.01655 而不是 0.2。您在寻找比率吗?
  • 舍入不是必需的。一旦代码创建了附加列,这将使用报告生成器应用程序转换为实际百分比。

标签: sql sql-server sql-server-2012 sliding-window


【解决方案1】:

OUTER APPLY 和 EXISTS 的另一个选项

SELECT *, t1.Percentage - o.Percentage AS dif
FROM dbo.test36 t1 
OUTER APPLY (
             SELECT t2.Percentage
             FROM dbo.test36 t2
             WHERE t1.IP_Country = t2.IP_Country 
               AND EXISTS (
                           SELECT 1
                           FROM dbo.test36 t3
                           WHERE t1.IP_Country = t3.IP_Country AND t1.ds < t3.ds
                           HAVING MIN(t3.ds) = t2.ds
                           )
             ) o

SQLFiddle上的演示

【讨论】:

    【解决方案2】:

    使用 CTE 和 @MartinSmith 的小提琴 (DEMO)。 (注意:为了更好的可读性,我已经格式化了 [ds] 日期)

    ;with cte as (
      select [IP_Country], [ds], [Percentage],
             row_number() over (partition by [IP_Country] order by ds) rn
      from YourTable
    )
    select t1.[IP_Country], convert(date, t1.[ds],102), 
           t1.[Percentage], t2.[Percentage]-t1.[Percentage] movement
    from cte t1 left join cte t2 on t1.[IP_Country] = t2.[IP_Country]
              t1.rn - 1 = t2.rn
    
    --Results
    IP_COUNTRY  COLUMN_1    PERCENTAGE  MOVEMENT
    Australia   2013-01-01  0.70155     (null)
    Australia   2013-02-01  0.685       0.01655
    Australia   2013-03-01  0.663594    0.021406
    Australia   2013-04-01  0.737541    -0.073947
    Australia   2013-05-01  0.688212    0.049329
    Australia   2013-06-01  0.665384    0.022828
    Australia   2013-07-01  0.620253    0.045131
    Australia   2013-08-01  0.697183    -0.07693
    

    【讨论】:

      【解决方案3】:

      您可以使用LAGLEAD 访问上一行和下一行。

      SELECT *,
              LAG([Percentage]) OVER (PARTITION BY [IP_Country] ORDER BY [ds]) 
                                                                     - [Percentage] AS diff,
             ([Percentage] - LEAD([Percentage]) OVER (PARTITION BY [IP_Country] ORDER BY [ds])) 
                                                                   / [Percentage] AS [ratio]
      FROM  YourTable  
      

      SQL Fiddle

      【讨论】:

      • 'LAG' 不是可识别的内置函数名称。
      • @user2046878 - 那时你不在 2012 年。对于以前的版本,您需要在 ROW_NUMBER 上自行加入或使用递归 CTE。
      猜你喜欢
      • 2017-03-13
      • 2021-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-23
      相关资源
      最近更新 更多