Grouping data by type and displaying - mysql

I have a table called 'product', with a 'created_at' date, and a 'type' which is a varchar.
Essentially what I want is an output of the COUNT(*) of each product for every day, for all of the product types. I know that there are only 5 different values for 'type', so that would narrow it down a bit with the query I imagine.
Example:
I have been playing around with this with no success, can't seem to wrap my mind around it. Any ideas?

Try this query
SELECT
SUM(CASE WHEN type = 'type1' THEN 1 ELSE 0 END) AS type1_count,
SUM(CASE WHEN type = 'type2' THEN 1 ELSE 0 END) AS type2_count,
SUM(CASE WHEN type = 'type3' THEN 1 ELSE 0 END) AS type3_count,
SUM(CASE WHEN type = 'type4' THEN 1 ELSE 0 END) AS type4_count,
created_at
GROUP BY created_at
For specific date
SELECT
SUM(CASE WHEN type = 'type1' THEN 1 ELSE 0 END) AS type1_count,
SUM(CASE WHEN type = 'type2' THEN 1 ELSE 0 END) AS type2_count,
SUM(CASE WHEN type = 'type3' THEN 1 ELSE 0 END) AS type3_count,
SUM(CASE WHEN type = 'type4' THEN 1 ELSE 0 END) AS type4_count,
created_at
WHERE created_at = '2015-12-21'
GROUP BY created_at
With date format
SELECT
SUM(CASE WHEN type = 'type1' THEN 1 ELSE 0 END) AS type1_count,
SUM(CASE WHEN type = 'type2' THEN 1 ELSE 0 END) AS type2_count,
SUM(CASE WHEN type = 'type3' THEN 1 ELSE 0 END) AS type3_count,
SUM(CASE WHEN type = 'type4' THEN 1 ELSE 0 END) AS type4_count,
DATE_FORMAT(created_at,'%Y/%m/%d') AS created_date
GROUP BY created_at
HAVING created_date = '2015/12/21'

Related

Count each day with SQL query

I want to display a table with SQL query like this:
I have run my query:
select
tb_r_orderdata.finishtime as date ,
count(*)sum all,
sum(when status = 'SUCCESS' and issync = '1' then 1 else 0 end) sumpaid,
sum(when status = 'SUCCESS' and issync in ('3', '4') then 1 else 0 end) sumfail,
sum(when status = 'CLOSED' then 1 else 0 end) sumclose,
sum(when status = 'Null' then 1 else 0 end) sumunflag
from
tb_r_orderdata;
But when I execute it, the result is different than what I expected. The result is like this:
Thank you for any help
You are missing the GROUP BY and the CASE:
select tb_r_orderdata.finishtime as date ,
COUNT(*) as sumall,
SUM(CASE WHEN status='SUCCESS' AND issync='1' then 1 ELSE 0 END) as sumpaid,
SUM(CASE WHEN status='SUCCESS' AND issync in ('3','4') then 1 ELSE 0 END) as sumfail,
SUM(CASE WHEN status='CLOSED' then 1 ELSE 0 END) as sumclose,
SUM(CASE WHEN status is null then 1 ELSE 0 END) as sumunflag
from tb_r_orderdata
group by tb_r_orderdata.finishtime ;
MySQL treats booleans as integers in a numeric context, with "1" for true and "0" for false. You can simplify your query to:
select o.finishtime as date ,
COUNT(*) as sumall,
SUM(status = 'SUCCESS' AND issync = '1') as sumpaid,
SUM(status = 'SUCCESS' AND issync in ('3', '4')) as sumfail,
SUM(status = 'CLOSED') as sumclose,
SUM(status is null) as sumunflag
from tb_r_orderdata o
where tb_r_orderdata.finishtime is not NULL
group by o.finishtime ;
This also removes NULL finish times.
Explanation in comment for Gordon Linoff
i have try your answer but there is record NULL in the top of table, i dont know why, can you explain it
with little bit change from Gordon Linoff answer
select tb_r_orderdata.finishtime as date ,
SUM(CASE WHEN status='SUCCESS' AND issync='1' then 1 ELSE 0 END) as sumpaid,
SUM(CASE WHEN status='SUCCESS' AND issync in ('3','4') then 1 ELSE 0 END) as sumfail,
SUM(CASE WHEN status='CLOSED' then 1 ELSE 0 END) as sumclose,
SUM(CASE WHEN status='NULL' then 1 ELSE 0 END) as sumunflag
from tb_r_orderdata
group by tb_r_orderdata.finishtime

