Pivoting on multiple columns - sql

I have the following computed data
Pl_Name Cnt Status Level
CF 21 Active 2
CF 3 Closed 2
INFRA 1 Closed 3
OTHER 40 Active 2
OTHER 4 Active 3
OTHER 2 Closed 1
OTHER 9 Closed 2
OTHER 5 Closed 3
MSG 5 Active 2
The query used for above result was
SELECT Platforms.PlatformName,COUNT(Ticket.TicketId) AS Count,Ticket.TicketStatus,Ticket.Priority
FROM Platforms
INNER JOIN Ticket
ON Platforms.ID = Ticket.Platform_id
GROUP BY Platforms.PlatformName,Ticket.TicketStatus,Ticket.Priority
Now I Need the following result from above result
Level1 Level2 Level3
PL_Name Active Closed Active Closed Active Closed
CF 0 0 21 3 0 0
INFRA 0 0 0 0 0 1
OTHER 0 2 40 5 4 5
MSG 0 0 2 0 0 0

Try this .. You need to use pivot to transpose your rows to columns.
SELECT Pl_Name,
Isnull([Level1_active], 0)[Level1_active],
Isnull([Level1_closed], 0)[Level1_closed],
Isnull([Level2_active], 0)[Level2_active],
Isnull([Level2_closed], 0)[Level2_closed],
Isnull([Level3_active], 0)[Level3_active],
Isnull([Level3_closed], 0)[Level3_closed]
FROM (SELECT Pl_Name,
cnt,
'Level' + CONVERT(VARCHAR(50), level) + '_'
+ status piv_col
FROM Computeddata) a
PIVOT (Max(cnt)
FOR piv_col IN([Level1_active],
[Level1_closed],
[Level2_active],
[Level2_closed],
[Level3_active],
[Level3_closed])) piv
Note: Result is some what similar to your result column headers might be same as you expect

Related

How to count how many times a name appear? [duplicate]

This question already has answers here:
How to count number of occurrences for all different values in database column?
(2 answers)
Closed 3 years ago.
I have a table like the following:
ID X Y
5 2 0
5 1 1
5 3 3
4 -2 1
4 0 0
3 5 -3
I would like to count how the records for each ID
ID count
5 3
4 2
3 1
This is pretty much all
SELECT ID, COUNT(*) AS count FROM TABLE GROUP BY ID

SQL Aggregate functions with groupings

I need to create some checks to make sure that students are enrolled in the correct courses with the correct number of units. Here is my SQL at the moment.
SELECT StudentID
,AssessmentCode
,BoardCode
,BoardCategory
,BoardUnits
,sum(cast(boardunits as int)) over (partition by studentid,boardcategory) as UnitCount
,Count(boardcategory) over (partition by studentid) as SubjectCount
FROM uvNCStudentSubjectDetails
where fileyear = 2015
and filesemester = 1
and studentyearlevel = 11
and StudentIBFlag = 0
order by Studentnameinternal,BoardCategory
This gives me the following info...
StudentID AssessmentCode BoardCode BoardCategory BoardUnits UnitCount SubjectCount
61687 11TECDAT 11080 A 2 11 7
61687 11PRS1U 11350 A 1 11 7
61687 11MATGEN 11235 A 2 11 7
61687 11LANGRB 11870 A 2 11 7
61687 11ENGSTD 11130 A 2 11 7
61687 11GEOGEO 11190 A 2 11 7
64549 11TECIND 11200 A 2 10 7
64549 11SCIPHY 11310 A 2 10 7
64549 11SCIEAE 11100 A 2 10 7
64549 11MATGEN 11235 A 2 10 7
64549 11ENGSTD 11130 A 2 10 7
64549 11TECHOS 26501 B 2 2 7
64549 11MUSDRS 63212 C 1 1 7
45461 11ECOECO 11110 A 2 13 7
45461 11ENGADV 11140 A 2 13 7
45461 11HISMOD 11270 A 2 13 7
45461 11HISLST 11220 A 2 13 7
45461 11MATMAT 11240 A 2 13 7
45461 11PRS1U 11350 A 1 13 7
45461 11SCIBIO 11030 A 2 13 7
Note for the first student, I have a count of Category A subject Units (11 in total) He is only doing Category A subjects. For the second student, he has 10 units of Category A subjects, he is doing 1 Category B subject worth 2 units and one category C subject worth 1 unit. the final student just has 13 Category A units.
Now what I would really like is something like this...!
StudentID Sum A Units Sum B Units Sum C Units Sum A Units + Sum B Units Count of Subjects
61687 11 0 0 11 7
64549 10 2 1 12 7
45461 13 0 0 13 7
So I would like some aggregated functions with a student grouped onto only 1 row and the sum of his different units as separate fields. I would also like a field which sums the Category A and B Units and also a field which gives a count of the total number of subjects they are doing. I could then use this data to set up some warning messages if a student is not doing the correct number of A or B Units etc
I have played around with common table expressions, subqueries etc but am not really sure what I am doing and am not sure which is the correct way about getting the data in the form I want.
Is anyone able to help?
SELECT
STUDENTID,
SUM(CASE BOARDCATEGORY WHEN 'A' THEN 1 ELSE 0 END) AS SUM_A_UNITS,
SUM(CASE BOARDCATEGORY WHEN 'B' THEN 1 ELSE 0 END) AS SUM_B_UNITS,
SUM(CASE BOARDCATEGORY WHEN 'C' THEN 1 ELSE 0 END) AS SUM_C_UNITS,
SUM(CASE BOARDCATEGORY WHEN 'A' THEN 1 WHEN 'B' THEN 1 ELSE 0 END) AS SUM_A_UNITS+SUM_B_UNITS,
COUNT(BOARDCODE) AS COUNT_OF_SUBJECTS
FROM (
SELECT StudentID
,AssessmentCode
,BoardCode
,BoardCategory
,BoardUnits
,sum(cast(boardunits as int)) over (partition by studentid,boardcategory) as UnitCount
,Count(boardcategory) over (partition by studentid) as SubjectCount
FROM uvNCStudentSubjectDetails
where fileyear = 2015
and filesemester = 1
and studentyearlevel = 11
and StudentIBFlag = 0
order by Studentnameinternal,BoardCategory
)
GROUP BY STUDENTID;
Wrapped your SQL statement in the solution, so that you can see what the solution does straight away.
Use SUM and CASE (i.e. SUM only when a condition is met).

