Sql-Server-2012

想在 SQL 中同時使用 pivot 和 lag 函式

  • December 11, 2020

我在一張表中有以下數據。我想把這些數據放在列中,然後根據年份有所不同。

+---------+--------+------+-------+
| Product | REGION | YEAR | Sales |
+---------+--------+------+-------+
| TEA     | D1     | 2018 | 40    |
| TEA     | D2     | 2018 | 30    |
| TEA     | D3     | 2018 | 20    |
| TEA     | D4     | 2018 | 10    |
| TEA     | D5     | 2018 | 7     |
| COFFEE  | D1     | 2018 | 70    |
| COFFEE  | D2     | 2018 | 100   |
| COFFEE  | D3     | 2018 | 200   |
| COFFEE  | D4     | 2018 | 300   |
| COFFEE  | D5     | 2018 | 400   |
| TOFFEE  | D1     | 2018 | 30    |
| TOFFEE  | D2     | 2018 | 7     |
| TOFFEE  | D3     | 2018 | 400   |
| TOFFEE  | D4     | 2018 | 34    |
| TOFFEE  | D5     | 2018 | 90    |
| TEA     | D1     | 2019 | 1     |
| TEA     | D2     | 2019 | 2     |
| TEA     | D3     | 2019 | 3     |
| TEA     | D4     | 2019 | 4     |
| TEA     | D5     | 2019 | 5     |
| COFFEE  | D1     | 2019 | 6     |
| COFFEE  | D2     | 2019 | 7     |
| COFFEE  | D3     | 2019 | 8     |
| COFFEE  | D4     | 2019 | 9     |
| COFFEE  | D5     | 2019 | 10    |
| TOFFEE  | D1     | 2019 | 11    |
| TOFFEE  | D2     | 2019 | 12    |
| TOFFEE  | D3     | 2019 | 13    |
| TOFFEE  | D4     | 2019 | 14    |
| TOFFEE  | D5     | 2019 | 15    |
| TEA     | D1     | 2020 | 16    |
| TEA     | D2     | 2020 | 17    |
| TEA     | D3     | 2020 | 18    |
| TEA     | D4     | 2020 | 19    |
| TEA     | D5     | 2020 | 20    |
| COFFEE  | D1     | 2020 | 21    |
| COFFEE  | D2     | 2020 | 22    |
| COFFEE  | D3     | 2020 | 23    |
| COFFEE  | D4     | 2020 | 24    |
| COFFEE  | D5     | 2020 | 25    |
| TOFFEE  | D1     | 2020 | 26    |
| TOFFEE  | D2     | 2020 | 27    |
| TOFFEE  | D3     | 2020 | 28    |
| TOFFEE  | D4     | 2020 | 29    |
| TOFFEE  | D5     | 2020 | 30    |
+---------+--------+------+-------+

我想要下面的輸出。我無法對數據進行透視,但無法在我移至列的行上使用滯後(如果有人可以建議任何其他功能)。下面是預期的輸出

+---------+------+----------------------------+--------------------------------------+
|         |      |         Department         | Difference in year   department wise |
+---------+------+----+-----+-----+-----+-----+-------+------+-------+-------+-------+
| Product | Year | D1 | D2  | D3  | D4  | D5  | D1D   | D2D  | D3D   | D4D   | D5D   |
+---------+------+----+-----+-----+-----+-----+-------+------+-------+-------+-------+
| TEA     | 2018 | 40 | 30  | 20  | 10  | 7   | 40    | 30   | 20    | 10    | 7     |
| TEA     | 2019 | 1  | 2   | 3   | 4   | 5   | -39   | -28  | -17   | -6    | -2    |
| TEA     | 2020 | 16 | 17  | 18  | 19  | 20  | 15    | 15   | 15    | 15    | 15    |
| COFFEE  | 2018 | 70 | 100 | 200 | 300 | 400 | 70    | 100  | 200   | 300   | 400   |
| COFFEE  | 2019 | 6  | 7   | 8   | 9   | 10  | -64   | -93  | -192  | -291  | -390  |
| COFFEE  | 2020 | 21 | 22  | 23  | 24  | 25  | 15    | 15   | 15    | 15    | 15    |
| TOFFEE  | 2018 | 30 | 7   | 400 | 34  | 90  | 30    | 7    | 400   | 34    | 90    |
| TOFFEE  | 2019 | 11 | 12  | 13  | 14  | 15  | -19   | 5    | -387  | -20   | -75   |
| TOFFEE  | 2020 | 26 | 27  | 28  | 29  | 30  | 15    | 15   | 15    | 15    | 15    |
+---------+------+----+-----+-----+-----+-----+-------+------+-------+-------+-------+

因為您只提供了圖片,所以我用不同的數據填充了表格,但這也應該適用於您的情況。這是你想要的?

編輯: 我將查詢更改為動態的。這應該可以解決問題。當然,您必須將表名#tbl 更改為您的表名。

/*Creating a table and populating it*/
CREATE TABLE #tbl (product nvarchar(50), region nvarchar(10), [year] int, sales int);
DECLARE @sql nvarchar(max);
DECLARE @columnname nvarchar(max);

