MySql count in group_concat - mysql

I'm trying to create a query that would return a table as followed:
dayName, #ofStatus1,#ofStatus2,#ofStatus3
dayName, #ofStatus1,#ofStatus2,#ofStatus3
dayName, #ofStatus1,#ofStatus2,#ofStatus3
dayName, #ofStatus1,#ofStatus2,#ofStatus3
dayName, #ofStatus1,#ofStatus2,#ofStatus3
dayName, #ofStatus1,#ofStatus2,#ofStatus3
dayName, #ofStatus1,#ofStatus2,#ofStatus3
Basically I have a table where users get to enter cases. Each case has the following fields(datedCreated, status).
There are three (3) status possible (new, progress, closed)
So I would like to retrieve the number of each status for each day.
Each line would look something like this:
Monday, 8,3,2
Tuesday, 8,3,2
Wednesday, 8,3,2
...
I have something that looks like this but can't seem to get it to work.
SELECT DAYNAME(dateAdded)AS Date, COUNT(status) AS Count, GROUP_CONCAT(CONCAT(status, ',', "54") SEPARATOR ',' ) AS Text FROM clients GROUP BY DATE(dateAdded) ORDER BY dateAdded LIMIT 7
I know right now I have three colomns, but I need it to be in one columns.
Thank your for the help in advance.

Try:
SELECT concat(
DAYNAME(dateAdded),', '
sum(case when status = 'new' then 1 else 0 end),','
sum(case when status = 'progress' then 1 else 0 end),','
sum(case when status = 'closed' then 1 else 0 end)) as single_col
FROM clients
GROUP BY DATE(dateAdded)
ORDER BY dateAdded

Why not just group concat the results?
SELECT
GROUP_CONCAT(t_date, t_new, t_progress, t_closed) AS 'Status Per Day'
FROM
( SELECT
DAYNAME(dateAdded)AS t_date,
SUM(status = 'new') t_new,
SUM(status = 'progress') t_progress,
SUM(status = 'closed') t_closed
FROM clients
GROUP BY DATE(dateAdded)
ORDER BY dateAdded LIMIT 7
) t
GROUP BY t_date

Related

SQL query to show multiple counts over the last day

How do i formulate a sql query where i can display the number of counts of success and errors and warning for the tables for latest day . So I can create a visualization in dashboard. The ultimate goal is for a user to know on a current day how many healthy pipelines are there and how many unhealthy pipelines are there.
i tried something like this, but i complicated it.
SELECT status, COUNT(*) as Total, cast(cast(time as Timestamp) as date) as time,
SUM(CASE WHEN Status = 'Success' THEN 1 ELSE 0 END) as Success,
SUM(CASE WHEN Status = 'Warning' THEN 1 ELSE 0 END) as Warning,
SUM(CASE WHEN Status = 'Error' THEN 1 ELSE 0 END) as Error
FROM table-name
where (cast(cast(time as Timestamp) as date) in ({{ Time }}) or {{ Time }} = 'All')
GROUP BY 1, cast(cast(time as Timestamp) as date)
order by cast(cast(time as Timestamp) as date) desc
lets say this is the given table
How do i formulate a sql query where i can display the number of counts of success and errors and warning for the tables for latest day .
You can use something like this:
SELECT DATE(time) as date, COUNT(*) as Total, ,
SUM(Status = 'Success') as Success,
SUM(Status = 'Warning') as Warning,
SUM(Status = 'Error') as Error
FROM table-name
WHERE date(time) = (SELECT MAX(date(time)) FROM table-name)
GROUP BY 1;

MySQL : using sum in( case when ) statement shows 0 as result

