How to query display data horizontally? - mysql

This is the data I have in my table
id id_mst_tag value time date
1 1 100 16:18:25 2019-10-04
2 2 300 14:10:12 2019-10-04
3 1 90 18:11:22 2019-10-04
4 2 299 18:15:34 2019-10-04
5 1 98 20:13:45 2019-10-04
6 2 311 20:18:25 2019-10-04
7 3 OFF 22:13:21 2019-10-04
and I want to show it horizontally like this
id_mst_tag 14:00 16:00 18:00 20:00 22:00
1 NULL 100 90 98 NULL
2 300 NULL 299 311 NULL
3 NULL NULL NULL NULL OFF
How can I make like this ? please help

You can consider GROUP BY and CASE combination as below to get your desired output.
Note: You have Integer and Text value in the column "Value" which is not realistic. Hope there are NULL in place of OFF in the table. Anyway, you can apply the following logic with data in correct format in column "Value".
SELECT id_mst_tag,
SUM(CASE WHEN HOUR(time) = 14 THEN Value ELSE 0 END) `14:00`,
SUM(CASE WHEN HOUR(time) = 16 THEN Value ELSE 0 END) `16:00`,
SUM(CASE WHEN HOUR(time) = 18 THEN Value ELSE 0 END) `18:00`,
SUM(CASE WHEN HOUR(time) = 20 THEN Value ELSE 0 END) `20:00`,
SUM(CASE WHEN HOUR(time) = 22 THEN Value ELSE 0 END) `22:00`
FROM your_table
GROUP BY id_mst_tag
But still, if you have that "OFF" is there in the database, you can try this following option with one additional level of data casting as below-
SELECT id_mst_tag,
SUM(CASE WHEN HOUR(time) = 14 THEN (CASE WHEN Value = 'OFF' THEN 0 ELSE CONVERT(Value,UNSIGNED INTEGER) END) ELSE 0 END) `14:00`,
SUM(CASE WHEN HOUR(time) = 16 THEN (CASE WHEN Value = 'OFF' THEN 0 ELSE CONVERT(Value,UNSIGNED INTEGER) END) ELSE 0 END) `16:00`,
SUM(CASE WHEN HOUR(time) = 18 THEN (CASE WHEN Value = 'OFF' THEN 0 ELSE CONVERT(Value,UNSIGNED INTEGER) END) ELSE 0 END) `18:00`,
SUM(CASE WHEN HOUR(time) = 20 THEN (CASE WHEN Value = 'OFF' THEN 0 ELSE CONVERT(Value,UNSIGNED INTEGER) END) ELSE 0 END) `20:00`,
SUM(CASE WHEN HOUR(time) = 22 THEN (CASE WHEN Value = 'OFF' THEN 0 ELSE CONVERT(Value,UNSIGNED INTEGER) END) ELSE 0 END) `22:00`
FROM your_table
GROUP BY id_mst_tag;

Related

MySQL- Count total records based on different values of same column

I have a table as follows
table_user
id name status flag country
====================================================================================================
1 AB 1 0 US
2 BC 1 0 UK
3 CD 0 0 IN
4 DE 3 0 BR
5 EF 3 0 UK
6 FG 2 0 IN
7 GH 4 0 IN
I want to count the no. of records where
status = 1 as totalactiverecords,
status = 0 as totalinactiverecords,
status = 3 as totalrecentactiverecords,
status = 2 as totalemailnotverifiedrecords,
status = 4 as totalemailverifiedrecords,
, and country is UK, all in a single SELECT statement.
Is there any specific way to do it?
I have thought of something like
SELECT COUNT(*) as totalactiverecords WHERE status=1
COUNT(*) as totalinactiverecordsWHERE status=0,
COUNT(*) as totalemailnotverifiedrecords WHERE status=2,
COUNT(*) as totalrecentactiverecords WHERE status=3,
COUNT(*) as totalemailverifiedrecords WHERE status=4
FROM table_user where country=IN
,but that does not seem to work.
You can try this query:
SELECT count(case status when '1' then 1 else null end) as totalactiverecords,
count(case status when '0' then 1 else null end) as totalinactiverecords,
count(case status when '2' then 1 else null end) as totalemailnotverifiedrecords,
count(case status when '3' then 1 else null end) as totalrecentactiverecords,
count(case status when '4' then 1 else null end) as totalemailverifiedrecords
FROM table_user where country='IN'
I usually use CASE WHEN in this kind of problem:
SELECT sum(case when status = 1 then 1 end) as totalactiverecords,
COUNT sum(case when status = 0 then 1 end) as totalinactiverecords,
COUNT sum(case when status = 2 then 1 end) as totalemailnotverifiedrecord,
COUNT sum(case when status = 3 then 1 end) as totalrecentactiverecords,
COUNT sum(case when status = 4 then 1 end) as totalemailverifiedrecords
FROM table_user where country=IN

