Oracle Pivot Based on Multiple Columns - sql

I am fairly new to Pivoting and trying to Pivot based on two columns.
Data I have:
Data I want to Achieve after pivoting:
My Query which is Flawed:
select *
from
(
select ISSUEID,ANSWER, ANSWERCOMMENT,QUESTION ,QUESTIONID
from issue_survey
WHERE ISSUEID = 6877
) d
pivot
(
max(QUESTION)
for QUESTIONID in (1 QUESTION1,2 QUESTION2, 3 QUESTION3)
) piv;
The Results I am getting with this flawed query:
Any suggestions with this are appreciated. Thank you!

Try:
select *
from
(
select ISSUEID,ANSWER, ANSWERCOMMENT,QUESTION ,
rownum rn
from issue_survey
WHERE ISSUEID = 6877
) d
pivot
(
max(QUESTION) as question, max(Answer) as answer,
max( ANSWERCOMMENT ) as ANSWERCOMMENT
for rn in ( 1 ,2 , 3 )
) piv;
Demo: http://www.sqlfiddle.com/#!4/e5aba7/6
| ISSUEID | 1_QUESTION | 1_ANSWER | 1_ANSWERCOMMENT | 2_QUESTION | 2_ANSWER | 2_ANSWERCOMMENT | 3_QUESTION | 3_ANSWER | 3_ANSWERCOMMENT |
|---------|-------------------|----------|-----------------|--------------|----------|-----------------|-----------------|----------|-----------------|
| 6877 | Do you wanna wait | YES | TEST1 | How about it | Its okay | TEST2 | Sample question | (null) | TEST3

Related

Pivoting table throws error: "only simple column names allowed here"

