I have found many answers to this question, but all of them leave me stymied as to actually making it work. Apparently, I am just being dense today. Can someone just give me the code to make this work?
My T-SQL query returns the following rows:
Before
I need to transpose the rows and columns:
Like this
unpivot —> pivot
select p.*
from
(
--My T-SQL query returns the following rows:
select *
from
(
values
('A',1,2,3,4,5,6,7,8),('B',10,20,30,40,50,60,70,80),
('C',100,200,300,400,500,600,700,800), ('I',11,22,33,0,0,0,0,88)
) as t(product_code,week_1,week_2,week_3,week_4,week_5,week_6,week_7,week_8)
) as s
unpivot
(
thevalue for weekno in (week_1,week_2,week_3,week_4,week_5,week_6,week_7,week_8)
) as u
pivot
(
max(thevalue) for product_code in (A,B,C,D,E,F,G,H,I,J)
) as p;
Related
I use Azure SQL database. I have a table - test_excel_poc_head with the below values which I want to transpose using link id values as the columns
The intended output is below where the column is the 'link_id' values. The link_id values are dynamic
I started using UNPIVOT and PIVOT option and below is my unpivot query and results:
SELECT link_id,head_values
FROM
(SELECT link_id,comp1,comp2,comp3,comp4
FROM [dbo].[test_excel_poc_head]
) AS cp
UNPIVOT
(head_values FOR head_value in (comp1,comp2,comp3,comp4)
) AS up
RESULTS:
Now when I add the PIVOT code, it expects an aggregate function which I do not have as it is a string and it errors out.
If I add MAX as the aggregate function, I do not get the intended result.
SELECT * FROM (
SELECT link_id,head_values
FROM
(SELECT link_id,comp1,comp2,comp3,comp4
FROM [dbo].[test_excel_poc_head]
) AS cp
UNPIVOT
(head_values FOR head_value in (comp1,comp2,comp3,comp4)
) AS up
) temp_results
PIVOT(
MAX(head_values)
FOR link_id
IN (
[1],[2],[3],[4],[5],[6]
)
) AS PivotTable
RESULT:
But this is not my expected result. Is there any other option to achieve PIVOT without the use of agg functions?
Thanks for your time and help.
I tried my luck. Could you check below query if it works,
What I did different to your query is making the result of UNPIVOT distinct by adding row_number to it so that the later PIVOT will take max of each row and display separately. My bad if the explanation doesn't makes sense to you.
select [1],[2],[3],[4],[5],[6]
from
( select link_id,head_values,
row_number() over (partition by link_id order by link_id) rn
from
( select link_id
,cast(comp1 as varchar(255)) as comp1
,cast(comp2 as varchar(255)) as comp2
,cast(comp3 as varchar(255)) as comp3
,cast(comp4 as varchar(255)) as comp4
from [dbo].[test_excel_poc_head]
) as cp
unpivot
(
head_values for head_value in (comp1,comp2,comp3,comp4)
) as up
) temp_results
pivot
(
max(head_values)
for link_id in ([1],[2],[3],[4],[5],[6])
) as pivottable;
db<>fiddle for your reference.
I have a table with 3 columns. in which i am showing Time wise report of ContainerCount with Time.
Below image shows the actual table
I am doing pivot for this table and the image is shown below
now i want to add all columns and want to shown in single column. But not getting. The query is mentioned below
SELECT 'CFS to Zero' Location, sum( [0]+[1]+[2]+[3]) FROM
(SELECT [ContainerCount],Time FROM #tt )as Tab1
PIVOT
(
MAX([ContainerCount]) FOR Time IN ([0])) AS Tab2 ;
use coalesce()
SELECT 'CFS to Zero' Location, coalesce([0],0)+coalesce([1],0)+coalesce([2],0)+coalesce([3],0) FROM
(SELECT [ContainerCount],Time FROM #tt )as Tab1
PIVOT
(
MAX([ContainerCount]) FOR Time IN ([0],[1],[2],[3])) AS Tab2
If you only need 1 SUM then you don't really need a PIVOT.
Just aggregate and get the MAX values, then SUM them.
This has the benefit that you can just use a BETWEEN to only select a range of Time.
Instead of having to hardcode the Time values in a PIVOT.
SELECT
'CFS to Zero' AS Location,
SUM(MaxContainerCount) AS TotalMaxContainerCount
FROM
(
SELECT
[Time],
MAX(ContainerCount) AS MaxContainerCount
FROM #tt
WHERE [Time] BETWEEN 0 AND 3
GROUP BY [Time]
) q
i'm trying to learn using SQL to generate pivot table. But no matter how i try i keep getting ORA-00936: missing expression error from oracle.
Here is my query:
SELECT * FROM (SELECT HOS_PAY_ID, AMOUNT FROM HOSPITAL_PAYMENT)
PIVOT (SUM (AMOUNT) FOR AMOUNT IN ([10000],[8000],[7000],[9000],[11000],[13000]) AS TEST
ORDER BY HOS_PAY_ID;
and this is my data:
Thank You.
Try this
SELECT * FROM
(
SELECT HOS_PAY_ID, AMOUNT
FROM HOSPITAL_PAYMENT
)
PIVOT (
SUM (AMOUNT) FOR AMOUNT IN (10000,8000,7000,9000,11000,13000)
)
ORDER BY HOS_PAY_ID;
http://postimage.org/delete/pwnan1ud4/
there are repetitive rows (column Name : aracId) in the picture as linked above. How can i modify query for the unique row.
Since your image is not viewable, try adding DISTINCT in your SELECT clause. Example,
SELECT DISTINCT *
FROM tableName
Try this :
With Cte as
(
Select row_number() over (partition by arac.aracID order by arac.aracID ) as row
-- other columns
left join ...
Where .... and
tip.tipadi in ('Kamyon','Kamyonet','Tir')
)
Select cte.aracID, cte.Model, ..........
from cte where cte.row=1
I am creating an SP which gives some result by applying distinct on it, now I want to implement sever side paging, so I tried using Row_number on distinct result like:
WITH CTE AS
(
SELECT ROW_NUMBER() OVER(ORDER BY tblA.TeamName DESC)
as Row,tblA.TeamId,tblA.TeamName,tblA.CompId,tblA.CompName,tblA.Title,tblA.Thumbnail,tblA.Rank,tblA.CountryId,tblA.CountryName
FROM
(
--The table query starts with SELECT
)tblA
)
SELECT CTE.* FROM CTE
WHERE CTE.Row BETWEEN #StartRowIndex AND #StartRowIndex+#NumRows-1
ORDER BY CTE.CountryName
but rows are first assigned RowNumber then distinct get applied that is why I am getting duplicate values, how to get distinct rows first then get row numbers for the same.
Any solution on this? Am I missing something?
need answer ASAP.
thanks in advance!
Don't you need to add "partition by" to your ROW_NUMBER statement?
ROW_NUMBER() OVER(Partition by ___, ___, ORDER BY tblA.TeamName DESC)
In the blank spaces, place the column names you would like to create a new row number for. Duplicates will receive a number that is NOT 1 so you might not need the distinct.
To gather the unique values you could write a subquery where the stored procedure only grabs the rows with a 1 in them.
select * from
(
your code
) where row = 1
Hope that helps.
I'm not sure why you're doing this:
WHERE CTE.Row BETWEEN #StartRowIndex AND #StartRowIndex+#NumRows-1