This question already has answers here:
Group by column and multiple Rows into One Row multiple columns
(2 answers)
Closed 6 months ago.
I have read stuff on pivot tables and I am still having problems getting this correct.
I have a table where column 1 is a Productnr, and column 2 is LHS, column 3 is another Productnr and lastly column 4 is RHS. Also the number of entries of Productnr2 (belonging to Productnr) is variable between 1 and 5. For example, if there are only 3 associated Productnr2 (see article no = 060013 in Productnr) then the last two columns should remain empty.
Productnr LHS Productnr2 RHS
060009 411 099088 5
060013 228 194139 25
060013 228 194141 17
060013 228 175823 75
060022 951 147071 90
060034 424 099088 14
060034 424 102704 88
060034 424 080034 82
060034 424 108436 87
060034 424 108437 58
I would like it to come out as a pivot table, like this:
Productnr | LHS | 1 | RHS | 2 | RHS | 3 | RHS | 4 | RHS | 5 | RHS |
-----
060009 411 099088 5
060013 228 194139 25 194141 17 175823 75
060022 951 147071 90
060034 424 099088 14 102704 88 080034 82 108436 87 108437 58
This can achieve by the following query. But this will work only for five different columns only, if more columns needed then need to increase the case count, but this is not recommended. Better try some dynamic queries for more columns.
CREATE TABLE #temp(Productnr INT, LHS INT, Productnr2 INT, RHS INT)
INSERT INTO #temp VALUES (060009,411,099088,5 )
INSERT INTO #temp VALUES (060013,228,194139,25)
INSERT INTO #temp VALUES (060013,228,194141,17)
INSERT INTO #temp VALUES (060013,228,175823,75)
INSERT INTO #temp VALUES (060022,951,147071,90)
INSERT INTO #temp VALUES (060034,424,099088,14)
INSERT INTO #temp VALUES (060034,424,102704,88)
INSERT INTO #temp VALUES (060034,424,080034,82)
INSERT INTO #temp VALUES (060034,424,108436,87)
INSERT INTO #temp VALUES (060034,424,108437,58)
;WITH CTE AS(
SELECT *
,ROW_NUMBER() OVER(PARTITION BY Productnr ORDER BY Productnr)RN
FROM #temp
)
SELECT Productnr,LHS
,MAX(CASE WHEN RN=1 THEN Productnr2 END) [1]
,MAX(CASE WHEN RN=1 THEN RHS END) [RHS]
,MAX(CASE WHEN RN=2 THEN Productnr2 END) [2]
,MAX(CASE WHEN RN=2 THEN RHS END) [RHS]
,MAX(CASE WHEN RN=3 THEN Productnr2 END) [3]
,MAX(CASE WHEN RN=3 THEN RHS END) [RHS]
,MAX(CASE WHEN RN=4 THEN Productnr2 END) [4]
,MAX(CASE WHEN RN=4 THEN RHS END) [RHS]
,MAX(CASE WHEN RN=5 THEN Productnr2 END) [5]
,MAX(CASE WHEN RN=5 THEN RHS END) [RHS]
FROM CTE
GROUP BY Productnr,LHS
DROP TABLE #temp
Output:
Productnr LHS 1 RHS 2 RHS 3 RHS 4 RHS 5 RHS
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
60009 411 99088 5 NULL NULL NULL NULL NULL NULL NULL NULL
60013 228 194139 25 194141 17 175823 75 NULL NULL NULL NULL
60022 951 147071 90 NULL NULL NULL NULL NULL NULL NULL NULL
60034 424 99088 14 102704 88 80034 82 108436 87 108437 58
Related
Given the following data table
Id Code Date PIVOT VALUE1 VALUE2
1 WMAZ 2014-01-31 12:23:06.000 1 103 1
2 EEEE 2014-01-31 11:59:15.000 2 74 2
3 WMAZ 2014-01-31 11:59:10.000 1 3 3
4 WMAZ 2014-01-31 11:56:55.000 2 10 4
5 WMAZ 2014-01-31 11:56:14.000 2 96 5
6 EEEE 2014-01-31 11:55:26.000 2 159 6
I need to pivot the data to get this:
Code Date SUMVALUE1FORPIVOT1 SUMVALUE1FORPIVOT2 SUMVALUE2FORPIVOT1 SUMVALUE2PIVOT2
WMAZ 2014-01-31 (103+3) (10+96) (1+3) (4+5)
EEEE 2014-01-31 NULL (74+159) NULL (6+2)
How do I get a sum for value1 and value2 for each pivot grouped by Code and Date without writing a sub-query for each field?
You could do something like this:
Test data
DECLARE #tbl TABLE(Id INT,Code VARCHAR(100),
Date DATETIME,
[PIVOT] INT,
VALUE1 INT,
VALUE2 INT)
INSERT INTO #tbl
VALUES
(1,'WMAZ','2014-01-31 12:23:06.000',1,103,1),
(2,'EEEE','2014-01-31 11:59:15.000',2,74,2),
(3,'WMAZ','2014-01-31 11:59:10.000',1,3,3),
(4,'WMAZ','2014-01-31 11:56:55.000',2,10,4),
(5,'WMAZ','2014-01-31 11:56:14.000',2,96,5),
(6,'EEEE','2014-01-31 11:55:26.000',2,159,6)
Query
SELECT
tbl.Code,
CAST(tbl.Date AS DATE) AS Date,
SUM(CASE WHEN [PIVOT]=1 THEN VALUE1 ELSE NULL END) AS SUMVALUE1FORPIVOT1,
SUM(CASE WHEN [PIVOT]=2 THEN VALUE1 ELSE NULL END) AS SUMVALUE1FORPIVOT2,
SUM(CASE WHEN [PIVOT]=1 THEN VALUE2 ELSE NULL END) AS SUMVALUE2FORPIVOT1,
SUM(CASE WHEN [PIVOT]=2 THEN VALUE2 ELSE NULL END) AS SUMVALUE2FORPIVOT2
FROM
#tbl AS tbl
GROUP BY
tbl.Code,
CAST(tbl.Date AS DATE)
ORDER BY
tbl.Code DESC
Result:
Code Date SUMVALUE1FORPIVOT1 SUMVALUE1FORPIVOT2 SUMVALUE2FORPIVOT1 SUMVALUE2PIVOT2
---------------------------------------------------------------------------------------------------
WMAZ 2014-01-31 106 106 4 9
EEEE 2014-01-31 NULL 233 NULL 8
ID DepID Status
------------------
000 54 0
000 12 1
141 14 0
141 56 1
000 12 0
000 89 1
I have the above table in which I have the depID. The following is the output I need:
ID DepOld DepNew
-------------------
000 54 12
141 14 56
000 12 89
Status of 0 means its old and 1 means new. How do I get the above output, considering it's in one table?
I can't use the IN clause.
I tried the following
SELECT
ID,
Max(CASE
WHEN Status = 0 THEN DepID
END) DepOld,
Max(CASE
WHEN Status = 1 THEN DepID
END) DepNew
FROM
tablename
GROUP BY
ID
but this the output I get
Id DepOld DepNew
--------------------
000 54 54
000 12 NULL
141 14 14
141 56 Null
if i pass depID=54 then this output is what i want
ID DepOld DepNew
000 54 12
You can use conditional aggregation:
select id,
max(case when status = 0 then DepID end) as DepOld,
max(case when status = 1 then DepID end) as DepNew
from table t
group by id;
If you'll only ever have two rows per ID, one with Status = 0 and the other with Status = 1, you could join the table to itself based on the ID column so you have both the old and new Department IDs available in a single row:
SELECT old.ID, old.DepID AS DepOld, new.DepID AS DepNew
FROM your_table old
INNER JOIN your_table new ON old.ID = new.ID AND new.Status = 1
WHERE old.Status = 0
Using Case statement and Max aggragate you can get the result.
CREATE TABLE #fast
(
ID VARCHAR(100),
DepID INT,
Status INT
)
INSERT INTO #fast
VALUES ( '000',54,0),
('000',12,1),
('141',14,0),
('141',56,1),
('000',12,0),
('000',89,1)
SELECT ID,
Max(CASE
WHEN Status = 0 THEN DepID
END) DepOld,
Max(CASE
WHEN Status = 1 THEN DepID
END) DepNew
FROM tablename
GROUP BY ID
i have a table as follows
and my expected output is as follows.
SQL Fiddle for this problem
In expected output ,it need to be pivoted by combination of id & date .
How can i solve this problem ?
There is not any PIVOT function in sql lite. Which the link that you have supplied leads to. But you could do this:
SELECT
yourtable.Id,
yourtable.Date,
MAX(CASE WHEN [Type]=1 THEN [Value] ELSE NULL END) AS [1],
MAX(CASE WHEN [Type]=2 THEN [Value] ELSE NULL END) AS [2],
MAX(CASE WHEN [Type]=3 THEN [Value] ELSE NULL END) AS [3]
FROM
yourtable
GROUP BY
yourtable.Id,
yourtable.Date
If you want to do it with an pivot and are using MSSQL 2012. Then you can do this:
SELECT
*
FROM
(
SELECT
yourtable.Id,
yourtable.Date,
yourtable.Type,
yourtable.Value
FROM
yourtable
) AS sourceTable
PIVOT
(
MAX(Value)
FOR Type IN([1],[2],[3],[4])
) AS pvt
This will result in this:
1 2014-04-01 00:00:00.000 23 NULL NULL NULL
2 2014-04-01 00:00:00.000 56 NULL NULL NULL
3 2014-04-01 00:00:00.000 12 78 NULL NULL
2 2014-07-01 00:00:00.000 56 NULL NULL NULL
3 2014-07-01 00:00:00.000 12 78 33 NULL
I have a table with data like:
A1 FID A2
0 0 39
1 0 23
0 1 16
1 1 64
2 1 12
0 2 76
0 3 11
0 4 87
And I want to create a view that will list this:
FID Col0 Col1 Col2
0 39 23 null
1 16 64 12
2 76 null null
3 11 null null
4 87 null null
How can this be possible in T-SQL?
You could use something like this:
SELECT FID,
Col0 = MAX(CASE WHEN A1 = 0 THEN A2 END),
Col1 = MAX(CASE WHEN A1 = 1 THEN A2 END),
Col2 = MAX(CASE WHEN A1 = 2 THEN A2 END)
FROM T
GROUP BY FID;
Or you could use PIVOT
SELECT pvt.FID,
[Col0] = pvt.[0],
[Col1] = pvt.[1],
[Col2] = pvt.[2]
FROM T
PIVOT
( MAX(A2)
FOR A1 IN ([0], [1], [2])
) pvt
Examples of Both on SQL Fiddle
If you have an unknown number of values for A1, and therefore an unknown number of columns you cannot do this in a view. You would need to use Dynamic SQL, although this is usually better handled in the application layer, not in SQL-Server itself
Hail to the fellow programmers and query writers,
I have this beautiful query
SELECT ID, [1] AS coL1, [15] AS coL2, [2] AS coL3, [16] AS coL4, [12] AS coL5
FROM MY_TABLE
PIVOT (sum(INT_VALUE) FOR FUND_CODE IN ([1],[2],[15],[16],[12])) AS p
--GROUP BY ID, [1] , [15] , [2] , [16] , [12]
ORDER BY ID ASC
That returns me data like this:
10001 182 NULL NULL NULL
10001 NULL 81 NULL NULL
10001 NULL NULL 182 NULL
10001 NULL NULL NULL 81
10002 165 NULL NULL NULL
10002 NULL 73 NULL NULL
10002 NULL NULL 165 NULL
10002 NULL NULL NULL 73
The 10001 and 10002 are two primary keys, and I'd like to show my data like this:
10001 182 81 182 81
10002 165 73 165 73
I tried this commented GROUP BY to no avail.
Any hints? Does it involve COALESCE?
SELECT ID
,SUM(1) AS 'col1'
,SUM(15) AS 'col2'
,SUM(2) AS 'col3'
,SUM(16) AS 'col4'
,SUM(12) AS 'col5'
FROM Table GROUP BY ID
Just in CASE...
SELECT ID,
SUM(CASE WHEN FUND_CODE = 1 THEN VR_MOVIMENTACAO_QUOTA ELSE 0 END) coL1,
SUM(CASE WHEN FUND_CODE = 15 THEN VR_MOVIMENTACAO_QUOTA ELSE 0 END) coL2,
SUM(CASE WHEN FUND_CODE = 2 THEN VR_MOVIMENTACAO_QUOTA ELSE 0 END) coL3,
SUM(CASE WHEN FUND_CODE = 16 THEN VR_MOVIMENTACAO_QUOTA ELSE 0 END) coL4,
SUM(CASE WHEN FUND_CODE = 12 THEN VR_MOVIMENTACAO_QUOTA ELSE 0 END) coL5
FROM MY_TABLE
GROUP BY ID