Breakdown of data - sql

SELECT SUM(CASE
WHEN answer_time IS NOT NULL
AND A.ent_split IS NOT NULL
AND call_type NOT LIKE 'PBX%'
THEN 1
ELSE 0
END) AS CH
,SUM(CASE
WHEN answer_time IS NOT NULL
AND A.ent_split IS NOT NULL
AND call_type NOT LIKE 'PBX%'
THEN 1
ELSE 0
END) + SUM(CASE
WHEN abandon_time IS NOT NULL
AND answer_time IS NULL
THEN 1
ELSE 0
END) AS CO
FROM reporting_call_matrix AS A WITH (NOLOCK)
WHERE A.CALENDAR_DATE >= '10/01/2015'
AND A.CALENDAR_DATE <= '4/30/2016'
AND A.SPLIT IN (
35
,55
,73
)
AND (A.ent_split IS NOT NULL)
Which in return rolled up all 3 split information to
CH 175282
CO 209452
My problem is I need the data to show individual fr each one of the split IN

"Data for each split" sounds like you need to use GROUP BY. Have you tried something like this?
SELECT A.SPLIT,
SUM(CASE
WHEN answer_time IS NOT NULL
AND A.ent_split IS NOT NULL
AND call_type NOT LIKE 'PBX%'
THEN 1
ELSE 0
END) AS CH
,SUM(CASE
WHEN answer_time IS NOT NULL
AND A.ent_split IS NOT NULL
AND call_type NOT LIKE 'PBX%'
THEN 1
ELSE 0
END) + SUM(CASE
WHEN abandon_time IS NOT NULL
AND answer_time IS NULL
THEN 1
ELSE 0
END) AS CO
FROM reporting_call_matrix AS A WITH (NOLOCK)
WHERE A.CALENDAR_DATE >= '10/01/2015'
AND A.CALENDAR_DATE <= '4/30/2016'
AND A.SPLIT IN (
35
,55
,73
)
AND (A.ent_split IS NOT NULL)
GROUP BY A.SPLIT
ORDER BY A.SPLIT

Related