MDX: iif condition on the value of dimension

I have 1 Virtual cube consists of 2 cubes.
Example of fact table of 1st cube.
id object_id time_id date_id state
1 10 2 1 0
2 11 5 1 0
3 10 7 1 1
4 10 3 1 0
5 11 4 1 0
6 11 7 1 1
7 10 8 1 0
8 11 5 1 0
9 10 7 1 1
10 10 9 1 2
Where State: 0 - Ok, 1 - Down, 2 - Unknown
For this cube I have one measure StateCount it should count States for each object_id.
Here for example we have such result:
for 10 : 3 times Ok , 2 times Down, 1 time Unknown
for 11 : 3 times Ok , 1 time Down
Second cube looks like this:
id object_id time_id date_id status
1 10 2 1 0
2 11 5 1 0
3 10 7 1 1
4 10 3 1 1
5 11 4 1 1
Where Status: 0 - out, 1 - in. I keep this in StatusDim.
In this table I keep records that should not be count. If object have status 1 that means that I have exclude it from count.
If we intersect these tables and use StateCount we will receive this result:
for 10 : 2 times Ok , 1 times Down, 1 time Unknown
for 11 : 2 times Ok , 1 time Down
As far as i know, i must use calculated member with IIF condition. Currently I'm trying something like this.
WITH MEMBER [Measures].[StateTimeCountDown] AS(
iif(
[StatusDimDown.DowntimeHierarchy].[DowntimeStatus].CurrentMember.MemberValue
<> "in"
, [Measures].[StateTimeCount]
, null )
)
The multidimensional way to do this would be to make attributes from your state and status columns (hopefully with user understandable members, i. e. using "Ok" and not "0"). Then, you can just use a normal count measure on the fact tables, and slice by these attributes. No need for complex calculation definitions.

Collating data in SQL Server

I have the following data in SQL Server
St 1 2 3 4 5 6 7 8
===========================================
603 2 5 1.5 3 0 0 0 0
603 0 0 0 0 2 1 3 5
As I insert the data by batches, each batch only has 4 columns each and I want to collate the data to the following
St 1 2 3 4 5 6 7 8
===========================================
603 2 5 1.5 3 2 1 3 5
but most of the threads I see here are about concatenating strings of a single column.
Anyone has any idea on how to collate or even merge different rows into a single row.
You can use the group by and Sum key word of the t-SQL
SELECT SUM(COL1) , SUM(COL2)..... FROM tbl GROUP BY ST
You can use the GROUP BY clause and aggregate with SUM fields 1-8 :
SELECT St, SUM(1), SUM(2),.. FROM tbl GROUP BY St

How to find count from two joined tables

We have to find count for each risk category for impact level as shown in last result part
Risk Table
RiskID RiskName
----------------------
1 Risk1
2 Risk2
3 Risk3
4 Risk4
5 Risk5
6 Risk6
7 Risk7
8 Risk8
9 Risk9
10 Risk10
11 Risk11
Category Table
Cat_ID Cat_Name
--------------------------
1 Design
2 Operation
3 Technical
Risk_Category table
Risk_ID Category_ID
------------------------
1 1
1 2
2 1
3 1
3 3
4 1
5 2
6 1
7 3
8 1
9 3
10 3
Risk_Impact_Assessment table
Risk_ID Impact_Level Impact_Score
---------------------------------------------
1 High 20
2 Medium 15
3 High 20
4 Low 10
5 High 20
6 High 20
7 High 20
8 Low 10
9 Medium 15
10 Low 15
11 Medium 15
Result should be like this
Cat_Name Impact_Level_High Impact_Level_Medium Impact_Level_Low
-------------------------------------------------------------------------------------
Design 1 1 2
Operation 2
Technical 2 2 1
You probably want to use the group by clause, along with case, eg.:
select
Cat_Name,
sum(case when Impact_Level = 'High' then 1 else 0 end) as [Impact_Level_High],
sum(case when Impact_Level = 'Medium' then 1 else 0 end) as [Impact_Level_Medium],
sum(case when Impact_Level = 'Low' then 1 else 0 end) as [Impact_Level_Low]
from [Risk_Impact_Assessment]
...
group by Cat_Name;
(I left out all the joins, I assume you can write these no problem)
You can use this trick to accomplish a lot of cool things, including parametric sorting and (just like here) complicated aggregate functions with little work.