Set column value when grouped record is null - mysql

I have the following query which returns rows grouped.
For the column mc_name which returns a NULL value, is there any way to set a value without changing records data?
This is the query:
select
megaagents.megaagent_name AS 'mc_name',
SUM(IF(MONTH(properties.created_at) = 1, 1, 0)) as ENE,
SUM(IF(month(properties.created_at) = 2, 1, 0)) AS FEB,
SUM(IF(month(properties.created_at) = 3, 1, 0)) as MAR,
SUM(IF(month(properties.created_at) = 4, 1, 0)) AS ABR,
SUM(IF(month(properties.created_at) = 5, 1, 0)) AS MAY,
SUM(IF(month(properties.created_at) = 6, 1, 0)) as JUN,
SUM(IF(month(properties.created_at) = 7, 1, 0)) as JUL,
SUM(IF(month(properties.created_at) = 8, 1, 0)) AS AGO,
SUM(IF(month(properties.created_at) = 9, 1, 0)) as SEP,
SUM(IF(month(properties.created_at) = 10, 1, 0)) as OCT,
SUM(IF(month(properties.created_at) = 11, 1, 0)) as NOV,
SUM(IF(month(properties.created_at) = 12, 1, 0)) as DIC,
COUNT(PROPERTIES.PROP_EXCLUSIVE) AS TOTAL
from
`properties`
left join `megaagents` on `properties`.`megaagent_id` = `megaagents`.`id`
where
`properties`.`marketcenter_id` = 11
and `properties`.`prop_exclusive` in ('No Exclusiva', 'Exclusiva')
and `properties`.`prop_transaction` in ('Alquiler Temporal', 'Alquiler', 'Venta')
group by
`megaagents`.`megaagent_name`
order by
`megaagents`.`megaagent_name` asc
Regards!

Use COALESCE():
select
coalesce(megaagents.megaagent_name, 'custom value') AS mc_name,
....................................................................

Related

Merge two rows into one with same columns and add columns values

I have two queries which return the same row structure in 2 rows:
mc_name ENE FEB MAR ABR MAY JUN JUL AGO SEP OCT NOV DIC TOTAL
TOTAL CANTIDAD 0 0 4 55 28 74 112 175 120 123 0 0 691
TOTAL CANTIDAD 0 0 0 0 0 1 2 3 8 7 0 0 21
With UNION I can return both rows but I need to merge both rows into one and add column values for each column expect the first one which is a reference.
How can I achieve this:
mc_name ENE FEB MAR ABR MAY JUN JUL AGO SEP OCT NOV DIC TOTAL
TOTAL CANTIDAD 0 0 4 55 28 75 114 178 128 130 0 0 712
Both queries, with UNION below:
select
'TOTAL CANTIDAD' AS 'mc_name',
SUM(IF(MONTH(properties.created_at) = 1, 1, 0)) as ENE,
SUM(IF(month(properties.created_at) = 2, 1, 0)) AS FEB,
SUM(IF(month(properties.created_at) = 3, 1, 0)) as MAR,
SUM(IF(month(properties.created_at) = 4, 1, 0)) AS ABR,
SUM(IF(month(properties.created_at) = 5, 1, 0)) AS MAY,
SUM(IF(month(properties.created_at) = 6, 1, 0)) as JUN,
SUM(IF(month(properties.created_at) = 7, 1, 0)) as JUL,
SUM(IF(month(properties.created_at) = 8, 1, 0)) AS AGO,
SUM(IF(month(properties.created_at) = 9, 1, 0)) as SEP,
SUM(IF(month(properties.created_at) = 10, 1, 0)) as OCT,
SUM(IF(month(properties.created_at) = 11, 1, 0)) as NOV,
SUM(IF(month(properties.created_at) = 12, 1, 0)) as DIC,
COUNT(PROPERTIES.PROP_EXCLUSIVE) AS TOTAL
from
`properties`
left join `megaagents` on `properties`.`megaagent_id` = `megaagents`.`id`
where
`properties`.`prop_currency` = 'USD'
and `properties`.`marketcenter_id` = 11
and `properties`.`prop_exclusive` in ('No Exclusiva', 'Exclusiva')
and `properties`.`prop_transaction` in ('Alquiler Temporal', 'Alquiler', 'Venta')
UNION
select
'TOTAL CANTIDAD' AS 'mc_name',
SUM(IF(MONTH(properties.created_at) = 1, 1, 0)) as ENE,
SUM(IF(month(properties.created_at) = 2, 1, 0)) AS FEB,
SUM(IF(month(properties.created_at) = 3, 1, 0)) as MAR,
SUM(IF(month(properties.created_at) = 4, 1, 0)) AS ABR,
SUM(IF(month(properties.created_at) = 5, 1, 0)) AS MAY,
SUM(IF(month(properties.created_at) = 6, 1, 0)) as JUN,
SUM(IF(month(properties.created_at) = 7, 1, 0)) as JUL,
SUM(IF(month(properties.created_at) = 8, 1, 0)) AS AGO,
SUM(IF(month(properties.created_at) = 9, 1, 0)) as SEP,
SUM(IF(month(properties.created_at) = 10, 1, 0)) as OCT,
SUM(IF(month(properties.created_at) = 11, 1, 0)) as NOV,
SUM(IF(month(properties.created_at) = 12, 1, 0)) as DIC,
COUNT(PROPERTIES.PROP_EXCLUSIVE) AS TOTAL
from
`properties`
left join `users` on `properties`.`prop_capper_email` = `users`.`email_local_crm`
left join `team_user` on `users`.`id` = `team_user`.`user_id`
left join `teams` on `team_user`.`team_id` = `teams`.`id`
where
`properties`.`prop_currency` = 'USD'
and `properties`.`marketcenter_id` = 11
and `properties`.`prop_exclusive` in ('No Exclusiva', 'Exclusiva')
and `properties`.`prop_transaction` in ('Alquiler Temporal', 'Alquiler', 'Venta')
AND `teams`.`team_name` = 'Productividad'