How to get sum of value for specific field

-------------------------------------------------
SELECT trtm,
COUNT(CASE WHEN trtm= 'TM' THEN 1 ELSE NULL END) AS Transmission,
COUNT(CASE WHEN trtm= 'TR' THEN 1 ELSE NULL END) AS Transfer,
COUNT(CASE WHEN trtm= 'DL' THEN 1 ELSE NULL END) AS Deletion
(SELECT
(SUM( tshares ) AS total WHERE trtm = 'TM'),
(SUM( tshares ) AS total1 WHERE trtm = 'TR'))
FROM transfer_file
where t_date between '10/1/1992' and '10/2/1992'
-----------------------------------------------
How to get the sum of values for specific fields,i am getting the count of value but not getting the sum of value,what to do? help me if any body knows
You should use conditional aggregation inside the SUM too:
SELECT trtm,
COUNT(CASE WHEN trtm= 'TM' THEN 1 ELSE NULL END) AS Transmission,
COUNT(CASE WHEN trtm= 'TR' THEN 1 ELSE NULL END) AS Transfer,
COUNT(CASE WHEN trtm= 'DL' THEN 1 ELSE NULL END) AS Deletion
SUM(CASE WHEN trtm = 'TM' THEN tshares END) AS Total_Transmission,
SUM(CASE WHEN trtm = 'TR' THEN tshares END) AS Total_Transfer
FROM transfer_file
WHERE t_date between '10/1/1992' and '10/2/1992'

Calculate date difference in sql for specific year

I have two dates, say start_date is 20141215 and end_date = 20150115. I would like to use SQL DATEDIFF to only count the dates within the year 2015 which I will specify in the query. Here is the current SQL I have written:
SELECT COUNT(leave_id),
sum(case when leave_status = 1 then 1 else 0 end) pending,
sum(case when leave_status = 2 then 1 else 0 end) declined,
sum(case when leave_status = 3 then 1 else 0 end) approved,
sum(case when leave_status = 4 then 1 else 0 end) rostered,
SUM(DATEDIFF(end_date, start_date)+1) as datetotals
FROM employee_leave WHERE
((YEAR(start_date) = :year) OR (YEAR(end_date) = :year))
AND employee_id = :emp_id
Thanks
You need to fix datediff() to only consider dates during the year. I think this does what you want:
SELECT COUNT(leave_id),
sum(case when leave_status = 1 then 1 else 0 end) pending,
sum(case when leave_status = 2 then 1 else 0 end) declined,
sum(case when leave_status = 3 then 1 else 0 end) approved,
sum(case when leave_status = 4 then 1 else 0 end) rostered,
SUM(DATEDIFF(least(end_date, date(concat_ws('-', :year, 12, 31))),
greatest(start_date, date(concat_ws('-', :year, 1, 1)))
) + 1) as datetotals
FROM employee_leave
WHERE ((YEAR(start_date) = :year) OR (YEAR(end_date) = :year)) AND
employee_id = :emp_id
Make it a AND condition rather like
WHERE
((YEAR(start_date) = :year) AND (YEAR(end_date) = :year))

using sum,count on the same column in mysql