new to MySQL..so pls help me out with this basic code..
i have a query something like this...
select weekofyear(id_time),
(id),
#Tat1:=exp1,
#Tat2:=exp2,
#check1:=exp3,
#check2:=exp4,
(case when #check2=0 then
(case when (#Tat1>(#Tat2+30) or (#check1=1 and (#Tat1>#Tat2+10))) then 1 else 0 end)
else
(case when (#Tat1>(#Tat2+30) or (#check1=1 and (#Tat1>#Tat2+20))) then 1 else 0 end)
end) as BO
from datb
where cid=18
and id_time between '2019-11-01 06:00:00' and '2019-11-25 06:00:00'
and it gives correct results as--here
however i want to use sum after case when statement so that I can get total values where BO=1 and group by week of year , so i made following changes-
select weekofyear(id_time),
count(id),
#Tat1:=exp1,
#Tat2:=exp2,
#check1:=exp3,
#check2:=exp4,
sum(case when #check2=0 then
(case when (#Tat1>(#Tat2+30) or (#check1=1 and (#Tat1>#Tat2+10))) then 1 else 0 end)
else
(case when (#Tat1>(#Tat2+30) or (#check1=1 and (#Tat1>#Tat2+20))) then 1 else 0 end)
end) as BO
from datb
where cid=18
and id_time between '2019-11-01 06:00:00' and '2019-11-25 06:00:00'
group by weekofyear(id_time)
but it always returns 0 as output.
Output --here 2
Please help , I don't know what am I doing wrong here.
Thanx !
As others have already said, session variables can be unpredictable (especially when aggregation gets mixed in). That said, it doesn't look like you're using the session variables to carry over values from one row to the next (as is often done), but to just make aliases of sorts for calculations you don't want to repeat.
A better way to handle that is just through subqueries.
SELECT woy, id, Tat1, Tat2, check1, check2
, CASE
WHEN check2=0 THEN (
CASE
WHEN (Tat1>(Tat2+30) OR (check1=1 AND (Tat1>Tat2+10))) THEN 1
ELSE 0
END
)
ELSE (
CASE WHEN (Tat1>(Tat2+30) OR (check1=1 AND (Tat1>Tat2+20))) THEN 1
ELSE 0
END
)
END AS BO
FROM (
SELECT WEEKOFYEAR(id_time) AS woy
, id
, exp1 AS Tat1
, exp2 AS Tat2
, exp3 AS check1
, exp4 AS check2
FROM datb
WHERE cid=18
AND id_time BETWEEN '2019-11-01 06:00:00' AND '2019-11-25 06:00:00'
) AS subQ
;
You can then tweak the above query for aggregation, or use it as a subquery for an aggregating outer query.

Grouping by months and by column with diferent values

I am having problems trying to create a query that allow me to group by months and by a column that has different values.
The following is a small representation of the table and columns I need to query.
Table name is requests and has two columns date and status. Status may have the values pending, attended, absent and canceled.
I want to get a query that looks like this
Right now i am trying a subquery on status for each possible value. It works but is a very slow query. It takes arround 48s for 8000 rows.
SELECT
MONTHNAME(date)
(SELECT count(status) FROM requests WHERE status = "pending"),
(SELECT count(status) FROM requests WHERE status = "attended"),
(SELECT count(status) FROM requests WHERE status = "absent"),
(SELECT count(status) FROM requests WHERE status = "canceled")
FROM request
GROUP BY 1;
Any recommendations on how to get the result efficiently? Thank you very much
You could use case whene on status instead of several subselect
select
MONTHNAME(date)
, sum( case when status = "pending" then 1 else 0 end) pending
, sum( case when status = "attended" then 1 else 0 end) attended
, sum( case when status = "absent" then 1 else 0 end) absent
, sum( case when status = "canceled" then 1 else 0 end) canceled
FROM request
GROUP BY MONTHNAME(date) ;

MySQL Select count rows with specific attribute

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

How to do a SELECT for total from beginning until the specified date in MySQL?

I have entry table:
I need to do a SELECT to receive 'Date', 'Number of entries' (in that date), 'Total number of entries until that date'.
When I do the SELECT:
SELECT e1.*,
(select count(*) from entry where date(dateCreated) <= e1.date) as Total
from (
SELECT
DATE(e.dateCreated) as "Date",
count(e.dateCreated) as "No of Entries",
sum( case when e.premium='Y' then 1 else 0 end ) as Premium,
sum( case when e.free='Y' then 1 else 0 end ) as Free,
sum( case when e.affiliateID IS NOT NULL then 1 else 0 end) as Affiliate
FROM entry e
WHERE e.competitionID=166
GROUP BY DATE(e.dateCreated)
) as e1
ORDER BY Date DESC
I've got a result table
but the column 'Total' has a wrong data.
How the correct select should be? Is this logic of select is the best and more efficient one?
Here is a demo
If it is just the 5 vs 7 that is off I think it is because that subquery in your select list, which accesses the inline view e1 (which is filtered to competitionID = 166), is not itself filtered when also utilizing the original entry table (unfiltered). You have to filter the original table to that competitionID as well.
Notice line 3 in sql below (only change)
SELECT e1.*,
(select count(*) from entry where date(dateCreated) <= e1.date
and competitionID=166) as Total
from (
SELECT
DATE(e.dateCreated) as "Date",
count(e.dateCreated) as "No of Entries",
sum( case when e.premium='Y' then 1 else 0 end ) as Premium,
sum( case when e.free='Y' then 1 else 0 end ) as Free,
sum( case when e.affiliateID IS NOT NULL then 1 else 0 end) as Affiliate
FROM entry e
WHERE e.competitionID=166
GROUP BY DATE(e.dateCreated)
) as e1
ORDER BY Date DESC
Fiddle - http://sqlfiddle.com/#!9/e5e88/22/0