NULL values populating when trying to calculate a percentage in MYSQL

SELECT
SUM(CASE WHEN Reason = 'Forced' then 1 Else 0 end) Total_Number_Forced_Outage_Events,
COUNT(*) - 'Total_Number_Forced_Outage_Events' AS Total_Number_Outage_Events,
ROUND(('Total_Number_Forced_Outage_Events' / 'Total_Number_Outage_Events') * 100) AS Forced_Outage_Percentage,
YEAR(Start_Time) as Year
FROM AEMR
WHERE Status = 'Approved'
GROUP BY
Reason,
YEAR(Start_Time)
ORDER BY
YEAR(Start_Time),
Reason
OUTPUT
Total_Number_Forced_Outage_Events
Total_Number_Outage_Events
Forced_Outage_Percentage
Year
0
181
NULL
2016
1264
1264
NULL
2016
0
106
NULL
2016
0
380
NULL
2016
0
127
NULL
2017
1622
1622
NULL
2017
0
102
NULL
2017
0
320
NULL
2017
You can use coalesce() to replace NULL values with 0:
SELECT
SUM(CASE WHEN Reason = 'Forced' then 1 Else 0 end) Total_Number_Forced_Outage_Events,
COUNT(*) - Coalesce('Total_Number_Forced_Outage_Events',0) AS Total_Number_Outage_Events,
ROUND((Coalesce('Total_Number_Forced_Outage_Events',0) / Coalesce('Total_Number_Outage_Events',0)) * 100) AS Forced_Outage_Percentage,YEAR(Start_Time) as Year
FROM AEMR
WHERE Status = 'Approved'
GROUP BY
Reason,
YEAR(Start_Time)
ORDER BY
YEAR(Start_Time), Reason
You used column aliases in same select list I don't know which database allow it so I am changing the query:
SELECT
SUM(CASE WHEN Reason = 'Forced' then 1 Else 0 end) Total_Number_Forced_Outage_Events,
COUNT(*) - SUM(CASE WHEN Reason = 'Forced' then 1 Else 0 end) AS Total_Number_Outage_Events,
ROUND((SUM(CASE WHEN Reason = 'Forced' then 1 Else 0 end) / (COUNT(*) - SUM(CASE WHEN Reason = 'Forced' then 1 Else 0 end))) * 100,0) AS Forced_Outage_Percentage,YEAR(Start_Time) as Year
FROM AEMR
WHERE Status = 'Approved'
GROUP BY
Reason,
YEAR(Start_Time)
ORDER BY
YEAR(Start_Time), Reason
SELECT
SUM(CASE WHEN Reason = 'Forced' THEN 1 ELSE 0 END) Total_Number_Forced_Outage_Events
,Count(*) as Total_Number_Outage_Events
,CAST((CAST(SUM(CASE WHEN Reason = 'Forced' THEN 1 ELSE 0 END)AS DECIMAL(18,2))/CAST(Count(*)
AS DECIMAL(18,2)))*100 AS DECIMAL(18,2)) as Forced_Outage_Percentage
,Year(Start_Time) as Year
FROM
AEMR
WHERE Status = 'Approved'
GROUP BY
Year(Start_Time)

mysql - sums per month and year

