Multiple join query and sub query - sql-server

Table Structures:
tblCustomer
Customer_id created field1 field2 cardno field14
------------------------------------------------------------------------------------------------
1014 2010-05-25 12:51:59.547 Cell Phone abc#lmn.com 1234567890 Test Card
1015 2010-08-15 12:51:59.547 Email abc#xyz.com 2345678891 NULL
tbl_TransactionDishout
Trnx_id offerNo TerminalID Created VirtualCard
-------------------------------------------------------------------
1 1014 170924690436418 2010-05-25 12:51:59.547 1234567890
Relation between tbl_transaction and tblCustomer is having same cardno.
Is it possible to get the result as below date-wise records:
Enrolled Enrolled as Email Enrolled as Text Deals Redeemed
<First Date> 7 5 2 6
<Next Date> 9 3 6 14
Date should be from both tables even if it has zero records..
Enrolled - Total No of records that is summation of Enrolled as Email and Enrolled as Text.
Enrolled as Email - Where field1 = 'Email' from tblCustomer table
Enrolled as Text - Where field1 = 'cell phone' from tblCustomer table
Deals Redeemed - Where field14 <> 'Test Card' from tblCustomer table and
where DishoutResponsecode = '0000' from tbl_Transaction table
My Existing Query:
SELECT
convert(varchar, CAST(ISNULL(t1.created,t2.created) AS DATETIME), 111) created,
COUNT(CASE WHEN (t1.field1 = 'E-mail' or t1.field1 = 'Cell Phone') and (t1.field14 <> 'Test Card' or t1.field14 is null) THEN 1 END) Enrolled,
COUNT(CASE WHEN t1.field1 = 'E-mail' and (t1.field14 <> 'Test Card' and t1.field14 is null) THEN 1 END) Enrolled_as_Email,
COUNT(CASE WHEN t1.field1 = 'Cell Phone' and (t1.field14 <> 'Test Card' and t1.field14 is null) THEN 1 END) Enrolled_as_Cell,
COUNT(CASE WHEN t2.DishoutResponseCode = '0000' and (IsNull(t1.field14, '') <> 'Test Card') THEN 1 END) Deals_Redeemed
FROM tblCustomer AS t1
FULL OUTER JOIN
tbl_TransactionDishout t2
ON t1.cardno = t2.VirtualCard and t1.created = t2.created
GROUP BY
convert(varchar, CAST(ISNULL(t1.created,t2.created) AS DATETIME), 111)
ORDER BY
convert(varchar, CAST(ISNULL(t1.created,t2.created) AS DATETIME), 111) DESC
Last 4-5 records in tblCustomer table
created cardno field14
----------------------------------------------------------
2012-03-07 10:03:00.034 1234007600101240
2012-03-05 04:02:00.040 1234007600602122
2012-03-01 06:25:50.400 1234010400972168 Test Card
2012-03-01 30:05:30.022 555566669999 Test Card
2012-03-01 50:50:20.450 666677778888 Test Card
Last 4-5 records in tbl_TransactionDisout table
created VirtualCard DishoutResponseCode
-----------------------------------------------------------------------
2012-03-09 13:18:02.703 1234010400972168 0010
2012-03-09 13:17:35.307 1234010400972168 0002
2012-03-09 13:17:14.237 1234010400972168 0007
2012-03-09 13:16:57.650 1234010400972168 0002
2012-03-08 21:13:57.137 1234010400475686 0000
2012-03-08 16:50:38.273 1234010400972168 0002
2012-03-08 16:50:26.070 1234010400972168 0007
2012-03-08 16:49:49.793 1234010400972168 0002
So there is only one card in this with having response code '0000' and also not a 'Test Card'..But I am getting all the card with code = '0000' and also having 'Test Card' so that means field14 is not able to compare because it is from the different table and different date..