How to nest a join into a complicated Select sum(case, group by statement

I am trying to generate a report, and so far have one completed that gives me how many orders, for each day, are in status 1-9.
TableA structure looks like this:
Sales Order | Order Status | Order Date
123456789 | 1 | 2017-02-22 00:00:00.000
123456790 | 0 | 2017-02-21 00:00:00.000
TableB structure looks like this:
Sales Order | Price
123456789 | 123.00
123456789 | 42.00
123456790 | 56.00
123456790 | 28.00
This code:
SELECT
MAX(year([OrderDate])) as Yr,
MAX(MONTH([OrderDate])) as M,
Day([OrderDate]) as Day,
sum(case when [OrderStatus]='0' THEN 1 ELSE 0 END) AS 'STATUS"0"',
sum(case when [OrderStatus]='1' THEN 1 ELSE 0 END) AS 'STATUS"1"',
sum(case when [OrderStatus]='2' THEN 1 ELSE 0 END) AS 'STATUS"2"',
sum(case when [OrderStatus]='4' THEN 1 ELSE 0 END) AS 'STATUS"4"',
sum(case when [OrderStatus]='8' THEN 1 ELSE 0 END) AS 'STATUS"8"',
sum(case when [OrderStatus]='9' THEN 1 ELSE 0 END) AS 'STATUS"9"',
sum(case when [OrderStatus]='S' THEN 1 ELSE 0 END) AS 'STATUS"S"',
sum(case when [OrderStatus]='*' THEN 1 ELSE 0 END) AS 'STATUS"*"',
sum(case when [OrderStatus]='/' THEN 1 ELSE 0 END) AS 'STATUS"/"'
FROM
SorMaster
WHERE
YEAR([OrderDate]) = YEAR(GETDATE())
GROUP BY
DATENAME(month, DateAdd(month, Month([OrderDate]) - 1, Cast('2008-01-01' AS Datetime))), Day([OrderDate])
ORDER BY
Yr DESC, M DESC, Day DESC
Returns this:
Yr | M | Day | STATUS"0" | STATUS"1" | STATUS"2" | STATUS"4" | STATUS"8" | STATUS"9" | STATUS"S" | STATUS"*" | STATUS"/"
2017 2 22 0 2 0 1 0 0 5 0 0
2017 2 21 0 0 0 7 0 0 0 0 0
This is PERFECT for my first report.
Now, comes the trouble. My Problem is that I need to nest-query Table B, so that instead of returning a count(orders), I need the sum(orders) those totals for each order are in Table B.
Using the above example, the query would need to return something like this:
Yr | M | Day | STATUS"0" | STATUS"1" | STATUS"2" | STATUS"4" | STATUS"8" | STATUS"9" | STATUS"S" | STATUS"*" | STATUS"/"
2017 2 22 0 165 0 0 0 0 0 0 0
2017 2 21 84 0 0 0 0 0 0 0 0
Any pointers?
Just join to TableB:
SELECT MAX(year([t1.OrderDate])) AS Yr,
MAX(MONTH([t2.OrderDate])) AS M,
DAY([t1.OrderDate]) AS Day,
SUM(CASE WHEN [OrderStatus] = '0' THEN t2.Price ELSE 0 END) AS 'STATUS"0"',
SUM(CASE WHEN [OrderStatus] = '1' THEN t2.Price ELSE 0 END) AS 'STATUS"1"',
SUM(CASE WHEN [OrderStatus] = '2' THEN t2.Price ELSE 0 END) AS 'STATUS"2"',
SUM(CASE WHEN [OrderStatus] = '4' THEN t2.Price ELSE 0 END) AS 'STATUS"4"',
SUM(CASE WHEN [OrderStatus] = '8' THEN t2.Price ELSE 0 END) AS 'STATUS"8"',
SUM(CASE WHEN [OrderStatus] = '9' THEN t2.Price ELSE 0 END) AS 'STATUS"9"',
SUM(CASE WHEN [OrderStatus] = 'S' THEN t2.Price ELSE 0 END) AS 'STATUS"S"',
SUM(CASE WHEN [OrderStatus] = '*' THEN t2.Price ELSE 0 END) AS 'STATUS"*"',
SUM(CASE WHEN [OrderStatus] = '/' THEN t2.Price ELSE 0 END) AS 'STATUS"/"'
FROM SorMaster t1
LEFT JOIN TableB t2
ON t1.[Sales Order] = t2.[Sales Order]
WHERE YEAR([OrderDate]) = YEAR(GETDATE())
GROUP BY DATENAME(month,DateAdd(month,Month([OrderDate])-1,Cast('2008-01-01' AS Datetime))),
DAY([OrderDate])
ORDER BY Yr DESC, M DEACLLSC, Day DESC
That's not too difficult, just a matter of LEFT JOINing in table B and then summing the prices in that. There's a couple of small tricks here. You want to LEFT JOIN to ensure that rows in table A always show up, even if there are no corresponding rows in table B. Secondly, in your SUM() statement, you'll need to add a COALESCE(...,0.00) to ensure you're summing decimals and no NULL values creep in from the LEFT JOIN. Oddly in databases, NULL + {anything} = NULL.
For the below query, you'll need to change the name of TableB to whatever the table name is, and the JOIN predicate will need to have the column names named accurately, and delimited correctly if they contain spaces. For example, in MSSQL the delimiters are [ and ], e.g. MyTable.[My Column With Spaces]
SELECT
MAX(YEAR([OrderDate])) as Yr,
MAX(MONTH([OrderDate])) as M,
DAY([OrderDate]) as Day,
sum(case when [OrderStatus]='0' THEN COALESCE(TableB.Price, 0.00) ELSE 0.00 END) AS 'STATUS"0"',
sum(case when [OrderStatus]='1' THEN COALESCE(TableB.Price, 0.00) ELSE 0.00 END) AS 'STATUS"1"',
sum(case when [OrderStatus]='2' THEN COALESCE(TableB.Price, 0.00) ELSE 0.00 END) AS 'STATUS"2"',
sum(case when [OrderStatus]='4' THEN COALESCE(TableB.Price, 0.00) ELSE 0.00 END) AS 'STATUS"4"',
sum(case when [OrderStatus]='8' THEN COALESCE(TableB.Price, 0.00) ELSE 0.00 END) AS 'STATUS"8"',
sum(case when [OrderStatus]='9' THEN COALESCE(TableB.Price, 0.00) ELSE 0.00 END) AS 'STATUS"9"',
sum(case when [OrderStatus]='S' THEN COALESCE(TableB.Price, 0.00) ELSE 0.00 END) AS 'STATUS"S"',
sum(case when [OrderStatus]='*' THEN COALESCE(TableB.Price, 0.00) ELSE 0.00 END) AS 'STATUS"*"',
sum(case when [OrderStatus]='/' THEN COALESCE(TableB.Price, 0.00) ELSE 0.00 END) AS 'STATUS"/"'
FROM SorMaster
LEFT OUTER JOIN TableB
ON TableB.SalesOrder = SorMaster.SalesOrder
WHERE YEAR([OrderDate]) = YEAR(GETDATE())
GROUP BY
DATENAME(month,DateAdd(month,Month([OrderDate])-1,Cast('2008-01-01' AS Datetime))),
DAY([OrderDate])
ORDER BY
Yr DESC,
M DESC,
Day DESC
By (left) joining tableB and replacing your 'count' ones by tableB.price you should get the sum of all positions of orders with the according status.

how to Sum "case when" clause after inner join without duplication

I am a new member of Stackoverflow (and also I'm a new of coding sql) if i do any mistakes about my question please advise me :)
I'm trying to get SUM of Amount in CASE WHEN Clause.
Here is my table
tableA
UserID transid Brand Amount
UserA 109974 MIX 960.00 --BrandMIX=A & B
UserB 109975 B 894.00
UserC 109976 C 350.00
UserC 109977 MIX 300.00 --BrandMIX=C & D
tableB
Row transid Brand
1 109974 A
2 109974 B
3 109975 B
4 109976 C
5 109977 C
6 109977 D
I tried inner join table a and table b on a.soid = b.soid
and when i SUM it, result was wrong due to duplication of transid in table b.
here is my coding.
SELECT UserID
,CASE WHEN COUNT(DISTINCT(b.transid )) <> 0 THEN COUNT(DISTINCT(b.transid ))
ELSE NULL END) AS 'Frequency'
,SUM(Amount) as 'TotalAmount'
,YEAR(transdatetime) AS 'Year'
,SUM (CASE [Brand] WHEN 'AA' THEN 1 ELSE 0 END) AS [BrandA]
,SUM (CASE [Brand] WHEN 'BB' THEN 1 ELSE 0 END) AS [BrandB]
,SUM (CASE [Brand] WHEN 'CC' THEN 1 ELSE 0 END) AS [BrandC]
,SUM (CASE [Brand] WHEN 'DD' THEN 1 ELSE 0 END) AS [BrandD]
,SUM (CASE [Brand] WHEN 'ZZ' THEN 1 ELSE 0 END) AS [BrandZ]
FROM tableA a
INNER tableB b ON a.transid = b.transid
WHERE is_paid = 'N'
GROUP BY UserID, YEAR(transdatetime)
Result that I got
Result that I want
I added ROW_NUMBER() into tableB, I want to SUM(Amount) WHERE MIN(ROW_NUMBER), is it impossible?
Please advise, thank you.
Based on your row_number i.e (row column of tableB) I have modified your query to take min(row) values. Please try this...If this does not work please post the complete tables structures.
SELECT UserID
,CASE WHEN COUNT(DISTINCT(b.transid )) <> 0 THEN COUNT(DISTINCT(b.transid ))
ELSE NULL END AS 'Frequency'
,SUM(Amount) as 'TotalAmount'
,YEAR(transdatetime) AS 'Year'
,SUM (CASE [Brand] WHEN 'AA' THEN 1 ELSE 0 END) AS [BrandA]
,SUM (CASE [Brand] WHEN 'BB' THEN 1 ELSE 0 END) AS [BrandB]
,SUM (CASE [Brand] WHEN 'CC' THEN 1 ELSE 0 END) AS [BrandC]
,SUM (CASE [Brand] WHEN 'DD' THEN 1 ELSE 0 END) AS [BrandD]
,SUM (CASE [Brand] WHEN 'ZZ' THEN 1 ELSE 0 END) AS [BrandZ]
FROM tableA a
INNER JOIN tableB b ON a.transid = b.transid
WHERE is_paid = 'N' AND b.row in (select min(row) from tableB group by transid)
GROUP BY UserID, YEAR(transdatetime)

Need to break down into day..Right now its rolled up into months

SELECT A.SPLIT,
SUM(CASE WHEN answer_time IS NOT NULL AND A.ent_split IS NOT NULL AND call_type NOT LIKE 'PBX%' THEN 1 ELSE 0 END) AS CH,
SUM(CASE WHEN answer_time IS NOT NULL AND A.ent_split IS NOT NULL AND call_type NOT LIKE 'PBX%' THEN 1 ELSE 0 END) + SUM(CASE WHEN abandon_time IS NOT NULL AND answer_time IS NULL THEN 1 ELSE 0 END) AS CO,
SUM(CASE WHEN answer_time IS NOT NULL AND A.ent_split IS NOT NULL AND call_type NOT LIKE 'PBX%' THEN 1 ELSE 1 END) AS AHT
FROM reporting_call_matrix AS A WITH (NOLOCK)
WHERE A.CALENDAR_DATE >= '10/01/2015' AND A.CALENDAR_DATE <= '9/30/2016' AND A.SPLIT IN (9,26,23,43,48,33,56,70,71,72,74,50) AND ( A.ent_split IS NOT NULL)
Group BY A.SPLIT
Heres is some of the data my code puts out.
Split CH CO AHT
9 957157 1156319 1156461
You mean this?
SELECT A.SPLIT, A.CALENDAR_DATE,
SUM(CASE WHEN answer_time IS NOT NULL AND A.ent_split IS NOT NULL AND call_type NOT LIKE 'PBX%' THEN 1 ELSE 0 END) AS CH,
SUM(CASE WHEN answer_time IS NOT NULL AND A.ent_split IS NOT NULL AND call_type NOT LIKE 'PBX%' THEN 1 ELSE 0 END) + SUM(CASE WHEN abandon_time IS NOT NULL AND answer_time IS NULL THEN 1 ELSE 0 END) AS CO,
SUM(CASE WHEN answer_time IS NOT NULL AND A.ent_split IS NOT NULL AND call_type NOT LIKE 'PBX%' THEN 1 ELSE 1 END) AS AHT
FROM reporting_call_matrix AS A WITH (NOLOCK)
WHERE A.CALENDAR_DATE >= '10/01/2015' AND A.CALENDAR_DATE <= '9/30/2016' AND A.SPLIT IN (9,26,23,43,48,33,56,70,71,72,74,50) AND ( A.ent_split IS NOT NULL)
Group BY A.SPLIT, A.CALENDAR_DATE

How to break my results down into Months

SELECT
COUNT(CALL_KEY) AS CONTACTS,
SUM(CASE WHEN answer_time IS NOT NULL AND A.ent_split IS NOT NULL AND call_type NOT LIKE 'PBX%' THEN 1 ELSE 0 END) AS CH,
CAST((CAST(SUM(A.talk_time)
/ (CASE WHEN COUNT(A.answer_time) = 0 THEN 1 ELSE COUNT(A.answer_time) END) AS float) + CAST(SUM(A.hold_time) AS float)
/ (CASE WHEN COUNT(A.answer_time) = 0 THEN 1 ELSE COUNT(A.answer_time) END)) + CAST(SUM(A.work_time) AS float)
/ CAST(COUNT(CASE WHEN A.answer_time > 0 THEN 1 ELSE 1 END) AS numeric(8, 2)) AS Int) AS AHT,
SUM(CASE WHEN abandon_time IS NOT NULL AND answer_time IS NULL THEN 1 ELSE 0 END) AS Total_ABN,
SUM(A.answer_speed) AS ASA,
SUM(CASE WHEN answer_time IS NOT NULL AND A.ent_split IS NOT NULL AND call_type NOT LIKE 'PBX%' THEN 1 ELSE 0 END) + SUM(CASE WHEN abandon_time IS NOT NULL AND answer_time IS NULL THEN 1 ELSE 0 END) AS CO
FROM reporting_call_matrix AS A WITH (NOLOCK)
WHERE A.CALENDAR_DATE >= '5/31/2016' AND A.CALENDAR_DATE <= '7/19/2016' AND A.SPLIT IN (43) AND ( A.ent_split IS NOT NULL)
Here's My Results
CONTACTS CH AHT Total_ABN ASA CO
17199 16744 640 448 580643 17192
Assuming that the month can be obtained from the A.CALENDAR_DATE column
SELECT Month(A.CALENDAR_DATE) as Month,
COUNT(CALL_KEY) AS CONTACTS,
SUM(CASE WHEN answer_time IS NOT NULL AND A.ent_split IS NOT NULL AND call_type NOT LIKE 'PBX%' THEN 1 ELSE 0 END) AS CH,
CAST((CAST(SUM(A.talk_time)
/ (CASE WHEN COUNT(A.answer_time) = 0 THEN 1 ELSE COUNT(A.answer_time) END) AS float) + CAST(SUM(A.hold_time) AS float)
/ (CASE WHEN COUNT(A.answer_time) = 0 THEN 1 ELSE COUNT(A.answer_time) END)) + CAST(SUM(A.work_time) AS float)
/ CAST(COUNT(CASE WHEN A.answer_time > 0 THEN 1 ELSE 1 END) AS numeric(8, 2)) AS Int) AS AHT,
SUM(CASE WHEN abandon_time IS NOT NULL AND answer_time IS NULL THEN 1 ELSE 0 END) AS Total_ABN,
SUM(A.answer_speed) AS ASA,
SUM(CASE WHEN answer_time IS NOT NULL AND A.ent_split IS NOT NULL AND call_type NOT LIKE 'PBX%' THEN 1 ELSE 0 END) + SUM(CASE WHEN abandon_time IS NOT NULL AND answer_time IS NULL THEN 1 ELSE 0 END) AS CO
FROM reporting_call_matrix AS A WITH (NOLOCK)
WHERE A.CALENDAR_DATE >= '5/31/2016' AND A.CALENDAR_DATE <= '7/19/2016' AND A.SPLIT IN (43) AND ( A.ent_split IS NOT NULL)
Group by Month(A.CALENDAR_DATE)

Unpivot : Column ambiguously defined

While running below statement i am getting "Column ambiguosuly defined "..
Please help me on this..
SELECT *
FROM
(
SELECT activity_type,
COUNT(decode(CASE WHEN activity_type = 'K' then 1 when activity_type='BH' then 1 END,1,1)) Holiday,
COUNT(decode(CASE WHEN activity_type = 'SL' then 1 when activity_type='2' then 1 END,1,1)) Leave,
COUNT(CASE WHEN activity_type = 'AL' then 1 ELSE NULL END) Annual,
COUNT(CASE WHEN activity_type = 'OL' then 1 ELSE NULL END) Other_no,
COUNT(CASE WHEN activity_type = 'IM' then 1 ELSE NULL END) InternalMeeting,
COUNT(CASE WHEN activity_type = 'TR' then 1 ELSE NULL END) Training,
COUNT(CASE WHEN activity_type = 'ISM' then 1 ELSE NULL END) Office,
COUNT(decode(CASE WHEN activity_type = 'CS' then 1 when activity_type='10' then 1 when activity_type='SAV'then 1 END,1,1,1)) ExternalMeeting,
COUNT(CASE WHEN activity_type = '9' then 1 ELSE NULL END) Symposium,
COUNT(CASE WHEN activity_type = '12' then 1 ELSE NULL END) Transit,
COUNT(CASE WHEN activity_type = 'H' then 1 ELSE NULL END) Result,
COUNT(CASE WHEN activity_type = '10' then 1 ELSE NULL END) CME
FROM planner_activity pa
WHERE tenant_id=500020
GROUP BY activity_type
)
UNPIVOT
(
monthly_count
FOR activity_type IN (HOLIDAY,LEAVE,ANNUAL,OTHER_NO,INTERNALMEETING,TRAINING,OFFICE,EXTERNALMEETING,SYMPOSIUM,TRANSIT,RESULT,CME)
)
I want to do the sum of the result..please help me..
Output shoud be :
Holiday 1
Leave 1
Anuual 2
Other_no 1
Noof days 5
Many thanks for your help..
Sunitha...
Try to change to this:
SELECT *
FROM
(
SELECT activity_type,
COUNT(decode(CASE WHEN activity_type = 'K' then 1 when activity_type='BH' then 1 END,1,1)) Holiday,
COUNT(decode(CASE WHEN activity_type = 'SL' then 1 when activity_type='2' then 1 END,1,1)) Leave,
COUNT(CASE WHEN activity_type = 'AL' then 1 ELSE NULL END) Annual,
COUNT(CASE WHEN activity_type = 'OL' then 1 ELSE NULL END) Other_no,
COUNT(CASE WHEN activity_type = 'IM' then 1 ELSE NULL END) InternalMeeting,
COUNT(CASE WHEN activity_type = 'TR' then 1 ELSE NULL END) Training,
COUNT(CASE WHEN activity_type = 'ISM' then 1 ELSE NULL END) Office,
COUNT(decode(CASE WHEN activity_type = 'CS' then 1 when activity_type='10' then 1 when activity_type='SAV'then 1 END,1,1,1)) ExternalMeeting,
COUNT(CASE WHEN activity_type = '9' then 1 ELSE NULL END) Symposium,
COUNT(CASE WHEN activity_type = '12' then 1 ELSE NULL END) Transit,
COUNT(CASE WHEN activity_type = 'H' then 1 ELSE NULL END) Result,
COUNT(CASE WHEN activity_type = '10' then 1 ELSE NULL END) CME
FROM planner_activity pa
WHERE tenant_id=500020
GROUP BY activity_type
)
UNPIVOT
(
monthly_count
FOR new_activity_type IN (HOLIDAY,LEAVE,ANNUAL,OTHER_NO,INTERNALMEETING,TRAINING,OFFICE,EXTERNALMEETING,SYMPOSIUM,TRANSIT,RESULT,CME)
)
activity_type is used two times in this query, possibly that causes the problem.
I'm not sure why you are getting that error, but why not just do a single group by for this? Something like this:
SELECT grp, count(*)
FROM (SELECT (CASE WHEN activity_type = 'SL' then 'Leave'
WHEN activity_type = 'AL' then 'Annual'
WHEN activity_type = 'OL' then 'Other_no'
WHEN activity_type = 'IM' then 'InternalMeeting'
WHEN activity_type = 'TR' then 'Training'
WHEN activity_type = 'ISM' then 'Office'
WHEN activity_type IN ('CS', '10', 'SAV') then 'ExternalMeeting'
WHEN activity_type = '9' then 'Symposium'
WHEN activity_type = '12' then 'Transit'
WHEN activity_type = 'H' then 'Result'
WHEN activity_type = '10' then 'CME'
END) as grp, pa.*
FROM planner_activity pa
WHERE tenant_id = 500020
) t
GROUP BY grp;