INSERT INTO #tbl(product, region, [year], sales)
SELECT  'TEA',  'D1',   2018,   40
UNION ALL SELECT    'TEA',  'D2',   2018,   30
UNION ALL SELECT    'TEA',  'D3',   2018,   20
UNION ALL SELECT    'TEA',  'D4',   2018,   10
UNION ALL SELECT    'TEA',  'D5',   2018,   7
UNION ALL SELECT    'COFFEE',   'D1',   2018,   70
UNION ALL SELECT    'COFFEE',   'D2',   2018,   100
UNION ALL SELECT    'COFFEE',   'D3',   2018,   200
UNION ALL SELECT    'COFFEE',   'D4',   2018,   300
UNION ALL SELECT    'COFFEE',   'D5',   2018,   400
UNION ALL SELECT    'TEA',  'D1',   2019,   1
UNION ALL SELECT    'TEA',  'D2',   2019,   2
UNION ALL SELECT    'TEA',  'D3',   2019,   3
UNION ALL SELECT    'TEA',  'D4',   2019,   4
UNION ALL SELECT    'TEA',  'D5',   2019,   5
UNION ALL SELECT    'COFFEE',   'D1',   2019,   6
UNION ALL SELECT    'COFFEE',   'D2',   2019,   7
UNION ALL SELECT    'COFFEE',   'D3',   2019,   8
UNION ALL SELECT    'COFFEE',   'D4',   2019,   9
UNION ALL SELECT    'COFFEE',   'D5',   2019,   10
UNION ALL SELECT    'TEA',  'D1',   2020,   13
UNION ALL SELECT    'TEA',  'D2',   2020,   26
UNION ALL SELECT    'TEA',  'D3',   2020,   39
UNION ALL SELECT    'TEA',  'D4',   2020,   52
UNION ALL SELECT    'TEA',  'D5',   2020,   65
UNION ALL SELECT    'COFFEE',   'D1',   2020,   78
UNION ALL SELECT    'COFFEE',   'D2',   2020,   91
UNION ALL SELECT    'COFFEE',   'D3',   2020,   104
UNION ALL SELECT    'COFFEE',   'D4',   2020,   117
UNION ALL SELECT    'COFFEE',   'D5',   2020,   130
;

SELECT @columnname=COALESCE(@columnname+ ',', '') + QUOTENAME(CAST(q.region AS nvarchar(20)),'[]')
FROM
(SELECT DISTINCT t.region
FROM #tbl t 
UNION ALL 
SELECT DISTINCT t.region+'D' AS region
FROM #tbl t) AS q



/*for your case, just replace the table name #tbl with the name of your table*/

SET @sql='
SELECT product, [year], '+@columnname+'
FROM
(SELECT product, 
CASE WHEN salee=''diff'' THEN region+''D'' ELSE region
END AS sales, [year], sale
FROM
(SELECT t.product, t.region, t.[year], t.sales, ISNULL((t.sales - LAG(t.sales) OVER(PARTITION BY t.product, t.region order by t.[year] asc)),t.sales) AS diff
FROM #tbl t) AS a
UNPIVOT
(sale for salee IN (sales, diff)) AS up) AS q
PIVOT 
(MAX(sale)
FOR sales IN ('+@columnname+')) AS p
ORDER BY product'

EXECUTE sp_executesql @sql

輸出:

+---------+------+----+-----+-----+-----+-----+-----+-----+------+------+------+
| product | year | D1 | D2  | D3  | D4  | D5  | D1D | D2D | D3D  | D4D  | D5D  |
+=========+======+====+=====+=====+=====+=====+=====+=====+======+======+======+
| COFFEE  | 2018 | 70 | 100 | 200 | 300 | 400 | 70  | 100 | 200  | 300  | 400  |
+---------+------+----+-----+-----+-----+-----+-----+-----+------+------+------+
| COFFEE  | 2019 | 6  | 7   | 8   | 9   | 10  | -64 | -93 | -192 | -291 | -390 |
+---------+------+----+-----+-----+-----+-----+-----+-----+------+------+------+
| COFFEE  | 2020 | 78 | 91  | 104 | 117 | 130 | 72  | 84  | 96   | 108  | 120  |
+---------+------+----+-----+-----+-----+-----+-----+-----+------+------+------+
| TEA     | 2018 | 40 | 30  | 20  | 10  | 7   | 40  | 30  | 20   | 10   | 7    |
+---------+------+----+-----+-----+-----+-----+-----+-----+------+------+------+
| TEA     | 2019 | 1  | 2   | 3   | 4   | 5   | -39 | -28 | -17  | -6   | -2   |
+---------+------+----+-----+-----+-----+-----+-----+-----+------+------+------+
| TEA     | 2020 | 13 | 26  | 39  | 52  | 65  | 12  | 24  | 36   | 48   | 60   |
+---------+------+----+-----+-----+-----+-----+-----+-----+------+------+------+

引用自:https://dba.stackexchange.com/questions/281325