Mysql retrieve orders from last year in the same month as today - mysql

I have a table orders and I would like to make a request to retrieve all orders from the month of last year to the same month as now. Example: we are in November, I would like to recover all the orders of the month of November 2017.
I try something like that but it does not work:
SELECT COUNT(*)
FROM ps_orders o
WHERE YEAR(o.date_add) = YEAR(NOW() - INTERVAL 1 YEAR)
AND MONTH(o.date_add) = MONTH(NOW() - INTERVAL 1 MONTH)
Thank you for your help

You dont need to subtract the month. It should be MONTH(NOW()) to get the same month results from the previous year.
SELECT COUNT(*)
FROM ps_orders o
WHERE YEAR(o.date_add) = YEAR(NOW() - INTERVAL 1 YEAR)
AND MONTH(o.date_add) = MONTH(NOW()) -- same as current month

I would recommend doing this with date ranges:
SELECT COUNT(*)
FROM ps_orders o
WHERE o.date_add >= (curdate() - interval (day - 1) day) - interval 12 month AND
o.date_add >= (curdate() - interval (day - 1) day) - interval 11 month ;
When you use functions such as YEAR() and MONTH() the optimizer will not take full advantage of an available index on date_add. However, this version can use an appropriate index.

Related

How DO I fetch last Week and current week

How do I fetch last week data from monday time (00:00:01) and end on sunday time (23:59:59)...
same as this current week from monday time (00:00:01) and end on sunday time (23:59:59)
WHat I tried!
$query = "SELECT users.name,count(*) as count,
campaign.campaign_name,
campaign.payout_cost*count(*) as totalPrice
FROM users
JOIN transactions on users.uid=transactions.uid
JOIN campaign on campaign.campaign_id_id=transactions.campaign_id
WHERE uid=$uid
AND `date` >= DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())+6 DAY)
AND `date` < DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())-1 DAY)
GROUP BY campaign.campaign_name_name ";
You are on the right track by avoiding functions like week() on the column -- that just messes up the optimizer. On the other hand, the uid parameter should be passed as a parameter rather than munging the query string.
You want to use the weekday() function because you want weeks to start on a Monday. Just some arcaneness of MySQL: weekday() returns 0 for Monday whereas dayofweek() returns 2 for Monday.
So, the logic for the current week would be:
date >= curdate() - interval weekday(curdate()) day and
date < curdate() + interval 7 - weekday(curdate()) day
For last week, this would be:
date >= curdate() - interval 7 + weekday(curdate()) day and
date < curdate() + interval - weekday(curdate()) day
Notes that curdate() (or current_date) returns the current date with no time component, so no date() is required.
Couple of ways to do it...
select data from tableName
where date between date_sub(now(),INTERVAL 1 WEEK) and now();
select data FROM tableName
wherdate >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY
You can use WEEK() function, which returns the week number for a given date, by adding
AND WEEK(date-INTERVAL 1 DAY) = WEEK(NOW()) - 1 to get current week's data starting from monday upto sunday,
and
AND WEEK(date-INTERVAL 1 DAY) = WEEK(NOW()) - 2 for the previous week's data
into the WHERE condition after WHERE uid=$uid
such as
$query = "SELECT c.campaign_name,
COUNT(*) as total_count,
SUM(c.payout_cost) as total_payout
FROM transactions t
JOIN campaign c
ON c.campaign_id = t.campaign_id
WHERE uid = $uid
AND WEEK(date - INTERVAL 1 DAY) = WEEK(NOW()) - 1
GROUP BY c.campaign_name ";
and replace WEEK(NOW()) - 1 with WEEK(NOW()) - 2, also
Demo

MySQL (now() - Interval 1 Month) for this year only