optimizing mysql query with multiple sum(if(condition))

I have written a query which consists of multiple joins and sum(if()) condition.
I am using MySql Database.
The query structure seems like this:
*The query joins from multiple tables(7 to be precise) and the sum(if()) conditions is to represent total 53 states of US.*It takes almost 20 minutes for the query to execute which is a very long period.
If anyone could suggest how can I reduce this large amount of time.
SELECT ag.position_id AS 'position_id',
ag.npn AS 'NPN',
concat(ag.first_name, ' ', ag.last_name) AS 'full_name',
lb.name AS 'lob',
location_lic AS 'loc',
COUNT(DISTINCT lt.id) AS 'RTS_Total',
SUM(IF(st.id = 1, 1, 0)) AS 'AK',
SUM(IF(st.id = 2, 1, 0)) AS 'AL',
SUM(IF(st.id = 3, 1, 0)) AS 'AR',
SUM(IF(st.id = 4, 1, 0)) AS 'AZ',
SUM(IF(st.id = 5, 1, 0)) AS 'CA',
SUM(IF(st.id = 6, 1, 0)) AS 'CO',
SUM(IF(st.id = 7, 1, 0)) AS 'CT',
SUM(IF(st.id = 8, 1, 0)) AS 'DC',
SUM(IF(st.id = 9, 1, 0)) AS 'DE',
SUM(IF(st.id = 10, 1, 0)) AS 'FL',
SUM(IF(st.id = 11, 1, 0)) AS 'GA',
SUM(IF(st.id = 12, 1, 0)) AS 'HI',
SUM(IF(st.id = 13, 1, 0)) AS 'IA',
SUM(IF(st.id = 14, 1, 0)) AS 'ID',
SUM(IF(st.id = 15, 1, 0)) AS 'IL',
SUM(IF(st.id = 16, 1, 0)) AS 'IN',
SUM(IF(st.id = 17, 1, 0)) AS 'KS',
SUM(IF(st.id = 18, 1, 0)) AS 'KY',
SUM(IF(st.id = 19, 1, 0)) AS 'LA',
SUM(IF(st.id = 20, 1, 0)) AS 'MA',
SUM(IF(st.id = 21, 1, 0)) AS 'MD',
SUM(IF(st.id = 22, 1, 0)) AS 'ME',
SUM(IF(st.id = 23, 1, 0)) AS 'MI',
SUM(IF(st.id = 24, 1, 0)) AS 'MN',
SUM(IF(st.id = 25, 1, 0)) AS 'MO',
SUM(IF(st.id = 26, 1, 0)) AS 'MS',
SUM(IF(st.id = 27, 1, 0)) AS 'MT',
SUM(IF(st.id = 28, 1, 0)) AS 'NC',
SUM(IF(st.id = 29, 1, 0)) AS 'ND',
SUM(IF(st.id = 30, 1, 0)) AS 'NE',
SUM(IF(st.id = 31, 1, 0)) AS 'NH',
SUM(IF(st.id = 32, 1, 0)) AS 'NJ',
SUM(IF(st.id = 33, 1, 0)) AS 'NM',
SUM(IF(st.id = 34, 1, 0)) AS 'NV',
SUM(IF(st.id = 35, 1, 0)) AS 'NY',
SUM(IF(st.id = 36, 1, 0)) AS 'OH',
SUM(IF(st.id = 37, 1, 0)) AS 'OK',
SUM(IF(st.id = 38, 1, 0)) AS 'OR',
SUM(IF(st.id = 39, 1, 0)) AS 'PA',
SUM(IF(st.id = 40, 1, 0)) AS 'PR',
SUM(IF(st.id = 41, 1, 0)) AS 'RI',
SUM(IF(st.id = 42, 1, 0)) AS 'SC',
SUM(IF(st.id = 43, 1, 0)) AS 'SD',
SUM(IF(st.id = 44, 1, 0)) AS 'TN',
SUM(IF(st.id = 45, 1, 0)) AS 'TX',
SUM(IF(st.id = 46, 1, 0)) AS 'UT',
SUM(IF(st.id = 47, 1, 0)) AS 'VA',
SUM(IF(st.id = 48, 1, 0)) AS 'VI',
SUM(IF(st.id = 49, 1, 0)) AS 'VT',
SUM(IF(st.id = 50, 1, 0)) AS 'WA',
SUM(IF(st.id = 51, 1, 0)) AS 'WI',
SUM(IF(st.id = 52, 1, 0)) AS 'WV',
SUM(IF(st.id = 53, 1, 0)) AS 'WY'
FROM cxprtsapp_licensetracker lt
INNER JOIN cxprtsapp_agents ag ON ag.id = lt.agent_id_id AND ag.position_status LIKE 'Active'
LEFT JOIN cxprtsapp_statelobjit slj ON slj.state_id = lt.state_id_id AND ag.lob_id = slj.lob_id
LEFT JOIN
(select npn, rtsreport_appointed, rtsreport_licensed, state_id, lob_id
from cxprtsapp_rtslob
order BY refresh_number desc
) rts ON rts.state_id = lt.state_id_id and ag.lob_id = rts.lob_id and ag.npn=rts.npn
INNER JOIN cxprtsapp_location lc ON lc.id = ag.loc_id
INNER JOIN cxprtsapp_lineofbussiness lb ON lb.id = ag.lob_id
INNER JOIN cxprtsapp_states st ON st.id = lt.state_id_id
LEFT JOIN
(SELECT DISTINCT npn, state_code, status
FROM cxprtsapp_pdbappointments
WHERE status LIKE 'Appointed'
) appt ON appt.npn = ag.npn AND appt.state_code = st.state_code
WHERE certification_id IS NOT NULL
AND (expiration_date IS NULL OR expiration_date > CURDATE())
AND (slj.jit = 1 OR rts.rtsreport_appointed = 1 OR appt.status IS NOT NULL)
GROUP BY ag.id, ag.lob_id,loc_id ORDER BY ag.hire_date DESC;
Solution:
The time taken for the query has reduced from 10-15 min to 10-20 sec.
We must alter database index for performance.
we must the run the below sql query in the database first.
‌
ALTER TABLE cxprtsapp_agents ADD INDEX cxprtsapp_agents_idx_status_id_id_npn_id (position_status,id,lob_id,npn,loc_id);
ALTER TABLE cxprtsapp_licensetracker ADD INDEX cxprtsapp_licensetra_idx_id_id_id_id (agent_id_id,state_id_id,certification_id,id);
ALTER TABLE cxprtsapp_lineofbussiness ADD INDEX cxprtsapp_lineofbuss_idx_id_name (id,name);
ALTER TABLE cxprtsapp_location ADD INDEX cxprtsapp_location_idx_id_lic (id,location_lic);
ALTER TABLE cxprtsapp_statelobjit ADD INDEX cxprtsapp_statelobji_idx_id_id (state_id,lob_id);
ALTER TABLE cxprtsapp_states ADD INDEX cxprtsapp_states_idx_id_code (id,state_code);
ALTER TABLE cxprtsapp_rtslob ADD INDEX cxprtsapp_rtslob_idx_numbe_npn_appoi_licen_id_id (refresh_number,npn,rtsreport_appointed,rtsreport_licensed,state_id,lob_id);
ALTER TABLE cxprtsapp_pdbappointments ADD INDEX cxprtsapp_pdbappoint_idx_status_npn_code (status,npn,state_code);