This is the result I get back with this query when I use the data that you specified in the main question:
SELECT
convert(varchar, CAST(ISNULL(t1.created,t2.created) AS DATETIME), 111) created,
COUNT(CASE WHEN (t1.field1 = 'Email' or t1.field1 = 'Cell Phone') and (t1.field14 <> 'Test Card' or t1.field14 is null) THEN 1 END) Enrolled,
COUNT(CASE WHEN t1.field1 = 'Email' and (IsNull(t1.field14, '') <> 'Test Card') THEN 1 END) Enrolled_as_Email,
COUNT(CASE WHEN t1.field1 = 'Cell Phone' and (IsNull(t1.field14, '') <> 'Test Card') THEN 1 END) Enrolled_as_Cell,
COUNT(CASE WHEN t2.DishoutResponseCode = '0000' and (IsNull(t1.field14, '') <> 'Test Card') THEN 1 END) Deals_Redeemed
FROM
tblCustomer AS t1
FULL OUTER JOIN
tbl_TransactionDishout t2
ON t1.cardno = t2.VirtualCard
AND t1.created = t2.created
GROUP BY
convert(varchar, CAST(ISNULL(t1.created,t2.created) AS DATETIME), 111)
ORDER BY
convert(varchar, CAST(ISNULL(t1.created,t2.created) AS DATETIME), 111) DESC
Result:
created Enrolled Enrolled_as_Email Enrolled_as_Cell Deals_Redeemed
------------------------------ ----------- ----------------- ---------------- --------------
2012/03/09 0 0 0 0
2012/03/08 0 0 0 1
2012/03/07 1 0 1 0
2012/03/05 1 0 1 0
2012/03/01 0 0 0 0

Related

Need Help on SQL Query - incorporating AVG