I have a dataset, example:
Master table:
x------x----------x-----------------x-----------x--------x
| Chasisnumber | Messagename | PaintML | Result
x------x--------------------x-------x-----------x--------x
| A123 | Message1 | 10 | OK
| A123 | Message2 | 70 | NOK
B123 | Message1 | 10 | OK
B123 | Message2 | 50 | OK
x------x--------------------x-------x-----------x--------x
I want to get:
Chasisnumber, PaintML-Message1 ,Result-Message1,PaintML-Message2,Result-Message2
| A123 | 10 | OK | 70 | NOK
B123 | 10 | OK | 50 | OK
This can be done with pivot. Can someone help me out?
Example:
select *
from
(Select chasis, message, paint, result
from paint_b) src
pivot
(
src.Paint, src.result for src.MessageName in
('Message1',
'Message2')
) piv;
Like i mentioned, a cross tab seems like a better idea:
--Sample Data
WITH VTE AS(
SELECT V.Chasisnumber,
V.Messagename,
V.PaintML,
V.Result
FROM (VALUES('A123','Message1',10,'OK'),
('A123','Message2',70,'NOK'),
('B123','Message1',10,'OK'),
('B123','Message2',50,'OK')) V(Chasisnumber,Messagename,PaintML,Result))
--Solution
SELECT V.Chasisnumber,
MAX(CASE V.Messagename WHEN 'Message1' THEN V.PaintML END) AS PaintML1,
MAX(CASE V.Messagename WHEN 'Message2' THEN V.PaintML END) AS PaintML2,
MAX(CASE V.Messagename WHEN 'Message1' THEN V.Result END) AS Result1,
MAX(CASE V.Messagename WHEN 'Message2' THEN V.Result END) AS Result2
FROM VTE V
GROUP BY V.Chasisnumber;
The following query should do what you want:
create table #tmp (Chasisnumber VARCHAR(10),Messagename VARCHAR(25), PaintML INT,Result VARCHAR(10))
insert into #tmp values
('A123','Message1',10,'OK'),
('A123','Message2',70,'NOK'),
('B123','Message1',10,'OK'),
('B123','Message2',50,'OK')
select * from (
select Chasisnumber, unpiv.val, unpiv.col+'-'+unpiv.Messagename as col
from (select Chasisnumber,Messagename,cast(PaintML as varchar(10)) PaintML,Result from #tmp) tmp
unpivot (val for col in (PaintML,Result)) unpiv )a
pivot (max(val) for col in ([PaintML-Message1],[Result-Message1],[PaintML-Message2],[Result-Message2])) piv

Combine two rows in single column with same Id

This is currently how I return values. but I want to combine rows that have the same Id's. I tried using the unpivot but I couldn't get it to work.
here's my query:
SELECT * FROM
(
SELECT
ID,
Setup,
Message
FROM myViewHere
)
AS tempTable
UNPIVOT
(
[Message]
FOR Test
IN (ID, Setup)
) AS PVT
This is the result of myViewHere
|ID | Setup | Message |
|---|--------|----------|
| 1 | Header | myHeader |
|---|--------|----------|
| 1 | Footer | myFooter |
What I want to achieve:
|ID | Header | Footer |
|---|----------|----------|
| 1 | myHeader | myFooter |
|---|----------|----------|
Typical pivot case https://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
Assumed table name is "source"
SELECT ID, [Header], [Footer]
FROM source
PIVOT
( max(Message) FOR Setup IN ([Header], [Footer])) p;
See test on sqlfeedle http://sqlfiddle.com/#!6/7635f/7
you can change your view query to be like below
SELECT * FROM
(
SELECT
ID,
Setup,
Message
FROM myViewHere
)
AS tempTable
UNPIVOT
(
[Message]
FOR Test
IN (ID, Setup)
) AS UNPVT
PIVOT
(
MAX([Message])
FOR [Setup]
IN ([Header], [Footer])
)PVT

transform rows into one row based on unique ID

Reason | ID
---------------------------------------
Sales - Agent Attitude | 2
---------------------------------------
Billing - Process | 2
---------------------------------------
Technical - Outages | 1005
---------------------------------------
Technical - knowledge | 1005
---------------------------------------
Others | 1005
---------------------------------------
i have the above table and i want a result like the below by using SQL server i can combine rows into one row by separating them by , by using STUFF() function but i want the format as the below so any help
ID | Reason 1 | Reason 2 | Reason 3
---------------------------------------------------------------------
2 | Sales - Agent Attitude | Billing - Process | NULL
---------------------------------------------------------------------
1005 | Technical - Outages | Technical - knowledge |Others
---------------------------------------------------------------------
Try below query..
select distinct
ID , [1] as 'Reason 1' , [2] as 'Reason 2' , [3] as 'Reason 3'
from
(
select *, ROW_NUMBER() OVER ( PARTITION BY id ORDER BY reason DESC ) as RID from #temp
) src
pivot
(
max(Reason)
for rid in ([1], [2],[3])
) piv
plz let us know if you have any que. or concerns
This is the pivot solution:
;with
t as (
SELECT 'Reason ' + cast(ROW_NUMBER() over (partition by id order by id) as varchar(2)) n, *
from YourTable
)
select *
FROM t
pivot (min(reason) for n in ([Reason 1],[Reason 2],[Reason 3],[Reason 4],[Reason 5])) p

SQL Pivot for multiple columns [duplicate]

This question already has answers here:
SQL Server Pivot Table with multiple column aggregates
(3 answers)
Closed 7 years ago.
I have the below table 'EmpTemp':
Name | Category | Value1 | Value 2
John | Cat1 | 11 | 33
John | Cat2 | 22 | 44
I would like to have the below output for the table:
Name | Cat1_Value1 | Cat2_Value1 | Cat1_Value2 | Cat2_Value2
John | 11 | 11 | 33 | 44
I guess this give a basic idea of what kind of transformation i'm expecting. I have tried the below query that gives me a partial solution:
SELECT
Name,
Cat1 AS 'Cat1_Value1',
Cat2 AS 'Cat2_Value1',
FROM EmpTemp AS T
PIVOT
(
MAX(Value1)
FOR Category IN (Cat1, Cat2)
) AS PVT
The above query gives me the following result:
Name | Cat1_Value1 | Cat2_Value1
John | 11 | 11
I am stuck how can I extend this pivot query. Any help is appreciated in advance.
Here is a way to do it using Pivot.
First you need to unpivot the data then do the pivot
;with cte as
(
select name,val,col_name from yourtable
cross apply (values
(value1,Category+'value1'),
(value2,Category+'value2')
) cs(val,col_name)
)
select * from cte
pivot(max(val) for col_name in([Cat1value1],
[Cat1value2],
[Cat2value1],
[Cat2value2]
)) p
Here is a simple way of doing it without using the pivot syntax:
select name,
max(case when category = 'Cat1' then value1 end) as cat1_value1,
max(case when category = 'Cat2' then value1 end) as cat2_value1,
max(case when category = 'Cat1' then value2 end) as cat1_value2,
max(case when category = 'Cat2' then value2 end) as cat2_value2
from EmpTemp
group by name

How to transform rows into column? [duplicate]

This question already has answers here:
Convert Rows to columns using 'Pivot' in SQL Server
(9 answers)
Closed 7 years ago.
I have a table like this and there are only two feature for all user in this table
+-------+---------+-----------+----------+
| User | Feature | StartDate | EndDate |
+-------+---------+-----------+----------+
| Peter | F1 | 2015/1/1 | 2015/2/1 |
| Peter | F2 | 2015/3/1 | 2015/4/1 |
| John | F1 | 2015/5/1 | 2015/6/1 |
| John | F2 | 2015/7/1 | 2015/8/1 |
+-------+---------+-----------+----------+
I want to transform to
+-------+--------------+------------+--------------+------------+
| User | F1_StartDate | F1_EndDate | F2_StartDate | F2_EndDate |
+-------+--------------+------------+--------------+------------+
| Peter | 2015/1/1 | 2015/2/1 | 2015/3/1 | 2015/4/1 |
| John | 2015/5/1 | 2015/6/1 | 2015/7/1 | 2015/8/1 |
+-------+--------------+------------+--------------+------------+
If you are using SQL Server 2005 or up by any chance, PIVOT is what you are looking for.
The best general way to perform this sort of operation is a simple group by statement. This should work across all major ODBMS:
select user,
max(case when feature='F1' then StartDate else null end) F1_StartDate,
max(case when feature='F1' then EndDate else null end) F1_EndDate,
max(case when feature='F2' then StartDate else null end) F2_StartDate,
max(case when feature='F2' then EndDate else null end) F2_EndDate
from table
group by user
Note: as mentioned in the comments, this is often bad practice, as depending on your needs, it can make the data harder to work with. However, there are cases where it makes sense, when you have a small, limited number of values.
This is a bit of a hack with a CTE:
;WITH CTE AS (
SELECT [User], [Feature] + '_StartDate' AS [Type], StartDate AS [Date]
FROM Table1
UNION ALL
SELECT [User], [Feature] + '_EndDate' AS [Type], EndDate AS [Date]
FROM Table1)
SELECT * FROM CTE
PIVOT(MAX([Date]) FOR [Type] IN ([F1_StartDate],[F2_StartDate], [F1_EndDate], [F2_EndDate])) PIV
Use UNPIVOT & PIVOT like this:
Test data:
DECLARE #t table
(User1 varchar(20),Feature char(2),StartDate date,EndDate date)
INSERT #t values
('Pete','F1','2015/1/1 ','2015/2/1'),
('Pete','F2','2015/3/1 ','2015/4/1'),
('John','F1','2015/5/1 ','2015/6/1'),
('John','F2','2015/7/1 ','2015/8/1')
Query:
;WITH CTE AS
(
SELECT User1, date1, Feature + '_' + Seq cat
FROM #t as p
UNPIVOT
(date1 FOR Seq IN
([StartDate], [EndDate]) ) AS unpvt
)
SELECT * FROM CTE
PIVOT
(MIN(date1)
FOR cat
IN ([F1_StartDate],[F1_EndDate],[F2_StartDate],[F2_EndDate])
) as p
Result:
User1 F1_StartDate F1_EndDate F2_StartDate F2_EndDate
John 2015-05-01 2015-06-01 2015-07-01 2015-08-01
Pete 2015-01-01 2015-02-01 2015-03-01 2015-04-01