I need some help with this.
I have the following SQL statement
SELECT * FROM table
WHERE MONTH(ORDERDATE) = MONTH(NOW() - INTERVAL 1 MONTH)
The problem is that it is returning data from last month but for all years... Am I doing something wrong or is this a normal issue that people face with this function?
The problem I am facing is that if I use the YEAR(NOW()) the report I am writing will not show the data for 2016 when we hit 2017. I'm trying to write a 6 month sales history report.
Any guidance would be appreciated.
Added Information
SELECT * FROM DATA_WH.SALESORD_HDR WHERE MONTH(ORDERDATE) = MONTH(NOW() - INTERVAL 1 MONTH)
RETURNS....
'2015-08-14 00:00:00'
Try using DATE_SUB with BETWEEN:
SELECT *
FROM DATA_WH.SALESORD_HDR
WHERE ORDERDATE BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND
DATE_SUB(NOW(), INTERVAL 2 MONTH)
This avoids the problem of having to deal with boundary conditions when using MONTH and YEAR.
Edit:
The above query will return records whose order date is between one and two months old. If you want to identify orders from the previous calendar month, then you will have to do a bit more work. Try this query:
SELECT *
FROM DATA_WH.SALESORD_HDR
WHERE ORDERDATE >= STR_TO_DATE(CONCAT('01-', LPAD(MONTH(DATE_SUB(NOW(), INTERVAL 1 MONTH)), 2, '0'), '-', YEAR(DATE_SUB(NOW(), INTERVAL 1 MONTH))), '%d-%m-%Y') AND
ORDERDATE < STR_TO_DATE(CONCAT('01-', LPAD(MONTH(NOW()), 2, '0'), '-', YEAR(NOW())), '%d-%m-%Y')
The strategy here is to build the date boundaries (August 1 and September 1 of 2016, as of the time of writing this answer), using the ORDERDATE.
Here is a Fiddle showing this logic in action:
SQLFiddle
I think you have to add another condition with AND with YEAR function
SELECT * FROM DATA_WH.SALESORD_HDR WHERE MONTH(ORDERDATE) = MONTH(NOW() - INTERVAL 1 MONTH) AND YEAR(ORDERDATE)= YEAR(NOW());
I have been working on this kind of queries recently:
This query will get the first day of the month and the last day of the month , also if you can carefully check the query you should be able to see that I have add a function from mysql that check the last day if the month "last_day(now())"
SELECT *
FROM DATA_WH.SALESORD_HDR
WHERE ORDERDATE BETWEEN date(concat(year(now()) , '-' ,month(now()) , '-01')) ,AND
date(concat(year(now()) , '-' ,month(now()) , '-' , day(last_day(now()))))
What about this?
SELECT * FROM table
WHERE MONTH(ORDERDATE) = MONTH(NOW() - INTERVAL 1 MONTH) and YEAR(ORDERDATE) = YEAR(NOW() - INTERVAL 1 MONTH)
This should only return rows where the order date is in the previous month.

mysql arithmetik operation (subtraction) last - first of the day(week, month)

i got a MySQL tbl, with some colums, where every 5 min. a new row is inserted with 3 values
1. Auto inc. curent Date Unix timestamp --> date
2. power consumption absolut --> wert01
3. Power Generation absolut --> wert02
To Show this Information in a Graph, for Exampl for weekly power consumption, i need to select the First and the last, which allready Works, but then have to Substract the last from the First and Show only tue result & the day of the werk.
SELECT
(SELECT wert01
FROM sml_splitt
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate()) DAY
ORDER BY date DESC LIMIT 1) AS 'last',
(SELECT wert01
FROM sml_splitt
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
AND date < curdate() - INTERVAL DAYOFWEEK(curdate()) DAY
ORDER BY date LIMIT 1) AS 'lirst
I am searching for some days to find a solution, but with no success.
Hopfuly, you could help me.
If you're happy with your query, then you can do the math by nesting it one more time like this: http://sqlfiddle.com/#!9/515ef/1
select t1.last, t1.first, t1.last - t1.first as result
from (
select (
select wert01
from sml_splitt
where dt >= curdate() - interval dayofweek(curdate()) + 6 day
and dt < curdate() - interval dayofweek(curdate()) day
order by dt desc limit 1
) as 'last',
(
select wert01
from sml_splitt
where dt >= curdate() - interval dayofweek(curdate()) + 6 day
and dt < curdate() - interval dayofweek(curdate()) day
order by dt limit 1
) as 'first'
) t1
;
If you really want to work with this data by week for reporting purposes, let me suggest a couple of views. The first will give you all of your distinct beginning of week dates:
create view v1 as
select date(dt) as week_begins
from sml_splitt
where dayofweek(dt) = 1
group by week_begins
The second view joins the first view with itself to give you a week beginning and week ending range:
create view v2 as
select t1.week_begins, coalesce(t2.week_begins,now()) as week_ends
from v1 t1
left join v1 t2
on t2.week_begins = t1.week_begins + interval 7 day
You can see the results here: http://sqlfiddle.com/#!9/a4d1b3/2. Notice that I'm using now() to get the current date and time if the week hasn't ended yet.
From there you can join your view with your original table and use min() and max() function with grouping to get the starting and ending 'wert' values and do any calculations on them that you like.
Here's an example: http://sqlfiddle.com/#!9/a4d1b3/6
select week_begins, week_ends,
min(wert01) as start_wert01,
max(wert01) as end_wert01,
max(wert01) - min(wert01) as power_consumed,
min(wert02) as start_wert02,
max(wert02) as end_wert02,
max(wert02) - min(wert02) as power_generated,
(max(wert02) - min(wert02)) - (max(wert01) - min(wert01)) as net_generated
from v2
inner join sml_splitt
on sml_splitt.dt >= v2.week_begins
and sml_splitt.dt < v2.week_ends
group by week_begins
I hope that helps.

