I'm using php with Mysql and I need to run a specific query when user selects month and year in a date_field.
This query returns all records created by the month/year selected by user and I don't want relate days in a clause where inside the select.
Since I need only records from month/year select, is there any ways how can I define inside the select only month/year?
Here is my Mysql statement with variable selected by user
There are two tables related with inner join so I can 'grab' records with Date:
$quer_mesano = "Select b.name AS Canal
from canal_canalvenda b
inner join meta_meta c On c.canal_canalvenda_id_c = b.id
And c.deleted = 0
where c.periodo = '$month_year' //Here is the date value I just need to put in month/year
And b.deleted = 0
Group by Canal order by 1";
Can any one help me?
This is very easy. Use DATE_FORMAT. Just change the Sql statement like this:
$quer_mesano = "Select b.name AS Canal
from canal_canalvenda b
inner join meta_meta c On c.canal_canalvenda_id_c = b.id
And c.deleted = 0
where DATE_FORMAT( c.periodo, '%Y-%m' ) = '$month_year' //Just put DATE_FORMAT
And b.deleted = 0
Group by Canal order by 1";
DATE_FORMAT() you can use as shown below
$quer_mesano = "Select b.name AS Canal
from canal_canalvenda b
inner join meta_meta c On c.canal_canalvenda_id_c = b.id
And c.deleted = 0
where DATE_FORMAT( c.periodo, '%Y/%m' ) = '$month_year'
And b.deleted = 0
Group by Canal order by 1";
For month you have different types -
%M Month name
%m Month, numeric (00-12)
and for year -
%Y Year, four digits
%y Year, two digits
I convert the month year to YYYY-MM formate where it can be compared with the db.
$quer_mesano = "Select b.name AS Canal
from canal_canalvenda b
inner join meta_meta c On c.canal_canalvenda_id_c = b.id
And c.deleted = 0
where DATE_FORMAT( c.periodo, '%Y-%m' ) = '" . date("Y-m", strtotime($month_year)) . "' //Here is the date value I just need to put in month/year
And b.deleted = 0
Group by Canal order by 1";
Related
I am making a Query for a project that I am working on.
I have to make a query that shows me the dates from Today and the dates that will still come. At the moment my Query is this:
$query = "SELECT * FROM systeem
RIGHT JOIN vestiging ON vestiging.id = systeem.vestigingID
LEFT JOIN systeemMeldkamer ON systeemMeldkamer.systeemID = systeem.id
LEFT JOIN meldkamers ON meldkamers.id = systeemMeldkamer.meldkamerID
LEFT JOIN systeemContract ON systeemContract.systeemID = systeem.id
LEFT JOIN onderhoudsLog ON onderhoudsLog.systeemContractID = systeemContract.id
LEFT JOIN contracten ON contracten.ident = systeemContract.contractIDENT
WHERE onderhoudsLog.onderhoudsDatum LIKE '2017%'
ORDER BY onderhoudsLog.onderhoudsDatum ASC";
This Query will give me all dates that look like "2017%".
Instead I want to get the date of today and every date that will come after the date of today:
today it is : 2018-03-05
The result that I want to get: 2018-03-05, 2018-03-06, 2018-03-07
Tomorrow It is: 2018-03-06 And then it has to search for all dates after 2018-03-06
I hope any one can help with my query! Don't mind the "LEFT JOINS", it is because I have to go through 6 tables so I can match the date for maintenance with the number if our customer.
For MySQL, you can use below query. Add where clause like: WHERE onderhoudsLog.onderhoudsDatum >= CURDATE()
Assuming that onderhoudsDatum field is datetime datatype
$query = "SELECT * FROM systeem
RIGHT JOIN vestiging ON vestiging.id = systeem.vestigingID
LEFT JOIN systeemMeldkamer ON systeemMeldkamer.systeemID = systeem.id
LEFT JOIN meldkamers ON meldkamers.id = systeemMeldkamer.meldkamerID
LEFT JOIN systeemContract ON systeemContract.systeemID = systeem.id
LEFT JOIN onderhoudsLog ON onderhoudsLog.systeemContractID = systeemContract.id
LEFT JOIN contracten ON contracten.ident = systeemContract.contractIDENT
WHERE onderhoudsLog.onderhoudsDatum >= CURDATE()
ORDER BY onderhoudsLog.onderhoudsDatum ASC";
You could try this code
$today = date('Y-m-d');
$query = "SELECT * FROM systeem
RIGHT JOIN vestiging ON vestiging.id = systeem.vestigingID
LEFT JOIN systeemMeldkamer ON systeemMeldkamer.systeemID = systeem.id
LEFT JOIN meldkamers ON meldkamers.id = systeemMeldkamer.meldkamerID
LEFT JOIN systeemContract ON systeemContract.systeemID = systeem.id
LEFT JOIN onderhoudsLog ON onderhoudsLog.systeemContractID = systeemContract.id
LEFT JOIN contracten ON contracten.ident = systeemContract.contractIDENT
WHERE onderhoudsLog.onderhoudsDatum => $today
ORDER BY onderhoudsLog.onderhoudsDatum ASC";
You get the date using PHP's date() function, format it as a MySql date string and then use that on the query:
WHERE onderhoudsLog.onderhoudsDatum => $today
is the onderhoudsLog.onderhoudsDatum date field then use '>=CURRENT_DATE' Instead 'like "2017%"' and order by onderhoudsLog.onderhoudsDatum
I have this query:
$sql = "SELECT m.id FROM members m
LEFT JOIN orders o ON o.user_id = m.id AND
YEAR(date) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH) AND
MONTH(date) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
LEFT JOIN transactions t ON t.user_id = o.user_id";
I need to get sum of transactions.points, so I do this:
$sql = "SELECT m.id, COALESCE(SUM(t.points), 0) AS total_points FROM members m
LEFT JOIN orders o ON o.user_id = m.id AND
YEAR(date) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH) AND
MONTH(date) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
LEFT JOIN transactions t ON t.user_id = o.user_id";
But when i execute this, I will get only rows with some transactions (and orders). What I must to do for getting 0 as total_points when no transactions found?
Text description: I want to get sum of points reward (from transactions table) of orders (orders table), where order was created in last month.
Thanks!
Get the sum of points per user and use it in the left join to get 0 when the user has no transactions.
SELECT m.id, COALESCE(t.total_points, 0) AS total_points
FROM members m
LEFT JOIN orders o ON o.user_id = m.id AND
/* use this instead of functions which prevent indexes on the date column from being used */
o.date >= date '2016-11-01' AND o.date <= date '2016-11-30'
LEFT JOIN (select user_id, SUM(points) total_points
from transactions group by user_id) t ON t.user_id = o.user_id
You need to add a GROUP BY clause to your query without which you are actually performing SUM() on the entire resultset. Not sure on which column but say on m.id
$sql = "SELECT m.id, COALESCE(SUM(t.points), 0) AS total_points FROM members m
LEFT JOIN orders o ON o.user_id = m.id AND
YEAR(date) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH) AND
MONTH(date) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
LEFT JOIN transactions t ON t.user_id = o.user_id
GROUP BY m.id";
$listSQL = "SELECT op.name as prodname,count(*) total
FROM oc_order_product op
INNER JOIN oc_order o ON op.order_id = o.order_id
INNER JOIN oc_product_to_category p2c ON op.product_id = p2c.product_id
INNER JOIN oc_category_description cd ON cd.category_id = p2c.category_id ";
$listSQL = $listSQL."where lower(cd.name) LIKE '%".$category_name."%'
AND YEAR(o.date_added) = '".$StartDate."'
AND o.order_status_id > '0' ";
$listSQL = $listSQL."GROUP BY op.name ORDER BY o.date_added ASC";
I have this query where i am displaying product names and count by year.
I want to display Product name, and for each product, show month and count for that month for that particular year.
for example for year 2015, show all 12 months and under which show count of products for that month.
Thanks
Your original query looks pretty close, but using non-grouped, non-aggregated fields "outside" a group by is usually not a good idea unless they came from a table whose full primary key was part of the group by list. That said, this should give you what you want.
SELECT op.name AS prodname
, YEAR(o.date_added) AS oYear
, MONTH(o.date_added) AS oMonth
, COUNT(DISTINCT o.order_id) AS numOfOrders
FROM ...
GROUP BY prodname, oYear, oMonth
ORDER BY prodname, oYear, oMonth
;
[...] being your original FROM and WHERE
I am attempting to count the number of new leads and the number of closed leads in any given month. The query below returns the month array correctly, but then only counts 1 if there are any leads or closes in the months, instead of the actual number that happened in that month. Any ideas what I am doing wrong?
query:
$productSql = "SELECT months.monthnum as monthnum, COUNT(contacts.lead_date) as lead_date_month, COUNT(contacts.close_date) as close_date_month, contacts.rep as rep
FROM months
LEFT JOIN contacts
ON months.monthnum = MONTH(contacts.lead_date)
AND months.monthnum = MONTH(contacts.close_date)
AND contacts.compid='$compid'
AND YEAR(contacts.lead_date) = '$year'
AND YEAR(contacts.close_date) = '$year'
AND contacts.rep = '$rep'
GROUP BY months.monthnum
ORDER BY months.monthnum ASC";
$productResult = mysql_query($productSql, $link) or die(mysql_error());
$label[] = $productRow['monthnum'];
$lead[] = $productRow['lead_date_month'];
$close[] = $productRow['close_date_month'];
};
echo "[".json_encode($label).",".json_encode($lead).",".json_encode($close)."]";
result:
[["January","February","March","April","May","June","July","August","September","October","November","December"],
["0","0","0","0","0","0","0","0","1","1","0","0"],
["0","0","0","0","0","0","0","0","1","1","0","0"]]
**Please don't chastise me for using mysql. I am dumping it as soon as this project is finished.
The way you build your JOIN condition you will get results only from records with MONTH(contacts.lead_date) = MONTH(contacts.close_date).
To fix that and to get your actual Count I would suggest splitting the statement into two queries:
SELECT
a.monthnum,
a.lead_date_month, b.close_date_month,
b.close_date_month / a.lead_date_month
FROM
(
-- Count number of new leads
SELECT
months.monthnum as monthnum,
COUNT(*) as lead_date_month,
contacts.rep as rep
FROM
months
LEFT JOIN contacts
ON
months.monthnum = MONTH(contacts.lead_date)
AND contacts.compid='$compid'
AND YEAR(contacts.lead_date) = '$year'
AND contacts.rep = '$rep'
GROUP BY
months.monthnum
ORDER BY
months.monthnum ASC
) as a
JOIN
(
-- Count number of closed leads
SELECT
months.monthnum as monthnum,
COUNT(*) as close_date_month,
contacts.rep as rep
FROM
months
LEFT JOIN contacts
ON
months.monthnum = MONTH(contacts.close_date)
AND contacts.compid='$compid'
AND YEAR(contacts.close_date) = '$year'
AND contacts.rep = '$rep'
GROUP BY
months.monthnum
ORDER BY
months.monthnum ASC
) as b
ON a.monthnum = b.monthnum
And MySQL isn't that bad. But MariaDB is better, you are right :-)
I have the following COUNT functionality working successfully in this query. I'd like to issue the exact same COUNT/Left Join functionality on another table (same format) called HTG_ScheduledActual
This works:
$query_WADAHTG_TechProps = "SELECT
HTG_TechProps.EmpNumber, HTG_TechProps.EmpFirstName, HTG_TechProps.EmpLastName, HTG_TechProps.Veh_Number,
COUNT(HTG_ScheduleRequest.ID) AS current_job FROM HTG_TechProps
LEFT JOIN HTG_ScheduleRequest ON HTG_TechProps.EmpNumber = HTG_ScheduleRequest.SSR
AND (HTG_ScheduleRequest.ScheduleDateOriginal = CURDATE()
OR HTG_ScheduleRequest.ScheduleDateCurrent = CURDATE()
OR HTG_ScheduleRequest.ScheduleDateExact = CURDATE() ) GROUP BY HTG_TechProps.EmpNumber
ORDER BY HTG_TechProps.EmpNumber ASC
";
I try to insert a second COUNT using AND and it breaks the query. I have bad feeling I can't issue two COUNT in the same query? How is the best way to overcome this?
$query_WADAHTG_TechProps = "SELECT
HTG_TechProps.EmpNumber, HTG_TechProps.EmpFirstName, HTG_TechProps.EmpLastName, HTG_TechProps.Veh_Number,
COUNT(HTG_ScheduleRequest.ID) AS current_job FROM HTG_TechProps
LEFT JOIN HTG_ScheduleRequest ON HTG_TechProps.EmpNumber = HTG_ScheduleRequest.SSR
AND (HTG_ScheduleRequest.ScheduleDateOriginal = CURDATE()
OR HTG_ScheduleRequest.ScheduleDateCurrent = CURDATE()
OR HTG_ScheduleRequest.ScheduleDateExact = CURDATE() ) GROUP BY HTG_TechProps.EmpNumber
AND COUNT(HTG_ScheduleActual.ID) AS actual_job FROM HTG_TechProps
LEFT JOIN HTG_ScheduleActual ON HTG_TechProps.EmpNumber = HTG_ScheduleActual.SSR
AND (HTG_ScheduleActual.ScheduleDateOriginal = CURDATE()
OR HTG_ScheduleActual.ScheduleDateCurrent = CURDATE()
OR HTG_ScheduleActual.ScheduleDateExact = CURDATE() ) GROUP BY HTG_TechProps.EmpNumber
ORDER BY HTG_TechProps.EmpNumber ASC
";