MySQL Select count rows with specific attribute - mysql

Sorry for the title, but my problem it's difficult to explain.
I have a table called "TEL_LIST" with this fields:
ID
TELEPHONE
STATUS
I have many rows for a single telephone number. The status may be YES or NO.
I want to count the total number of rows with status "NO" (without counting the "YES" rows) only for telephone numbers which have at least one "YES" status.
To make you understand better, I want this:
EDIT:
TEL:011, STATUS:YES
TEL:011, STATUS:NO
TEL:011, STATUS:NO
TEL:012, STATUS:NO
TEL:012, STATUS:NO
TEL:012, STATUS:NO
RESULT: 2.
TEL:011, STATUS:YES
TEL:011, STATUS:NO
TEL:011, STATUS:NO
TEL:012, STATUS:YES
TEL:012, STATUS:NO
TEL:012, STATUS:NO
RESULT: 4.
Perhaps I have not explained well:
I want the total number (the sum) of all "No" records which have at least one "Yes" record.
To make you understand well, I work in a contact center. I want the total of all negative calls (status: no) that have become positive (status: yes).
Thank you again!

I think this follows your logic:
select tel,
(case when sum(status = 'Yes') = 0 then 0
else sum(status = 'No')
end)
from t
group by tel;

I think maybe this can help me:
select count(case when STATUS != 'YES' Then 1 end) AS TOT
from T
having (select count(case when STATUS='YES' Then 1 end) AS T)>0 AND TOT>0
I tried this solution but I'm not sure that the result is correct...

I would use a left join and a group by query:
select t1.tel, count(t2.tel) AS total_no
from
TEL t1 left join TEL t2
on t1.tel=t2.tel AND t1.status='Yes' AND t2.status='No'
group by
t1.tel
with an index on tel and status, performances should be optimal. Numbers that don't have any status='Yes' won't be returned.

Try this one:
select x.Tel, count(distinct x.Number)
from (
select t.Tel, case when tmp.tel is not null then Id else null end as Number
from yourtable t
left outer join (
select tel
from yourtable
where status = 'Yes'
) tmp on tmp.Tel = t.Tel
where t.status = 'No'
) x
group by x.tel

Use Conditional Aggregate to count the values
select TEL,
count(case when STATUS = 'Yes' Then 1 end) AS Conditional_Count
from yourtable
Group by TEL
Another way would be
SUM(case when STATUS = 'Yes' Then 1 ELSE 0 end)
Update: Based on the clarification in question
select count(case when STATUS = 'NO' Then 1 end) AS Conditional_Count
from yourtable
Having count(case when STATUS = 'YES' Then 1 end) > 0

Related

Vertical column result to horizontal

I need put a column result in to horizontal position, like SUM(CASE WHEN status = 'On Hold' THEN 1 ELSE 0 END) AS 'word' do, I tried a subquery and alias AS too but I didn't have had success. I think that JOIN is to multiple tables, and UNION to get results in same column.
I'm using this page as reference
https://www.mysqltutorial.org/mysql-case-function/
mysql Table: phpvms_pireps
pilotid|flightnum|submitdate|accepted
My sql code:
SELECT DISTINCT `phpvms_pireps`.`pilotid`
, `phpvms_pireps`.`accepted`
, `phpvms_pireps`.`flightnum`
, `phpvms_pireps`.`submitdate`
FROM phpvms_pireps
WHERE ((`phpvms_pireps`.`flightnum` in ('A-1', 'A-2', 'A-3', 'A-4')))
AND submitdate BETWEEN '2020-04-09' AND '2020-04-11'
ORDER
BY `phpvms_pireps`.`pilotid` ASC
The result:
And I want to achieve this:
I'm using php/html, How I can get that result?
Thank you very much!
You are describing a pivot table. Consider using conditional aggregation:
select
pilotid,
max(case when flightnum = 'A-1' then accepted end) a1,
max(case when flightnum = 'A-2' then accepted end) a2,
max(case when flightnum = 'A-3' then accepted end) a3,
max(case when flightnum = 'A-4' then accepted end) a4
from phpvms_pireps
where
flightnum in ('A-1', 'A-2', 'A-3', 'A-4')
and submitdate between '2020-04-09' and '2020-04-11'
group by pilotid
order by pilotid

mysql SELECT columns but use WHERE to only one

I have this query:
SELECT i.d, COUNT(id) AS dr, COUNT(id2) AS dn, SUM(eq) AS eq_sum, COUNT(thx) AS thx_count
FROM dsd
INNER JOIN
(
SELECT COUNT(id) AS d FROM ds
) i
Now I want to use WHERE only to column thx like WHERE thx="y" , so that it will count only all values with "y".
But If I just add WHERE at the end of the query it will affect other columns as well which I don't want to.
How to do this?
Then change your COUNT(thx) AS thx_count to below using CASE expression like
COUNT(CASE WHEN thx = 'y' THEN 1 ELSE 0 END) AS thx_count
(OR)
SUM(CASE WHEN thx = 'y' THEN 1 ELSE 0 END) AS thx_count

Reduce the number of queries