get Month and Year in Colums // Mysql

I have the following Select in Mysql, which enables me to list an amount for each customer by month. It works fine as it is.
I would like to have in each column not only by month but also adding the corresponding year (instead of 'Jan' in Col 1, 'Jan 2015', 'Feb 2015' in Col 2, etc...)
Also, As a first line, how could I group the sum of the corresponding column to have this
Jan-2015 Feb-2015 Mar-2015
Total 1000 1600 ...
Customer1 100 800
Customer2 900 600
Customer3 0 200
How could I achieve this? I can have a Total line with PHP, but getting it in a Select would save me a lot of time...
Here is my initial select
SELECT
Customers,
sum(if(month(Date) = 1, Total_Deposits, 0)) AS Jan,
sum(if(month(Date) = 2, Total_Deposits, 0)) AS Feb,
sum(if(month(Date) = 3, Total_Deposits, 0)) AS Mar,
sum(if(month(Date) = 4, Total_Deposits, 0)) AS Apr,
sum(if(month(Date) = 5, Total_Deposits, 0)) AS May,
sum(if(month(Date) = 6, Total_Deposits, 0)) AS Jun,
sum(if(month(Date) = 7, Total_Deposits, 0)) AS Jul,
sum(if(month(Date) = 8, Total_Deposits, 0)) AS Aug,
sum(if(month(Date) = 9, Total_Deposits, 0)) AS Sep,
sum(if(month(Date) = 10, Total_Deposits, 0)) AS Oct,
sum(if(month(Date) = 11, Total_Deposits, 0)) AS Nov,
sum(if(month(Date) = 12, Total_Deposits, 0)) AS `Dec`
FROM Online_customer_activity_v2
where Date BETWEEN '2015-01-01' AND '2015-12-31'
Group by Customers
ORDER by sum(`Online_customer_activity_v2`.`Total_Deposits`) DESC
LIMIT 20
Thanks to everyone in advance for your tips!

