I have data set as below:
And I need to transpose data like (I use Excel transpose):
How to do that in SQL Server with PIVOT or UNPIVOT relational operators? I have tried, but no success.
Thanks
Since we do not have any real DDL statements from you, maybe you can try out this fiddle here or see the query below.
The below query uses unpivoting followed by pivoting to get the job done.
select * from
(select * from Temp
)s
unpivot
(datavalues for cols in ([2],[2],[3],[4],[5]))u
pivot
(sum(datavalues) for [programType] in ([hp],[load]))p
alternately you can also use group with case to get same output like
select
cols, sum(case when programType ='hp' then datavalues end) as [hp],
sum(case when programType ='load' then datavalues end) as [load]
from
(select * from Temp
)s
unpivot
(datavalues for cols in ([1],[2],[3],[4],[5]))u
group by cols
Related
I have a query which generates result set such as below image :
And i want a result set like this
Along with the below pivoted columns
I have used the below query for pivot
select distinct
ptbl.PdaId,
ptbl.BusinessUnitName,
ptbl.SalesAreaName,
ptbl.regionName,
ptbl.territoryName,
ptbl.ResponseType,
[11-04-2016],
[11-17-2016],
[11-18-2016],
[11-20-2016]
from
(select
#data.PdaId,
#data.UserName,
#data.BusinessUnitName,
#data.SalesAreaName,
#data.regionName,
#data.territoryName,
#data.ResponseType,
#data.TOTAL [TOTAL],
#data.TOTAL [DateBreakUpTOTAL],
MyTable.InterviewedDate
from
#data
join #InProgressResponses
on #InProgressResponses.PdaId=#data.PdaId
left join MyTable
on MyTable.PdaId=#data.PdaId
) tbl1
pivot
(
sum([DateBreakUpTOTAL])
for InterviewedDate in ([11-04-2016], [11-17-2016], [11-18-2016], [11-20-2016])
) ptbl
but the break up data is null instead of dividing the above total count into their respective dates.
Assume #data has the dataset that i have depicted in first image.
and MyTable has the dates that i have mentioned in the pivot.
What is wrong with my query?
I have a table with 12 columns.
I need a query for computing COUNT(*) and selecting all the columns.
I mean I want to have these two queries just in one query:
select *
from mytable
where OneOfTheColumns = something;
select COUNT(*)
from mytable
where OneOfTheColumns = something;
Conditions and tables are the same.
Can I do this?
Thanks a million.
You can use a window function for that
select *,
count(*) over () as total_count
from mytable
where OneOfTheFields = something;
Can someone help out with calculating a total row at the bottom of this PIVOT table please?
select *, [Drug1] + [Drug2] + [Drug3] + [Drug4] + [Drug5] as [Total]
from
(Select [id], [drug], [Diagnosis]
from DrugDiagnosis
) as ptp
pivot
(count(id)
for drug
in ([Drug1], [Drug2], [Drug3], [Drug4], [Drug5])
) as PivotTable
I know I can do it with a UNION and have a separate query to calc the totals, but that will double the hit on the database.
I have found examples using ROLLUP and CUBE, but these are deprecated features so I don't want to use them.
Any other ideas, GROUPING SETS maybe?
You can use GROUPING SETS to get the totals row:
select isnull(diagnosis, 'Total') Diagnosis,
sum([Drug1]) Drug1, sum([Drug2]) Drug2,
sum([Drug3]) Drug3, sum([Drug4]) Drug4,
sum([Drug5]) Drug5,
sum([Drug1] + [Drug2] + [Drug3] + [Drug4] + [Drug5]) as [Total]
from
(
Select [id], [drug], [Diagnosis]
from DrugDiagnosis
) as ptp
pivot
(
count(id)
for drug in ([Drug1], [Drug2], [Drug3], [Drug4], [Drug5])
) as PivotTable
group by grouping sets((diagnosis), ());
See SQL Fiddle with Demo
I'm using this query to return the distribution of a float field around its average:
SELECT COUNT(*) AS [Count], Result FROM (
SELECT ROUND(Result - AVG(Result) OVER(), 1) Result FROM Results)
GROUP BY Result
This query returns the distance between all records and the mean. Now, I need to filter the records which are out of the ±3SD range. I thought perhaps I could easily achieve this by changing my query to this:
SELECT COUNT(*) AS [Count], Result FROM (
SELECT ROUND(Result - AVG(Result) OVER(), 1) Result FROM Results
HAVING Abs(Result - AVG(Result)) OVER() < 3 * STDEV(Result) OVER())
GROUP BY Result
But SQL Server is giving me two errors:
Column 'Results.Result' is invalid in the HAVING clause because it is
not contained in either an aggregate function or the GROUP BY clause.
Windowed functions can only appear in the SELECT or ORDER BY clauses.
How can I achieve what I'm looking for? Google isn't kind to me today :-(
As the second error message indicated, windowed functions can only appear in the SELECT or ORDER BY clauses - so rather than including them in the HAVING clause, include them in the inner SELECT and then select on them in the outer WHERE clause - like so:
SELECT COUNT(*) AS [Count], Result FROM
(SELECT ROUND(Result - AVG(Result) OVER(), 1) Result,
Abs(Result - AVG(Result) OVER()) avgdiff,
STDEV(Result) OVER() stddev
FROM Results) r
WHERE avgdiff < 3 * stddev
GROUP BY Result
I'm having a bit of an issue with some derived tables that I hope someone will be able to help with. What I've got is 2 derived tables inside a select statement that then uses a pivot to display the results horizontally rather than vertically.
What I've got so far is:
SELECT * FROM(
SELECT SUM(Value) AS TotDays, ClassId FROM MainTable GROUP BY ClassId)
Union All
SELECT SUM(NumDays) As TotDays, ClassId FROM (
SELECT CASE WHEN COUNT(SiteId) > 0 THEN 1 ELSE 0 END AS NumDays
FROM Table2 GROUP BY ClassId ) as SUB
) AS a
PIVOT (SUM(TotDays) FROM ClassId
IN ([12],[13],[14],[15]
What I'm trying to do is reference the individual columns rather than using SELECT *, but I don't know how to do it. I can make it work without if I drop everything from the union onwards, but when I put the union in it doesn't work and I have to use SELECT *.
Anyone got any ideas on what's going wrong?
Thanks
Alex
You have a couple of errors on your query. For example, your UNION ALL has sets with a different number of columns, and you have other syntax errors. Try this way:
SELECT [12],[13],[14],[15]
FROM ( SELECT SUM(Value) AS TotDays, ClassId
FROM MainTable
GROUP BY ClassId
UNION ALL
SELECT SUM(NumDays) As TotDays, ClassId
FROM ( SELECT CASE WHEN COUNT(SiteId) > 0 THEN 1 ELSE 0 END NumDays,
ClassId
FROM Table2
GROUP BY ClassId) as SUB
) AS a
PIVOT (SUM(TotDays) FROM ClassId IN ([12],[13],[14],[15])) AS PT