I have seperate queries but i need to reduce the no so put all in one
select count(applicant_id) as registered from student_application where filter_status=0 AND
select count(applicant_id) as filer_select from student_application where filter_status=1 AND
select count(applicant_id) as filter_reject from student_application where filter_status=2
but this shows some errors
Use CASE expression.
Query
select
count(case when filter_status = 0 then applicant_id else null end) as registered,
count(case when filter_status = 1 then applicant_id else null end) as filer_select,
count(case when filter_status = 2 then applicant_id else null end) as filer_reject
from student_application;
SQL Fiddle
You could also use group_by, with the where clause if you're looking for a subset rather than all possible values of filter_status:
SELECT filter_status, COUNT(*)
FROM student_application
WHERE filter_status in (0, 1, 2)
GROUP BY filter_status;

Combing two queries while using group by

Having some trouble figuring out the logic to this. See the two queries below:
Query 1:
SELECT cId, crId, COUNT(EventType)
FROM Data
WHERE EventType='0' OR EventType='0p' OR EventType='n' OR EventType = 'np'
GROUP BY crId;
Query 2:
SELECT cId, crId, COUNT(EventType) AS Clicks
FROM Data
WHERE EventType='c'
GROUP BY crId;
Was just wondering if there was a way to make the column that I would get at the end of query 2 appear in query 1. Since the where statements are different, not really sure where to go, and any subquery that I've wrote just hasn't worked.
Thanks in advance
SELECT cId, crId,
SUM(CASE WHEN EventType='0' OR EventType='0p' OR EventType='n' OR EventType = 'np' THEN 1 ELSE 0 END) AS Count_1,
SUM(CASE WHEN EventType='c' THEN 1 ELSE 0 END) AS Count_2
FROM Data
WHERE EventType IN ('0','0p','n','np','c')
GROUP BY crId;
You can join the two, using the second as a correlated subquery.
SELECT
Data.cId,
Data.crId,
COUNT(EventType) AS event_type_count,
click_counts.Clicks
FROM
Data
/* Correlated subquery retrieves the Clicks (EventType 'c') per cId */
LEFT JOIN (
SELECT cId, crId, COUNT(EventType) AS Clicks
FROM Data
WHERE EventType='c'
GROUP BY crId
) AS click_count ON Data.cId = click_count.cId AND Data.crId = click_count.crId
/* OR chain replaced with IN() clause */
WHERE Data.EventType IN ('0','0p','n','np')
/* This GROUP BY should probably also include Data.cId... */
GROUP BY Data.crId;
You can do this all querying from the table once and using CASE statements.
SELECT cId, crId,
SUM(CASE WHEN EventType IN ('0', '0p', 'n', 'np') THEN 1 ELSE 0 END) as events,
SUM(CASE WHEN EventType = 'c' THEN 1 ELSE 0 END) as clicks
FROM Data
WHERE EventType IN ('0', '0p', 'n', 'np', 'c')
GROUP BY crId;
You want to use IN?
SELECT cId, crId, COUNT(EventType) as Clicks
FROM Data
WHERE EventType IN ('0','0p','n','np','c')
GROUP BY crId;
:) PUtting myself in right direction ;)
sqlfiddle demo
select id, crid,
count(case when type <> 'c'
then crid end) count_others,
count(case when type ='c'
then crid end) count_c
from tb
group by crid
;

get count of two table fields in one query

I am trying to get the count of females and males in the gender field of a table.
Is there a way to get the count of each in one query?
Something like:
select * from table count(where gender = 'm') as total_males, count(where gender = 'f') as total_females;
or will it require two queries?
select count(*) from table where gender = 'm';
select count(*) from table where gender = 'f';
This is basically a PIVOT. MySQL does not have a pivot so you can use an aggregate function with a CASE statement to perform this:
select
sum(case when gender = 'm' then 1 else 0 end) Total_Male,
sum(case when gender = 'f' then 1 else 0 end) Total_Female
from yourtable
See SQL Fiddle with Demo
Or using COUNT:
select
count(case when gender = 'm' then 1 else null end) Total_Male,
count(case when gender = 'f' then 1 else null end) Total_Female
from yourtable;
See SQL Fiddle with Demo
Something like this will work:
SELECT SUM(IF(t.gender='m',1,0)) AS total_males
, SUM(IF(t.gender='f',1,0)) AS total_females
FROM mytable t
The "trick" here is that we are using a conditional test to return either a 0 or a 1 for each row, and then adding up the 0's and 1's. To make this a little more clear, I am using the SUM aggregate function rather than COUNT, although COUNT could be used just as easily, though we'd need to return a NULL in place of the zero.
SELECT COUNT(IF(t.gender='m',1,NULL)) AS total_males
, COUNT(IF(t.gender='f',1,NULL)) AS total_females
FROM mytable t
Consider that the two expressions in the SELECT list of this query:
SELECT COUNT(1)
, SUM(1)
FROM mytable t
Will return the same value.
If you want to avoid the MySQL IF function, this can also be done using the ANSI SQL CASE expression:
SELECT SUM( CASE WHEN t.gender = 'm' THEN 1 ELSE 0 END )) AS total_males
, SUM( CASE WHEN t.gender = 'f' THEN 1 ELSE 0 END )) AS total_females
FROM mytable t
select sum(case when gender='m' then 1 else null end) as total_males, sum(case when gender='f' then 1 else null end) as total_females from ...
Should work just fine!
If your only issue is to avoid two queries, you can always write two queries as subselects of one query.
Select (select 1 from dual) as one, (select 2 from dual) as two from dual
This would work for your scenario, too.