SQL function to download rows with specific values only - sql

I have duplicate IDs with different activities. To return all the IDs, but remove duplicates, and to return three new columns called email, phone call and appointment containing true if activity is (email(for email columns), phone call(for phone column), appointment(for appointment columns)), otherwise false.
What I have
ID
Activity
101
Email
101
Appointment
102
Campaign
103
Phone call
104
Appointment
SELECT id,
MAX(CASE WHEN activity='Phone Call' THEN TRUE ELSE FALSE END) AS PhoneCall,
MAX(CASE WHEN activity='Appointment' THEN TRUE ELSE FALSE END) AS Appointment,
MAX(CASE WHEN activity='Email' THEN TRUE ELSE FALSE END) AS Email
| 104 | Campaign |
What I want
ID
Email
Appointment
Phone call
101
True
True
False
102
False
False
False
103
False
False
Ture
104
False
Ture
False

This should be what you are looking for
SELECT id, MAX(CASE WHEN activity='Email' THEN 'True' ELSE 'False' END) AS Email, MAX(CASE WHEN activity='Appointment' THEN 'True' ELSE 'False' END) AS Appointment, MAX(CASE WHEN activity='Phone Call' THEN 'True' ELSE 'False' END) AS 'Phone Call' FROM {your_table_name} GROUP BY id;

Related

Sql query - Order by number of true values in the columns

I have a table like this
I need to get the validity order by the number of true values in the last 4 columns.
For e.g. the output of the below query should be
1110 // 4 true values
1001 // 2 true values
1000 // 1 true value
You can use subquery;
SELECT subquery.VALIDITY,
concat(CAST ((subquery.TAXI + subquery.CAR + subquery.TRUCK + subquery.BIKE) AS TEXT) , ' True values') as COUNTTRUEVALUES
FROM (select VALIDITY,
CASE WHEN TAXI THEN 1 ELSE 0 END AS TAXI,
CASE WHEN CAR THEN 1 ELSE 0 END AS CAR,
CASE WHEN TRUCK THEN 1 ELSE 0 END AS TRUCK,
CASE WHEN BIKE THEN 1 ELSE 0 END AS BIKE
FROM YourTableName) as subquery
ORDER BY 2 DESC
output
VALIDITY COUNTTRUEVALUES
1110 4 True values
1001 2 True values
1000 1 True values
Convert the boolean values to integers and order descending by their total:
SELECT *
FROM tablename
ORDER BY taxi::int + car::int + truck::int + bike::int DESC;
See the demo.
What about something like this?
SELECT
id,
validity,
taxi1 + car1 + truck1 + bike1
FROM
(
SELECT
id,
validity
CASE WHEN taxi = 'TRUE' THEN 1 ELSE 0 END taxi1,
CASE WHEN car = 'TRUE' THEN 1 ELSE 0 END car1,
CASE WHEN truck = 'TRUE' THEN 1 ELSE 0 END truck1,
CASE WHEN bike = 'TRUE' THEN 1 ELSE 0 END bike1
FROM table
)

How to get the count of specific rows as columns

I have a table in the database shown as shown below:
Status
Email
Count
Assigned
admin1#admin1.com
1
Completed
admin1#admin1.com
1
InProgress
admin1#admin1.com
2
Assigned
admin2#admin2.com
5
The possible values in the Status column are Assigned, InProgress and Completed.
I want a result to be displayed like this:
Email
Assigned
InProgress
Completed
admin1#admin1.com
1
2
1
admin2#admin2.com
5
0
0
You can use conditional aggregation:
select email,
sum(case when status = 'Assigned' then count else 0 end) as assigned,
sum(case when status = 'InProgress' then count else 0 end) as InProgress,
sum(case when status = 'Completed' then count else 0 end) as Completed
from t
group by email;

Find out whether a value is present grouped by a value in SQL

I have a table that looks sort of like this:
CustomerID ItemType
001 'a'
001 'b'
001 'c'
001 'd'
002 'd'
How can I structure a select statement that looks something like this:
CASE WHEN ItemType = 'a' THEN 1 ELSE 0 END as Aexists,
CASE WHEN ItemType = 'b' THEN 1 ELSE 0 END as Bexists,
CASE WHEN ItemType = 'c' THEN 1 ELSE 0 END as Cexists,
CASE WHEN ItemType = 'd' THEN 1 ELSE 0 END as Dexists,
CASE WHEN ItemType = 'e' THEN 1 ELSE 0 END as Eexists,
GROUP BY CustomerID
Where the results would look like this:
CustomerID, Aexists, Bexists, Cexists, Dexists, Eexists
001 1 1 1 1 0
002 0 0 0 1 0
I'm confused on how to tell if the items exist since they are spread over rows; I only want one row returned per customer.
Close enough. Use aggregate function MAX
select
CustomerID,
max(CASE WHEN ItemType = 'a' THEN 1 ELSE 0 END) as Aexists,
max(CASE WHEN ItemType = 'b' THEN 1 ELSE 0 END) as Bexists,
max(CASE WHEN ItemType = 'c' THEN 1 ELSE 0 END) as Cexists,
max(CASE WHEN ItemType = 'd' THEN 1 ELSE 0 END) as Dexists,
max(CASE WHEN ItemType = 'e' THEN 1 ELSE 0 END) as Eexists
from t
GROUP BY CustomerID