i have an mysql table with the following structure:
tblapp
app_id app_date app_price app_price_paid payment_id receipt_id expenses_enabled
1 01/01/2000 100 50 1 1 1
1 11/01/2000 10 20 3 2 0
1 21/01/2000 40 40 1 4 0
1 30/01/2000 30 30 2 1 1
I would like to have as columns
YEAR DETAILS Jan Feb ... Dec TOTALS
and rows
1. Price = sum app_price where expenses_enabled=1
2. PricePaid = sum app_price_paid where expenses_enabled=1
3. No = sum app_price where expenses_enabled=1 and receipt_id=1
3. Yes = sum app_price where expenses_enabled=1 and receipt_id=0
Desire output:
Year Details Jan Feb ... Dec Totals
2020 Price 130 0 ... 0 130
2020 Price_Paid 80 0 ... 0 80
2020 No 80 0 ... 0 80
2020 Yes 0 0 ... 0 0
Is it possible.
Try this one:
select
y.year,
d.details,
sum(case when month(app_date) = 1 then val else 0 end) month_01,
sum(case when month(app_date) = 2 then val else 0 end) month_02,
sum(case when month(app_date) = 3 then val else 0 end) month_03,
sum(case when month(app_date) = 4 then val else 0 end) month_04,
sum(case when month(app_date) = 5 then val else 0 end) month_05,
sum(case when month(app_date) = 6 then val else 0 end) month_06,
sum(case when month(app_date) = 7 then val else 0 end) month_07,
sum(case when month(app_date) = 8 then val else 0 end) month_08,
sum(case when month(app_date) = 9 then val else 0 end) month_09,
sum(case when month(app_date) = 10 then val else 0 end) month_10,
sum(case when month(app_date) = 11 then val else 0 end) month_11,
sum(case when month(app_date) = 12 then val else 0 end) month_12,
sum(case when month(app_date) > 0 then val else 0 end) total
FROM (
SELECT 'Price' details UNION ALL
SELECT 'PricePaid' details UNION ALL
SELECT 'No' details UNION ALL
SELECT 'Yes' details
) d cross join (
SELECT distinct year(app_date) yr
FROM tblapp
) y
left join (
select app_date, COALESCE(app_price, 0) val, 'Price' details from tblapp
WHERE expenses_enabled = 1
union all
select app_date, COALESCE(app_price_paid, 0) val, 'PricePaid' details from tblapp
WHERE expenses_enabled = 1
union all
select app_date, COALESCE(app_price, 0) val, 'No' details from tblapp
WHERE expenses_enabled = 1 and receipt_id = 1
union all
select app_date, COALESCE(app_price, 0) val, 'Yes' details from tblapp
WHERE expenses_enabled = 1 and receipt_id = 0
) t on year(t.app_date) = y.year and t.details = d.details
group by y.year, d.details
order by y.year desc;

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))

Multiple rows into one field on GROUPED results Mysql

I have a query results like this.
status count
-----------------
OTHER 5
ATTENDED 74
I want result like this:
OTHERS ATTENDED
5 74
Note this is already a grouped result. So I am thinking, Group_Concat might not work.
Query:
SELECT CASE Rstat WHEN 1 THEN 'ATTENDED'
WHEN 2 THEN 'TENTATIVE'
WHEN 3 THEN 'REJECTED'
WHEN 4 THEN 'OUTSTANDING'
WHEN 6 THEN 'ACCEPTED' ELSE 'OTHER' END AS 'status',
COUNT(Rstat) AS 'count'
FROM `eStatus`
GROUP BY RSTAT
Any other ideas?
SELECT SUM(CASE WHEN Rstat = 1 THEN 1 ELSE 0 END) AS ATTENDED,
SUM(CASE WHEN Rstat = 2 THEN 1 ELSE 0 END) AS TENTATIVE,
SUM(CASE WHEN Rstat = 3 THEN 1 ELSE 0 END) AS REJECTED,
SUM(CASE WHEN Rstat = 4 THEN 1 ELSE 0 END) AS OUTSTANDING,
SUM(CASE WHEN Rstat = 6 THEN 1 ELSE 0 END) AS ACCEPTED,
SUM(CASE WHEN Rstat NOT IN (1,2,3,4,6) THEN 1 ELSE 0 END) AS OTHER
FROM eStatus