[Edit from #marcus-vinicius-pompeu: I rewrote the query for better identation. To bypass 'mostly code' constraint, I changed the original group by logic]
I am totally stuck while writing a query. Required output is attached. Query I have written is as below. it is working fine till column SL_30_Sec. How to add two columns ASA & AHT based on average values of each date
SELECT
Date(t.call_date) as created_date,
--
Sum(CASE WHEN t.table_name = 'one' THEN 1 ELSE 0 END) AS Offered_Calls,
Sum(CASE WHEN t.table_name = 'two' THEN 1 ELSE 0 END) AS Answered_Calls,
--
Concat(
Round(
(
Sum(CASE WHEN t.table_name = 'two' THEN 1 ELSE 0 END) /
Sum(CASE WHEN t.table_name = 'one' THEN 1 ELSE 0 END) * 100
), 2
), '%'
) AS Success_Rate,
--
Sum(CASE WHEN t.table_name = 'three' THEN 1 ELSE 0 END) AS OB_Calls,
Sum(CASE WHEN t.table_name = 'four' THEN 1 ELSE 0 END) AS OB_Calls_Received,
Sum(CASE WHEN t.table_name = 'five' THEN 1 ELSE 0 END) AS Calls_ANS_in_30_Sec,
--
Concat(
Round(
(
Sum(CASE WHEN t.table_name = 'five' THEN 1 ELSE 0 END) /
Sum(CASE WHEN t.table_name = 'one' THEN 1 ELSE 0 END) * 100
), 2
), '%'
) AS SL_30_Sec
FROM
(
SELECT call_date, 'one' AS table_name FROM table_1
WHERE call_date BETWEEN '2020-01-01' AND '2020-01-31 23:59' AND campaign_id = 'abc_inbound'
-- -----
UNION ALL
-- -----
SELECT call_date, 'two' AS table_name FROM table_1
WHERE call_date BETWEEN '2020-01-01' AND '2020-01-31 23:59' AND campaign_id = 'abc_inbound' AND term_reason IN('agent', 'caller')
-- -----
UNION ALL
-- -----
SELECT call_date, 'three' AS table_name FROM table_2
WHERE call_date BETWEEN '2020-01-01' AND '2020-01-31 23:59' AND campaign_id = 'xyz'
-- -----
UNION ALL
-- -----
SELECT call_date, 'four' AS table_name FROM table_2
WHERE call_date BETWEEN '2020-01-01' AND '2020-01-31 23:59' AND campaign_id = 'xyz' AND term_reason IN('agent', 'caller')
-- -----
UNION ALL
-- -----
SELECT call_date, 'five' AS table_name FROM table_1
WHERE call_date BETWEEN '2020-01-01' AND '2020-01-31 23:59' AND campaign_id = 'abc_inbound' AND term_reason IN('agent', 'caller', 'ABANDON') AND queue_seconds <= 30
) t
GROUP BY Date(t.call_date)
Required Output
You cannot, given the dataset...
Table_1 = date of offered calls
Table_2 = date of answered calls
Table_3 = date of outbound calls
Table_4 = date of offered outbound calls
Table_5 = date of answered outbound calls in less than 30 seconds
To compute:
ASA - you have to have the time of answer time (you should have, since the data allows for filtering those answered in 30 seconds or below)
AHT - you have to have answer time and talk & wrap time
For not outbound calls it seems we already have answer time from table_1.queue_seconds...
Links for definitions:
https://www.genroe.com/resources/glossary/call-centre-definitions-and-glossary
https://www.callcentrehelper.com/how-to-measure-average-handling-time-52403.htm
You can try this.
SELECT ((SUM(ASA) +SUM(AHT))/count(*))
FROM tableName
GROUP BY date

SQL Server: This created score is multiplying by 4?

The TotalScore result is 320 when it should just be 80(30 + 50) since the top 1 record for ProviderID 874 has SessionsProgress = 3 and the providerID is also present in the joined SubscriptionsTV table.
DECLARE #ProviderID int = '874';
WITH cte as(
SELECT TOP 1 a.ProviderID, Time_Stamp,
SUM(CASE WHEN [AdditionalReports] = '1' THEN 5 ELSE 0 END) as AdditionalReports,
SUM(CASE WHEN [UniqueReportRequests] = '1' THEN 15 ELSE 0 END) as UniqueReportsRequests,
SUM(CASE WHEN [SessionsProgress] > '0' THEN 30 ELSE 0 END) as SessionsProgress,
MAX(CASE WHEN b.ProviderID IS NULL THEN 0 ELSE 50 END) as SubscriptionExists
FROM ProviderValueCard a
LEFT JOIN SubscriptionsTV b
ON a.ProviderID = b.ProviderID
WHERE a.ProviderID = #ProviderID AND GroupID = 2
GROUP BY Time_Stamp, a.ProviderID, event
ORDER BY event DESC, Time_Stamp DESC
)
SELECT ProviderID, Time_Stamp, (AdditionalReports + UniqueReportsRequests + SessionsProgress + SubscriptionExists) AS TotalScore
FROM cte
Here are the 2 records for ProviderID 874 which only the most recent by TimeStamp is used.
ProviderID AdditionalReports UniqueReportRequests Time_Stamp AdditionalReportsNum UniqueReportsNum SessionsProgress AdditionalReportsNumQtr UniqueReportsNumQtr SurveyCompleted
----------- ----------------- -------------------- ----------------------- -------------------- ---------------- ---------------- ----------------------- ------------------- ---------------
874 0 1 2015-01-30 08:13:44.660 0 55 3 0 10 1
874 0 0 2014-12-30 08:31:20.893 0 0 3 0 0 1

Count of rows for 2 days

My data is in below format:
employee order id date
a 123 01/06/2013
b 124 02/06/2013
a 125 02/06/2013
a 129 02/06/2013
I need the data in below format:
employee day 1 day 2
a 1 2
b 0 1
Try this one -
DECLARE #temp TABLE
(
dtStart DATETIME
, employees CHAR(1)
)
INSERT INTO #temp (employees, dtStart) VALUES('a','01/06/2013')
INSERT INTO #temp (employees, dtStart) VALUES('a','01/06/2013')
INSERT INTO #temp (employees, dtStart) VALUES('b','02/06/2013')
SELECT
employees
, day1 = COUNT(CASE WHEN DAY(dtStart) = 1 THEN 1 END)
, day2 = COUNT(CASE WHEN DAY(dtStart) = 2 THEN 1 END)
FROM #temp
--WHERE dtStart BETWEEN '01/06/2013' AND '30/06/2013'
GROUP BY employees
Something along these lines should work (depending on whether you have a fixed amount of days or not):
select employee,
SUM(CASE WHEN date = '01/06/2013' THEN 1 ELSE 0 END) as day1,
SUM(CASE WHEN date = '02/06/2013' THEN 1 ELSE 0 END) as day2
from table
group by employee
select distinct employees,
SUM(CASE WHEN dtStart = '01/06/2013' THEN 1 ELSE 0 END) as day1,
SUM(CASE WHEN dtStart = '02/06/2013' THEN 1 ELSE 0 END) as day2
from yourTable
group by dtStart,employees
see your demo

Combine two queries, which include aggregations, into a single query

Table "tblCustomer":
Customer_id
created
field1
field2
cardno
1014
2010-05-25 12:51:59.547
Cell Phone
abc#lmn.com
1234567890
1015
2010-08-15 12:51:59.547
Email
abc#xyz.com
2345678891
Table "tbl_TransactionDishout":
Trnx_id
offerNo
TerminalID
Created
VirtualCard
1
1014
170924690436418
2010-05-25 12:51:59.547
1234567890
Expected Output:
Enrolled
Enrolled as Email
Enrolled as Text
Deals Redeemed
<First Date>
7
5
2
6
<Next Date>
9
3
6
14
I have two different queries which I need to combine into one.
First One:
SELECT CAST(FLOOR(CAST(t.created AS FLOAT )) AS Datetime) created,
COUNT(field1) Enrolled,
COUNT(CASE field1 WHEN 'E-mail' THEN 1 END) Enrolled_as_Email,
COUNT(CASE field1 WHEN 'Cell Phone' THEN 1 END) Enrolled_as_Cell
FROM tblCustomer as t
GROUP BY t.created
ORDER BY t.created DESC
Which Displays:
create
Enrolled
Enrolled_as_Email
Enrolled_as_Cell
2012-03-01 00:00:00.000
3
1
2
2012-02-29 00:00:00.000
1
0
1
Second One:
SELECT CAST(FLOOR(CAST(t.created AS FLOAT)) AS Datetime) created,
COUNT(*) [Deals_Redeemed]
FROM tbl_TransactionDishout t
LEFT JOIN tblCustomer c
ON t.VirtualCard = c.cardno
GROUP BY CAST(FLOOR(CAST(t.created AS FLOAT )) as Datetime)
ORDER BY t.created desc
Which Displays:
create
Deals_Redeemed
2012-03-02 00:00:00.000
1
2012-03-01 00:00:00.000
6
2012-02-28 00:00:00.000
1
2012-02-27 00:00:00.000
2
Now I want a record which contain date from both and should be combined into one.
But It's giving me the result of the date contained only in tblCustomer table..
How to get "Deals_redeemed"?
Note: relation between tbl_transaction and tblCustomer is having same cardno.
SELECT
CAST(t1.created AS DATE) created,
COUNT(t1.field1) Enrolled,
COUNT(CASE t1.field1 WHEN 'E-mail' THEN 1 END) Enrolled_as_Email,
COUNT(CASE t1.field1 WHEN 'Cell Phone' THEN 1 END) Enrolled_as_Cell,
COUNT(t2.created) Deals_Redeemed
FROM tblCustomer AS t1
LEFT JOIN tbl_TransactionDishout t2
ON t1.cardno = t2.VirtualCard
GROUP BY CAST(t1.created AS DATE)
ORDER BY CAST(t1.created AS DATE) DESC
Edit: Changed condition to cardno, and changed from FULL JOIN to LEFT JOIN.
You could Pivot():
select [create]
, sum([Email]+[Cell Phone]) as [Enrolled]
, max([Email]) as [Enrolled as Email]
, max([Cell Phone]) as [Enrolled as Cell Phone]
, max([Deal Redeemed]) as [Deals Redeemed]
from (
select [create]=created
, create1=created
, field1
from tblCustomer
union all
select [create]=created
, create1=created
, field1='Deal Redeemed'
from tbl_TransactionDishout
) p
pivot (
count(create1)
for field1 in ([Cell Phone],[Email],[Deal Redeemed])
) pv
group by [create]
order by [create]

Add SubQuery in existing subquery

Table Structures:
tblCustomer
Customer_id created field1 field2 cardno
--------------------------------------------------------
1014 Test1 Cell Phone 123146 1234567890
1015 Test2 Email abc#xyz.com 2345678891
tbl_TransactionDishout
Trnx_id offerNo TerminalID Created cardno
-------------------------------------------------------------------
1 1014 170924690436418 2010-05-25 12:51:59.547 1234567890
Is it possible to get the result as below date-wise records:
Enrolled Enrolled as Email Enrolled as Text Deals Redeemed
<First Date> 7 5 2 6
<Next Date> 9 3 6 14
My current query is something like this:
select created,
count(field1) Enrolled,
count(case field1 when 'E-mail' then 1 end) Enrolled_as_Email,
count(case field1 when 'Cell Phone' then 1 end) Enrolled_as_Cell
from tblCustomer c
group by created
order by created desc
But It's giving me the result of the date contained only in tblCustomer table..
Now, How to get Deals_redeemed..?
relation between tbl_transaction and tblCustomer is having same cardno...
In my understanding table tbl_TransactionDishout is an offer, and if it is followed through a record will be inserted into tblCustomers; if not, nothing will change. So deals redeemed is count of non-existing records in tblCustomers for given cardno:
select t.created,
count(c.field1) Enrolled,
count(case c.field1 when 'E-mail' then 1 end) Enrolled_as_Email,
count(case c.field1 when 'Cell Phone' then 1 end) Enrolled_as_Cell,
count(case when c.field1 is null then 1 end) [Deals Redeemed]
from tbl_TransactionDishout t left join tblCustomer c
on t.cardno = c.cardno
group by t.created
order by t.created desc
EDIT: c.created changed to t.created

Resources