Multiple conditions in SQL

I have following table:
Employee ID Employee Status Date of Termination
1 A NULL
2 A NULL
3 I 1/1/2016
4 I 12/15/2016
5 I 1/1/2016
I would like to report on the following:
Number of current active employees - 2
Number of inactive employees - 3
Number of employees terminated in last one month - 2
This is the piece of code I used:
select
case when employee_status='A' then count(employee_id) else '' end,
case when employee_status='I' then count(employee_id) else '' end,
case when employee_status='I'
then
(select count(employee_id)
from employee
where date_of_termination between '1/1/2016' and '2/1/2016')
else '' end
from employee
My result set is:
Active | Inactive | Inactive_last_month
2 | 0 | 0
0 | 3 | 2
I would like to achieve the following:
Active | Inactive | Inactive_last_month
2 | 3 | 2
Any recommendations will be appreciated.
You need to SUM up the number of rows that match each criteria:
SELECT
SUM(CASE WHEN date_of_termination IS NULL THEN 1 ELSE 0 END) AS active,
SUM(CASE WHEN date_of_termination IS NOT NULL THEN 1 ELSE 0 END) AS inactive,
SUM(CASE WHEN date_of_termination BETWEEN '20160101' AND '20160201' THEN 1 ELSE 0 END) AS inactive_last_month
FROM
Employee
I've ignored the employee_status column with the assumption that the date is sufficient to determine whether or not the employee is active/inactive - in which case that column probably shouldn't even exist in the table since it's duplicating data.
This should be possible to simplify it using SUM :
select
sum(case when employee_status='A' then 1 else 0 end) as active,
sum(case when employee_status='I' then 1 else 0 end) as inactive,
sum(case when employee_status='I' and date_of_termination between '1/1/2016' and '2/1/2016' then 1 else 0 end) as inactive_last_month
from employee
I woudl wrap the case satements in sum() function and also modify the ELSE part of the CASE Statement to be 0.
so it will look like something like this:
select
SUM(case when employee_status='A' then count(employee_id) else 0 end) AS Active,
SUM(case when employee_status='I' then count(employee_id) else 0 end) AS Inactive,
SUM(case when employee_status='I'
then
(select count(employee_id)
from employee
where date_of_termination between '1/1/2016' and '2/1/2016')
else 0 end) AS Inactive_last_month
from employee

Wrong Output in the FULL OUTER JOIN query

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
tbl_TransactionDishout
Trnx_id offerNo TerminalID Created VirtualCard
-------------------------------------------------------------------
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
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,
t1.field14,
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 (t1.field14 <> 'Test Card' and t1.field14 is null) 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),
t1.field14
ORDER BY
convert(varchar, CAST(ISNULL(t1.created,t2.created) AS DATETIME), 111) DESC
Now, here I am facing one problem that the fourth column is executing something wrong because I have One record in tbl_TransactionDishout table yesterday which has responsecode = 0000 and also is not a 'Test card' but still I am getting 0 count.
relation between tbl_transaction and tblCustomer is having same cardno...
Based on what you have said in the comments section, I think you need to change one snippet of code...
What I want is that card should not have field14 as 'Test card'
(t1.field14 <> 'Test Card' and t1.field14 is null)
=>
(t1.field14 <> 'Test Card' OR t1.field14 is null)
Build up a logic table to check if you really want AND or if you want OR
field14 | (field14 <> 'Test Card') | (t1.field14 is null) | A OR B | A AND B
--------------------------------------------------------------------------------
'Test Card' | FALSE | FALSE | FALSE | FALSE
NULL | NULL | TRUE | TRUE | FALSE
'Any Card' | TRUE | FALSE | TRUE | FALSE
EDIT Follow up to comment
Using OR in the code above can't yield TRUE when Field14 is 'Test Card'. Both tests yield FALSE and so the result must be FALSE.
You need to break things down in stages. Debugging should be done by testing pieces at a time and graddually proving what work to isolate what doesn't. Never try to sort everything out at once, approach things methodically.
Run this test...
SELECT
*,
CASE WHEN field14 <> 'Test Card' THEN 1 ELSE 0 END Test1,
CASE WHEN field14 IS NULL THEN 1 ELSE 0 END Test2,
CASE WHEN field14 <> 'Test Card' OR field14 IS NULL THEN 1 ELSE 0 END 1_OR_2,
CASE WHEN field14 <> 'Test Card' AND field14 IS NULL THEN 1 ELSE 0 END 1_AND_2
FROM
tblCustomer