How do I pivot query using UNION ALL - sql

I have following table structure & below is the Query i am executing :-
Following are the tables :-
First Table :-
Second Table :-
SELECT Code, Fname, OTHINC1, OTHINC2
FROM (SELECT a.FieldName
,a.YearlyValue
,b.Code
,b.Fname
FROM [TaxOtherIncome] AS a
INNER JOIN [EmployeeDetail] AS b
ON a.EmployeeId = b.Id
WHERE a.EntryDate = '2014-12-01') x
PIVOT (MAX(YearlyValue) FOR FieldName IN (OTHINC1,OTHINC2)) p
Result i am getting :-
I also want Records from the Second table i mentioned above. So In my final Result Columns SUBFLD36
SUBFLD37 & House_Rent will be added.
As i am new to Pivot, Help me to modify above query to get expected results.

Consider you are inserting the result after your join to a temporary table which is the below
Declare a variable for getting the columns to pivot
DECLARE #cols NVARCHAR (MAX)
SELECT #cols = COALESCE (#cols + ',[' + [FIELD NAME] + ']',
'[' + [FIELD NAME] + ']')
FROM (SELECT DISTINCT [FIELD NAME] FROM #TEMP) PV
ORDER BY [FIELD NAME]
Now pivot it
DECLARE #query NVARCHAR(MAX)
SET #query = '
SELECT * FROM
(
SELECT * FROM #TEMP
) x
PIVOT
(
MAX([YEARLY VALUE])
FOR [FIELD NAME] IN (' + #cols + ')
) p
'
EXEC SP_EXECUTESQL #query
Click here to view the result
RESULT

You can try this:
SELECT Code, Fname, OTHINC1, OTHINC2, SUBFLD36, SUBFLD37, House_Rent
FROM (SELECT a.FieldName
,a.YearlyValue
,b.Code
,b.Fname
FROM [TaxOtherIncome] AS a
INNER JOIN [EmployeeDetail] AS b
ON a.EmployeeId = b.Id
WHERE a.EntryDate = '2014-12-01'
UNION
SELECT a.FieldName
,a.FieldValue AS YearlyValue
,a.EmployeeCode AS Code
,b.Fname
FROM SecondTable AS a
INNER JOIN [EmployeeDetail] AS b
ON a.EmployeeId = b.Id
WHERE EntryDate = '2014-12-01') x
PIVOT (MAX(YearlyValue) FOR FieldName IN (OTHINC1, OTHINC2, SUBFLD36, SUBFLD37, House_Rent)) p

Related

Pivot SQL with top 1

I have a simple table, with scan data in rows.
I want to pivot the dataset, with the first scan in each phase_key.
Into this:
I use this sql:
select
d.shipment_id,
d.carrier_reference,
e.phase_key,
e.event,
CONVERT(DATETIME,e.time) AS ScanDate
from
data d
inner join event e on d.id = e.data_id
where
shipment_id = '99156136'
order by e.time asc
I have tried using the suggested sql. (adding 1 id, to verify format. But it loads without the code suggested from #gotqn.
DECLARE #DynammicTSQLStatement NVARCHAR(MAX)
,#DynamicPIVOTColumns NVARCHAR(MAX);
SELECT #DynamicPIVOTColumns = STRING_AGG(CAST(QUOTENAME([phase_key]) AS VARCHAR(MAX)), ',') WITHIN GROUP (ORDER BY [phase_key])
FROM
(
SELECT DISTINCT [phase_key]
FROM data d
inner join event e on d.id = e.data_id
) DS ([phase_key]);
SET #DynammicTSQLStatement = N'
SELECT *
FROM
(
SELECT shipment_id
,phase_key
,time
FROM data d
inner join event e on d.id = e.data_id
where
shipment_id = "99156136"
) DS
PIVOT
(
MAX([time]) FOR [phase_key] IN (' + #DynamicPIVOTColumns + ')
) PVT';
EXEC sp_executesql #DynammicTSQLStatement;
But after 2mins it still have not loaded the 1. id om trying as a sample.
Try this:
DECLARE #DynammicTSQLStatement NVARCHAR(MAX)
,#DynamicPIVOTColumns NVARCHAR(MAX);
SELECT #DynamicPIVOTColumns = STRING_AGG(CAST(QUOTENAME([phase_key]) AS VARCHAR(MAX)), ',') WITHIN GROUP (ORDER BY [phase_key])
FROM
(
SELECT DISTINCT [phase_key]
FROM [my_table]
) DS ([phase_key]);
SET #DynammicTSQLStatement = N'
SELECT *
FROM
(
SELECT shipment_id
,phase_key
,ScanDate
FROM [my_table]
) DS
PIVOT
(
MAX([ScanDate]) FOR [phase_key] IN (' + #DynamicPIVOTColumns + ')
) PVT';
EXEC sp_executesql #DynammicTSQLStatement;

SQL - SUM the values from a COLUMN and put each value in a SEPARATE column

I have a simple join query for multiple tables that looks like this:
select
b.buyer_id,
v.vendor_id,
r.report_number,
sum(r.amount_fee),
f.fee_description
from buyer b
join vendor v on v.vendor_id = bu.vendor_id
join report r on r.report_num = bu.report_num
join fees f on f.report_num = r.report_num
group by b.buyer_id, v.vendor_id, r.report_number, f.fee_description
Which will show something like this:
But I want it to look like this:
Can you help me how to rewrite my script please?
Thanks alot!
If your fee descriptions are fixed, a simple PIVOT query will do the trick.
SELECT
buyer_id,
vendor_id,
report_number,
[Late Charge],
[Finance Charge],
[Reserve Fee],
[Additional Fee]
FROM
(
select b.buyer_id, v.vendor_id, r.report_number, r.amount_fee As AmountFee, f.fee_description
from buyer b
join vendor v on v.vendor_id = bu.vendor_id
join report r on r.report_num = bu.report_num
join fees f on f.report_num = r.report_num
) As s
PIVOT
(
Sum(AmountFee) FOR fee_description IN ([Late Charge], [Finance Charge], [Reserve Fee], [Additional Fee])
) As P
If the fee descriptions could change, you'll need a dynamic pivot query:
DECLARE #columns nvarchar(max);
SET #columns = STUFF
(
(SELECT DISTINCT N',' + QUOTENAME(fee_description)
FROM fees
ORDER BY fee_description
FOR XML PATH(''), TYPE)
.value('.', 'nvarchar(max)'),
1, 1, N''
);
DECLARE #sql nvarchar(max);
SET #sql = N'SELECT buyer_id, vendor_id, report_number, ' + #columns + N'
FROM
(
select b.buyer_id, v.vendor_id, r.report_number, r.amount_fee As AmountFee, f.fee_description
from buyer b
join vendor v on v.vendor_id = bu.vendor_id
join report r on r.report_num = bu.report_num
join fees f on f.report_num = r.report_num
) As s
PIVOT
(
Sum(AmountFee) FOR fee_description IN (' + #columns + N')
) As P';
EXEC sp_executesql #sql;

Show value of particular column as Header in SQL Server

I am creating a web app in which I have a requirement where I want to display a column value as a header
Example
SELECT Name, Leave
FROM tblUser
INNER JOIN tblLeaveMaster ON tblUser.EmployeeID = tblLeaveMaster.EmployeeID
From that query, I get these results:
Name Leave
---------------
Test1 5
Test2 10
test3 2
Now I want to get these values as
Test1 Test2 Test3
-----------------
5 10 2
How can I achieve this?
You can try using pivot
select pv.* from
(SELECT Name,Leave
FROM tblUser INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
)X
pivot
(max(leave) for name in ([Test1],[Test2],[Test3])) as pv
For Dynamic PIVOT
declare #sql varchar(max)='',#col_list varchar(8000)=''
set #col_list = (select distinct quotename([Name])+',' from (SELECT Name,Leave
FROM tblUser INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
)X
for xml path(''))
set #col_list = left (#col_list,len(#col_list)-1)
set #sql = 'select '+#col_list+' from
(SELECT Name,Leave
FROM tblUser INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
)X
pivot (max([Leave]) for [Name] in ('+#col_list+'))pv'
exec(#sql)
try by using case when
select max( case when name='Test1' then Leave end) as test1,
max( case when name='Test2' then Leave end) as test2,
max( case when name='Test3' then Leave end) as test3 from
tblUser INNER JOIN tblLeaveMaster
ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
You can try to use condition aggregate function. CASE WHEN with MAX or MIN
SELECT
MAX(CASE WHEN Name = 'Test1' THEN Leave END) Test1,
MAX(CASE WHEN Name = 'Test2' THEN Leave END) Test2,
MAX(CASE WHEN Name = 'Test3' THEN Leave END) Test3
FROM tblUser
INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
EDIT
If your column want to create dynamic you can try to use Dynamic PIVOT
create your SQL statement and make condition aggregate function by connect SQL string. then use execute it Dynamically.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ', MAX(CASE WHEN Name = ''' + Name+''' THEN Leave END) ' + QUOTENAME(Name)
FROM tblUser
INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #query= 'SELECT '+ #cols+'
FROM tblUser
INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID'
execute(#query)
sqlfiddle
You can find your result from the query as shown below. Here I have taken your query output in a temporary table.
Create table #finalData(ColName Varchar(30), Leave INT)
INSERT INTO #finalData Values('Test1', 5),('Test2', 10),('Test3', 2)
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.ColName)
FROM #finalData c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT ' + #cols + ' from
(
select ColName
, Leave
from #finalData
) x
pivot
(
max(Leave)
for ColName in (' + #cols + ')
) p '
execute(#query)
DROP TABLE #finalData
Hope this will help you.
The output is as shown below
Test1 Test2 Test3
5 10 2
select pv.* from
(SELECT Name,Leave
FROM tblUser INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
)X
pivot
(max(leave) for name in ([Test1],[Test2],[Test3])) as pv
Note:- this work for me but how to use where condition base on dropdown list selected value.
eg: if wants to show only 2020 and not 2019.

SQL Server query result by column to row

This is my sample code:
SQL Fiddle
I need it to result like this:
category outlet1 outlet2 outlet3
Sale 70 20 40
Expense 250 130 200
How can I do this?
EDIT: My outlets are not fixed, sorry for not telling this beforehand.
You can solve your particular problem using conditional aggregation:
SELECT c.category,
SUM(CASE WHEN o.outletname = 'Outlet1' THEN t.amt ELSE 0 END) as Outlet1,
SUM(CASE WHEN o.outletname = 'Outlet2' THEN t.amt ELSE 0 END) as Outlet2,
SUM(CASE WHEN o.outletname = 'Outlet3' THEN t.amt ELSE 0 END) as Outlet3
FROM tblcategory c INNER JOIN
tbltran t
ON t.catid = c.id INNER JOIN
tbloutlet o
ON o.id = t.outletid
GROUP BY c.category;
If the outlet names are not fixed, then you need dynamic SQL. The problem cannot be solve using a single SELECT query.
Here with dynamic Outlets http://sqlfiddle.com/#!18/a7b09/25
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT ',' + QUOTENAME(outletname)
from tbloutlet
group by outletname
order by outletname
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT category,' + #cols + ' from
(
SELECT c.category, o.outletname, SUM(t.amt) as amt
FROM tblcategory c
INNER JOIN tbltran t ON t.catid = c.id
INNER JOIN tbloutlet o ON o.id = t.outletid
GROUP BY c.category, o.outletname
) x
pivot
(
sum(amt)
for outletname in (' + #cols + ')
) p '
execute(#query);
you may also use the PIVOT operator
SELECT *
FROM
(
SELECT category, outletname, amt
FROM tblcategory c
INNER JOIN tbltran t ON t.catid = c.id
INNER JOIN tbloutlet o ON o.id = t.outletid
) d
PIVOT
(
SUM(amt)
FOR outletname in ([Outlet1] , [Outlet2] , [Outlet3])
) p
EDIT : below is the Dynamic SQL version
declare #Outlets nvarchar(max),
#SQL nvarchar(max)
select #Outlets = isnull(#Outlets + ',', '') + quotename(outlet)
from outlet
select #SQL = '
SELECT *
FROM
(
SELECT category, outletname, amt
FROM tblcategory c
INNER JOIN tbltran t ON t.catid = c.id
INNER JOIN tbloutlet o ON o.id = t.outletid
) d
PIVOT
(
SUM(amt)
FOR outletname in (' + #Outlets + ')
) p'
print #SQL -- print out for verification
exec sp_executesql #SQL

Can I pivot dynamic table with no group by in SQL Server

This is my data in table (left join from field table and value table)
This is my expected result table after use pivot function
Thanks for help ^___^
I suggest you to use dynamic SQL as fieldnames number may very in future:
DECLARE #columns nvarchar(max),
#sql nvarchar(max)
SELECT #columns = COALESCE(#columns,'') + ',' + QUOTENAME(c.fieldname)
FROM [Columns] c
ORDER BY c.cid
SELECT #sql = N'
SELECT *
FROM (
SELECT v.[row],
c.fieldname,
v.fieldvalue
FROM [Values] v
INNER JOIN [Columns] c
ON v.cid = c.cid
) t
PIVOT (
MAX(fieldvalue) FOR fieldname IN ('+STUFF(#columns,1,1,'')+')
) pvt'
EXEC sp_executesql #sql
Will output:
row FirstName LastName Email Phone
1 Arnun Saelim Arnun.s#outlook.com 0922743838
2 Micheal Saelim Micheal#gmail.com 0886195353
I'm not sure why group by got into your mind, but here is a working example of what you are trying to achieve.
select * into #temp from
( values
(1,'A','AV'),
(1,'B','BV'),
(1,'C','CV'),
(2,'A','AV'),
(2,'B','BV'),
(2,'C','CV'))
as t(row, FieldName, FieldValue)
select *
from #temp
PIVOT
(MAX(FieldValue) FOR FieldName in ([A],[B],[C])) as pvt
Does that work for you?