2013-02-06 61 views
5

我有一個SQL 2012查詢,讓我得到以下結果:SQL - 如何顯示多行之間的差異導致

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中執行此操作,但理想情況下,我希望結果與查詢中的移動一起出現。

+1

您標記這是MySQL,但你說你有一個SQL 2012查詢,你使用的是哪個數據庫? – Taryn

+0

對不起 - 它的MS SQL Server 2012,使用服務器管理工​​作室。 – user2046878

+1

沒問題,我們只是想確保你得到正確的用戶看你的問題。 :) – Taryn

回答

7

您可以使用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

+0

'LAG'不是公認的內置函數名稱。 – user2046878

+5

@ user2046878 - 你不在2012年。對於以前的版本,您需要自行加入'ROW_NUMBER'或使用遞歸CTE。 –

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 
0

還有一個與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