I have a table where i have actions and messages as columns i want to count of particular actions on particular datetime i was able to sum on every action but not count on particular action.
SELECT DATE(datetime),carpark_name,
Sum(CASE action when '2' then 1 else 0 end) as AcceptedIMG,
Sum(CASE action when '3' then 1 else 0 end) as RejectedIMG,
Sum(CASE action when '4' then 1 else 0 end) as ChangeIMG,
sum(CASE action when '23' then 1 else 0 end) as AcceptedViolation,
sum(CASE action when '24' then 1 else 0 end) as RejectedViolation,
sum(CASE action when '25' then 1 else 0 end) as SkippedViolation,
FROM customer_1.audit_trail inner join customer_1.carparks on
customer_1.audit_trail.location_id = customer_1.carparks.id
where DATE(datetime)> '2013-12-01'and DATE(datetime)< '2013-12-03' and location_id = '146'
But this is what I need adding it count(AcceptedIMG, RejectedIMG,ChangeIMG,) or (count(action(2,3,4) as review. I am not able to do this.
To get the SUM of action 2,3 and 4, as column REVIEW and 23,24,25 as CONTRAVENTIO you could do:
SELECT DATE(datetime),
carpark_name,
Sum(CASE action when '2' then 1 else 0 end) as AcceptedIMG,
Sum(CASE action when '3' then 1 else 0 end) as RejectedIMG,
Sum(CASE action when '4' then 1 else 0 end) as ChangeIMG,
SUM(CASE WHEN action IN ('2','3','4') then 1 else 0 end) as REVIEW
sum(CASE action when '23' then 1 else 0 end) as AcceptedViolation,
sum(CASE action when '24' then 1 else 0 end) as RejectedViolation,
sum(CASE action when '25' then 1 else 0 end) as SkippedViolation,
SUM(CASE WHEN action IN ('23','24','25') then 1 else 0 end) as CONTRAVENTION
FROM customer_1.audit_trail
INNER join customer_1.carparks
ON customer_1.audit_trail.location_id = customer_1.carparks.id
WHERE DATE(datetime) > '2013-12-01'
AND DATE(datetime) < '2013-12-03'
AND location_id = '146'
GROUP BY DATE(datetime),carpark_name
I just added the two columns to your query. If you don't need the individual ones, you can remove them.

Getting total value from each field?

How do I get the Total value of Yes, No, Other fields of each username?
I like to add Total field.
SELECT Username,
SUM(CASE WHEN type = 'Yes' THEN 1 ELSE NULL END) as Yes,
SUM(CASE WHEN type = 'No' THEN 1 ELSE NULL END) as No,
SUM(CASE WHEN type = '' THEN 1 ELSE NULL END) as Other
//How to get total of Yes/No/Other
FROM table
WHERE source = 'CompanyName' ";
Also the highest Total goes at the top order.
use 0 instead of NULL, add the missing group by and use COUNT(*) to get the total of each group and order the result:
SELECT Username,
SUM(CASE WHEN type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN type = 'No' THEN 1 ELSE 0 END) as No,
SUM(CASE WHEN type = '' THEN 1 ELSE 0 END) as Other,
COUNT(*) as TOTAL
FROM table
WHERE source = 'CompanyName'
group by Username
order by TOTAL desc;
This assumes that type can only be 'Yes', 'No' or ''.
Use a sub query to sum up your results and add a sort:
select yes, no, other, yes + no + other as Total
from (
SELECT Username,
SUM(CASE WHEN type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN type = 'No' THEN 1 ELSE 0 END) as No,
SUM(CASE WHEN type = '' THEN 1 ELSE 0 END) as Other
FROM table
WHERE source = 'CompanyName'
)
order by (yes + no + other) desc
Don't use SUM(null), the SUM of (1,1,1,null) = null, not 3.
SELECT s.*, s.yes+s.no+s.other as all FROM (
SELECT Username,
SUM(CASE WHEN type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN type = 'No' THEN 1 ELSE 0 END) as No,
SUM(CASE WHEN type = '' THEN 1 ELSE 0 END) as Other
FROM table
WHERE source = 'CompanyName'
GROUP BY Username
) s
ORDER BY all DESC