How to SUM TIMEDIFF's During hours

I hope this can clearly explain what I am looking for. I have searched read through a few articles on this site, but haven't found what I am looking for. I have also spent close to 3 hours trying to figure this out on my own.
I am trying to count the number of records and SUM the WorkTime. Here is my query I have been working with.
SELECT Log.User
, sum(if(hour(endtime) = 0, 1, 0)) AS Midnight
, sum(if(hour(endtime) = 1, 1, 0)) AS `1AM`
, sum(if(hour(endtime) = 2, 1, 0)) AS `2AM`
, sum(if(hour(endtime) = 3, 1, 0)) AS `3AM`
, sum(if(hour(endtime) = 4, 1, 0)) AS `4AM`
, sum(if(hour(endtime) = 5, 1, 0)) AS `5AM`
, sum(if(hour(endtime) = 6, 1, 0)) AS `6AM`
, sum(if(hour(endtime) = 7, 1, 0)) AS `7AM`
, sum(if(hour(endtime) = 8, 1, 0)) AS `8AM`
, sum(if(hour(endtime) = 9, 1, 0)) AS `9AM`
, sum(if(hour(endtime) = 10, 1, 0)) AS `10AM`
, sum(if(hour(endtime) = 11, 1, 0)) AS `11AM`
, sum(if(hour(endtime) = 12, 1, 0)) AS `12PM`
, sum(if(hour(endtime) = 13, 1, 0)) AS `1PM`
, sum(if(hour(endtime) = 14, 1, 0)) AS `2PM`
, sum(if(hour(endtime) = 15, 1, 0)) AS `3PM`
, sum(if(hour(endtime) = 16, 1, 0)) AS `4PM`
, sum(if(hour(endtime) = 17, 1, 0)) AS `5PM`
, sum(if(hour(endtime) = 18, 1, 0)) AS `6PM`
, sum(if(hour(endtime) = 19, 1, 0)) AS `7PM`
, sum(if(hour(endtime) = 20, 1, 0)) AS `8PM`
, if(hour(endtime) = 20, sec_to_time(sum(time_to_sec(endtime) - time_to_sec(starttime))), 0) AS `8PM Time`
, sum(if(hour(endtime) = 21, 1, 0)) AS `9PM`
, sum(if(hour(endtime) = 22, 1, 0)) AS `10PM`
, sum(if(hour(endtime) = 23, 1, 0)) AS `11PM`
FROM
(
SELECT user
, controlnumber
, starttime
, endtime
, timediff(endtime, starttime) AS Worktime
FROM
atrtaxcert.ordertimeworked
) AS Log
GROUP BY
Log.User;
These start and end times are only minutes apart.
Any guidance is much appreciated. This is my first post here, and was not able to provide any images to help describe.
If starttime and endtime are TIME datatypes, then use the TIME_TO_SEC function and do a subtraction. Total up the seconds, and then convert the total to a string representation.
SELECT `Log`.`User`
, ...
, SUM(HOUR(`Log`.endtime)=20) AS `8PM_count`
, SUM(IF(HOUR(`Log`.endtime)=20,work_seconds,0) AS `8PM_seconds`
, SEC_TO_TIME(SUM(IF(HOUR(`Log`.endtime)=20,`Log`.work_seconds,0) AS `8PM_hhhmmss`
, ...
FROM ( SELECT
, TIME_TO_SEC(endtime)-TIME_TO_SEC(starttime) AS work_seconds
) `Log`
GROUP
BY `Log`.`User`
NOTE: this:
SELECT HOUR(endtime)=0 AS foo
is shorthand equivalent to
SELECT IF(HOUR(endtime) = 0, 1, 0) AS foo
If starttime and endtime are DATETIME values, the you can use the TIMESTAMPDIFF function to calculate the difference in seconds:
SELECT `Log`.`User`
, ...
, SUM(HOUR(`Log`.endtime)=20) AS `8PM_count`
, SUM(IF(HOUR(endtime)=20,TIMESTAMPDIFF(SECOND,`Log`.starttime,`Log`.endtime),0) AS `8PM_seconds`
, ...
FROM (
) `Log`
GROUP
BY `Log`.`User`
(You probably want to ignore the values returned when e.g. starttime = '23:59:00' and endtime = '00:01:00', and that would require another conditional test.)

Mysql filter query from drop down box

Good morning, I have the mysql query below to display the years sales which worked fine until the year changed as it now shows Jan 2012 & Jan 2013 combined.
To try to resolve I placed a drop down form box (id=YearSelect) with value of 2012 & 2013, is it possible I can control this query with the value selected? Should the end user select 2012 then that value would be sent to column Year as a type of where clause?
<form id="yearselect">
<select name="year">
<option value="">Select year </option>
<option value="2012">2012</option>
<option value="2013">2013</option>
</select>
</form>
Select
*,
If(q.Adviser Is Null, 1, 0) As remove
From
(Select
a.ContactFullName As Adviser,
YEAR(b.CaseDate) As Year,
Sum(If(Month(b.StatusSubmittedDate) = 1, b.CaseCommission, 0)) As Jan,
Sum(If(Month(b.StatusSubmittedDate) = 2, b.CaseCommission, 0)) As Feb,
Sum(If(Month(b.StatusSubmittedDate) = 3, b.CaseCommission, 0)) As Mar,
Sum(If(Month(b.StatusSubmittedDate) = 4, b.CaseCommission, 0)) As Apr,
Sum(If(Month(b.StatusSubmittedDate) = 5, b.CaseCommission, 0)) As May,
Sum(If(Month(b.StatusSubmittedDate) = 6, b.CaseCommission, 0)) As Jun,
Sum(If(Month(b.StatusSubmittedDate) = 7, b.CaseCommission, 0)) As Jul,
Sum(If(Month(b.StatusSubmittedDate) = 8, b.CaseCommission, 0)) As Aug,
Sum(If(Month(b.StatusSubmittedDate) = 9, b.CaseCommission, 0)) As Sep,
Sum(If(Month(b.StatusSubmittedDate) = 10, b.CaseCommission, 0)) As Oct,
Sum(If(Month(b.StatusSubmittedDate) = 11, b.CaseCommission, 0)) As Nov,
Sum(If(Month(b.StatusSubmittedDate) = 12, b.CaseCommission, 0)) As Decb,
Sum(b.CaseCommission) As Total
From
tblcontacts a Inner Join
tblcases b On a.ContactID = b.ContactAssignedTo
Where
WHERE Year(b.StatusSubmittedDate) = ".(int)$_POST['year']."
Group By
a.ContactFullName WITH ROLLUP
Having
Sum(b.CaseCommission) > 0.01) q
Order By
If(q.Adviser Is Null, 1, 0), q.Total Desc
Any advice appreciated.
What about changing this WHERE:
Where
b.StatusSubmittedDate > '2012 - 01 - 01'
to:
Where
YEAR(b.StatusSubmittedDate) = ".(int)$YEAR_VALUE_FROM_DROPDOWN."
That should be enough...
Considering the PHP tag I assume you are showing the results on a PHP bases page. You can use the following code to do what you want.
<form id="yearselect" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" >
<select name='selyear' onchange='document.getElementById("yearselect").submit()'>
<option value=''> - Select year </option>
<option value='2012'>2012</option>
<option value='2013'>2013</option>
</select>
</form>
<?
$y = date("Y");
if (isset($_POST['selyear']))
{
if (checkdate(1, 1, $_POST['selyear']) && $_POST['selyear']>=2012)
$y = $_POST['selyear'];
}
$query = 'Select
*,
If(q.Adviser Is Null, 1, 0) As remove
From
(Select
a.ContactFullName As Adviser,
YEAR(b.CaseDate) As Year,
Sum(If(Month(b.StatusSubmittedDate) = 1, b.CaseCommission, 0)) As Jan,
Sum(If(Month(b.StatusSubmittedDate) = 2, b.CaseCommission, 0)) As Feb,
Sum(If(Month(b.StatusSubmittedDate) = 3, b.CaseCommission, 0)) As Mar,
Sum(If(Month(b.StatusSubmittedDate) = 4, b.CaseCommission, 0)) As Apr,
Sum(If(Month(b.StatusSubmittedDate) = 5, b.CaseCommission, 0)) As May,
Sum(If(Month(b.StatusSubmittedDate) = 6, b.CaseCommission, 0)) As Jun,
Sum(If(Month(b.StatusSubmittedDate) = 7, b.CaseCommission, 0)) As Jul,
Sum(If(Month(b.StatusSubmittedDate) = 8, b.CaseCommission, 0)) As Aug,
Sum(If(Month(b.StatusSubmittedDate) = 9, b.CaseCommission, 0)) As Sep,
Sum(If(Month(b.StatusSubmittedDate) = 10, b.CaseCommission, 0)) As Oct,
Sum(If(Month(b.StatusSubmittedDate) = 11, b.CaseCommission, 0)) As Nov,
Sum(If(Month(b.StatusSubmittedDate) = 12, b.CaseCommission, 0)) As Decb,
Sum(b.CaseCommission) As Total
From
tblcontacts a Inner Join
tblcases b On a.ContactID = b.ContactAssignedTo
Where
b.StatusSubmittedDate > \''.$y.' - 01 - 01\'
AND b.StatusSubmittedDate < \''.$y.' - 12 - 31\'
Group By
a.ContactFullName WITH ROLLUP
Having
Sum(b.CaseCommission) > 0.01) q
Order By
If(q.Adviser Is Null, 1, 0), q.Total Desc'
//output results
?>
Now I didnt check your query as you mentioned it works. Also instead of posting the form on changing the select list, you could also alter it to use AJAX or whatever to make it better. But I guess you get the idea.
Also I now check for a valid year, not just 2012 or 2013. That depends on what you want.