HOW To get monthwise report of downloaded songs of last 1 year from current date in mysql

I want to get no of downloads per month from current date since last 1 year
This is my query
SELECT a.imei,
a.numberofdownloads,
a.numberofdownloads AS aug,
a.numberofstreams AS jul,
a.numberofdownloads AS jun,
a.numberofstreams,
b.datetime
FROM activeusers a,
imei_downloadstream b
WHERE a.imei = b.imei
AND b.datetime BETWEEN Date_format(Curdate() - INTERVAL 1 month,
'%Y-%m-01 00:00:00'
) AND
Date_format(Last_day(Curdate() -
INTERVAL 1 month),
'%Y-%m-%d 23:59:59')
AND Date_format(Last_day(Curdate() - INTERVAL 2 month),
'%Y-%m-%d 23:59:59')
AND Date_format(Last_day(Curdate() - INTERVAL 3 month),
'%Y-%m-%d 23:59:59')
LIMIT 10;
You are very close. You need a way to determine the first day of the month from the current date.
You have almost figured that out. It is this:
DATE(DATE_FORMAT(CURDATE(), '%Y-%m-01'))
Then you need to use a GROUP BY clause featuring that expression. Something like this will do it.
SELECT a.imei,
SUM(a.numberofdownloads) AS numberofdownloads,
DATE(DATE_FORMAT(b.datetime, '%Y-%m-01')) AS month_beginning
FROM activeusers a,
JOIN imei_downloadstream b ON a.imei = b.imei
WHERE b.datetime >= DATE(DATE_FORMAT(CURDATE(), '%Y-%m-01')) - INTERVAL 12 MONTH
AND b.datetime < DATE(DATE_FORMAT(CURDATE(), '%Y-%m-01'))
GROUP BY DATE(DATE_FORMAT(b.datetime, '%Y-%m-01')), a.imei
See what's going on here? You're choosing all the records having dates between the first of the month twelve months ago and the first of the present month. Then you're computing the beginning date of the month for each record, then you're grouping by that value.
This works flawlessly if you get your JOIN right. Here is a more detailed writelup.
http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/

comparing dates by month and year in mysql

I have a table containing data about events and festivals with following columns recording their start and end dates.
Start_Date
End_Date
date format is in YYYY-MM-DD. I need to fetch event details with the following condition.
Need to fetch all events which start with a current month and there end dates can be anything say currentDate+next30days.
I am clear about end date concept. but not sure how I can fetch data whose start dates are in a current month.
For this, I need to compare current year and current month against the Start_Date column in my database.
Can anyone help me to point out as how I can do that?
select * from your_table
where year(Start_Date) = year(curdate())
and month(Start_Date) = month(curdate())
and end_date <= curdate() + interval 30 day
I don't like either of the other two answers, because they do not let the optimizer use an index on start_date. For that, the functions need to be on the current date side.
So, I would go for:
where start_date >= date_add(curdate(), interval 1 - day(curdate()) day) and
start_date < date_add(date_add(curdate(), interval 1 - day(curdate()) day), interval 1 month)
All the date functions are on curdate(), which does not affect the ability of MySQL to use an index in this case.
You can also include the condition on end_date:
where (start_date >= date_add(curdate(), interval 1 - day(curdate()) day) and
start_date < date_add(date_add(curdate(), interval 1 - day(curdate()) day), interval 1 month)
) and
end_date <= date_add(curdate(), interval 30 day)
This can still take advantage of an index.
DateTime functions are your friends:
SELECT
*
FROM
`event`
WHERE
(MONTH(NOW()) = MONTH(`Start_Date`))
AND
(`End_Date` <= (NOW() + INTERVAL 30 DAY))
AND
(YEAR(NOW()) = YEAR(`Start_Date`))
Comparing the year and month separately feels messy. I like to contain it in one line. I doubt it will make a noticeable difference in performance, so its purely personal preference.
select * from your_table
where LAST_DAY(Start_Date) = LAST_DAY(curdate())
and end_date <= curdate() + interval 30 day
So all I'm doing is using the last_day function to check the last day of the month of each date and then comparing this common denominator. You could also use
where DATE_FORMAT(Start_Date ,'%Y-%m-01') = DATE_FORMAT(curdate(),'%Y-%m-01')