簡體   English   中英

如何用SQL返回去年同期數據?

[英]How to return the same period last year data with SQL?

我正在嘗試在 postgreSQL 中創建一個視圖,其要求如下:

該表需要顯示每條記錄的去年同期數據。

樣本數據:

date_sk  | location_sk | division_sk | employee_type_sk | value
20180202 | 6           | 8           | 4                | 1
20180202 | 7           | 2           | 4                | 2
20190202 | 6           | 8           | 4                | 1
20190202 | 7           | 2           | 4                | 1
20200202 | 6           | 8           | 4                | 1
20200202 | 7           | 2           | 4                | 3

在表中,date_sk、location_sk、division_sk 和employee_type_sk 是超級鍵,它們在表中形成了唯一的記錄。 您可以檢查所需的輸出如下:

date_sk  | location_sk | division_sk | employee_type_sk | value     | value_last_year
20180202 | 6           | 8           | 4                | 1         | NULL
20180203 | 7           | 2           | 4                | 2         | NULL
20190202 | 6           | 8           | 4                | 1         | 1
20190203 | 7           | 3           | 4                | 1         | NULL
20200202 | 6           | 8           | 4                | 1         | 1
20200203 | 7           | 3           | 4                | 3         | 1

記錄開始於20180202,因此無法獲得上年同期的數據。 在第 4 條記錄中,division_sk 與去年同期相比存在差異 - 因此,head_count_last_year 為 NULL。 我當前的解決方案是從示例數據創建一個視圖,添加列作為 same_date_last_year 然后左連接同一個表。 SQL 查詢如下:

CREATE VIEW test_view AS
SELECT *, 
    CONCAT(LEFT(date_sk, 4) - 1, RIGHT(date_sk, 4)) AS same_date_last_year 
FROM test_table 

SELECT
    test_view.date_sk,
    test_view.location_sk,
    test_view.division_sk,
    test_view.employee_type_sk,
    test_view.value,
    test_table.value AS value_last_year
FROM test_view
LEFT JOIN test_table ON (test_view.same_date_last_year  = test_table.date_sk)

我們有很多數據在表中。 我上面的解決方案在性能方面是不可接受的。 是否有不同的查詢產生相同的結果並可能提高性能?

您可以在這里簡單地使用相關子查詢,這可能最有利於性能:

select *, 
    (
        select value from t t2 
        where t2.date_sk=t.date_sk - interval '1' year and
          t2.location_sk=t.location_sk and
          t2.division_sk=t.division_sk and
          t2.employee_type_sk=t.employee_type_sk
    ) as value_last_year
from t
WITH CTE(DATE_SK,LOCATION_SK,DIVISION_SK,EMPLOYEE_TYPE_SK,VALUE)AS
 (
    SELECT CAST('20180202' AS DATE),6,8,4,1 UNION ALL 
    SELECT CAST('20180203'AS DATE),7,2,4,2 UNION ALL 
    SELECT CAST('20190202'AS DATE),6,8,4,1 UNION ALL 
    SELECT CAST('20190203'AS DATE),7,2,4,1 UNION ALL 
    SELECT CAST('20200202'AS DATE),6,8,4,1 UNION ALL 
    SELECT CAST('20200203'AS DATE),7,2,4,3  
 )
 SELECT C.DATE_SK,C.LOCATION_SK,C.DIVISION_SK,C.EMPLOYEE_TYPE_SK,C.VALUE,
    LAG(C.VALUE)OVER(PARTITION BY C.LOCATION_SK,C.DIVISION_SK,C.EMPLOYEE_TYPE_SK    ORDER BY C.DATE_SK ASC)LAGG
     FROM CTE AS C
  ORDER BY C.DATE_SK ASC;

請您試試以上是否適合您。 我假設,DATE_SK 是一個日期列或者可以 CAST 到一個日期

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM