Changing start-date in MySQL for week - mysql

I found the following code to help in creating a weekly report based on a start date of Friday. The instructions say to replace ".$startWeekDay." with a 4. When I put '".$startDay."' as '2013-01-30', I get errors.
Also I get a report by day rather than week as I desire.
SELECT SUM(cost) AS total,
CONCAT(IF(date - INTERVAL 6 day < '".$startDay."',
'".$startDay."',
IF(WEEKDAY(date - INTERVAL 6 DAY) = ".$startWeekDay.",
date - INTERVAL 6 DAY,
date - INTERVAL ((WEEKDAY(date) - ".$startWeekDay.")) DAY)),
' - ', date) AS week,
IF((WEEKDAY(date) - ".$startWeekDay.") >= 0,
TO_DAYS(date) - (WEEKDAY(date) - ".$startWeekDay."),
TO_DAYS(date) - (7 - (".$startWeekDay." - WEEKDAY(date)))) AS sortDay
FROM daily_expense
WHERE date BETWEEN '".$startDay."' AND '".$endDay."'
GROUP BY sortDay;
The following code is what I am using
SELECT count(DISTINCT (
UserID)
) AS total, CONCAT(IF(date(LastModified) - INTERVAL 6 day < date(LastModified),
date(LastModified),
IF(WEEKDAY(date(LastModified) - INTERVAL 6 DAY) = 4,
date(LastModified) - INTERVAL 6 DAY,
date(LastModified) - INTERVAL ((WEEKDAY(date(LastModified)) - 4)) DAY)),
' - ', date(LastModified)) AS week
FROM `Purchase`
WHERE `OfferingID` =87
AND `Status`
IN ( 1, 4 )
GROUP BY week
The output I get is
total week
3 2013-01-30 - 2013-01-30
1 2013-01-31 - 2013-01-31

I'm not sure exactly how you want to display your week, the sql above is attempting to display date ranges. If this isn't a requirement, your query could be very simple, you can just offset your time by two days (since friday is two days away from the natural star of the week) and use the week function to get the week number.
The query would look like this:
select count(distinct (UserID)) as total
, year( LastModified + interval 2 day ) as year
, week( LastModified + interval 2 day ) as week_number
FROM `Purchase`
WHERE `OfferingID` =87
AND `Status`
IN ( 1, 4 )
group by year, week_number;

Related

MYSQL: Getting all results from last week starting Monday)

CREATE TABLE `sport_data` (
`id` int(255) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`sport` varchar(255) NOT NULL,
`musclePlan` varchar(255) NOT NULL,
`sport_time` varchar(255) NOT NULL,
`kcal` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
How can i get all data from this table from the last week (from Monday to Sunday)?
I have tried:
WHERE date >= curdate() - INTERVAL DAYOFWEEK(curdate())+5 DAY AND date < curdate() - INTERVAL DAYOFWEEK(curdate())-2 DAY
I don't know if this is correct that way?
Thanks in advance.
The >= and < pattern is what we usually use. That part looks right.
I think the question is about the expressions that returning the range start and end values.
I suggest that we test those expressions for a variety of date values, not just CURDATE(). We can use a value in place of CURDATE(), and check the results, and do that for a series of date values.
Conveniently, those expressions will evaluate the same in a SELECT list as they do in a WHERE clause. So we can run a SELECT statement, and check the results.
For example:
SELECT t.dt AS dt
, t.dt - INTERVAL DAYOFWEEK(t.dt)+5 DAY AS _ge
, t.dt - INTERVAL DAYOFWEEK(t.dt)-2 DAY AS _lt
FROM (
SELECT CURDATE() + INTERVAL 0 DAY AS dt
UNION ALL SELECT CURDATE() + INTERVAL -1 DAY
UNION ALL SELECT CURDATE() + INTERVAL -2 DAY
UNION ALL SELECT CURDATE() + INTERVAL -3 DAY
UNION ALL SELECT CURDATE() + INTERVAL -4 DAY
UNION ALL SELECT CURDATE() + INTERVAL -5 DAY
UNION ALL SELECT CURDATE() + INTERVAL -6 DAY
UNION ALL SELECT CURDATE() + INTERVAL -7 DAY
UNION ALL SELECT CURDATE() + INTERVAL -8 DAY
UNION ALL SELECT CURDATE() + INTERVAL -9 DAY
UNION ALL SELECT CURDATE() + INTERVAL -10 DAY
) t
If the expressions are returning the values we expect, in accordance with the specification, for each possible date value, then the expressions are right.
If the expressions are returning values that don't meet the spec, then we need to make adjustments. Note that an expression that "works" on a Wednesday date might not "work" on a Sunday date.)
DEMO: Showing 3 approaches and why current doesn't work.
If we assume by "last week" you mean the last full week Monday - Sunday of a week prior to the day you're presently on...
So if today was 20180422, you'd want 20180409-20180415
SELECT *
FROM SO50026532_sport_data
CROSS JOIN (SELECT #Today:=curdate()) z
WHERE date >= #today - interval (6 + case when dayofweek(#today)=1 then 7 else dayofWeek(#today)-1 end) day
and date <=#today - interval (case when dayofweek(#today)=1 then 7 else dayofWeek(#today)-1 end) day;
Or if your a fan of the >= and < then
SELECT *
FROM SO50026532_sport_data
CROSS JOIN (SELECT #Today:=curdate()) z
WHERE date >= #today - interval (6 + case when dayofweek(#today)=1 then 7 else dayofWeek(#today)-1 end) day
and date <#today - interval (case when dayofweek(#today)=1 then 7 else dayofWeek(#today)-1 end-1) day;
in the 2nd example we had to subtract by 1 since dayofweek isn't a 0 based. Of course I could have just date shifted everything down 2 and set sunday to 6... then I wouldn't' need to subtract by 1. and then we'd be adding 7 instead of 6 on the 1st part of the where. (demo has these 3 and your initial example showing what happens on 4/22.
Dayofweek starts on Sunday being 1. So I use a case statement to shift 1 to 7 and and all the others down 1 giving us Monday = 1 and sunday = 7
The cross join to derived table z was so I could control the curdate() easier and test. You could replace the variable with curdate() if you want and eliminate the cross join and derived table.
The first where clause subtracts 6 days (1 week and then the # of days from current date back to monday. This ensures we always start 1 week back from current date and on a monday. then we only get dates to the Sunday of that week.

How do I find all data from a table in a specific month

I am trying to retrieve all data from table in a specific month, my date format in the database table is 2016-06-19 I am need to find with the respect of a selected date, like if I select 2016-05-22
it will retrieve 2016-05-07 to 2016-06-06 interval values from the table.
And also to all the values in this month which is 05 month, I am using mysqli with PHP. I have tried using this query
SELECT * FROM t_tenancy_details WHERE
agreement_date >= DATE_FORMAT( CURRENT_DATE - INTERVAL 1 MONTH, '%Y/%m/01' )AND
agreement_date < DATE_FORMAT( CURRENT_DATE, '%Y/%m/01' )
This works fine for the running month, But problem is that if I select a previous month it does not work.
It's not very clear from the question as to what is needed. Based on the 2 requirements that I could understand:
Get everything surrounding the given date (i.e. +-15 days from the given date):
SELECT *
FROM t_tenancy_details
WHERE agreement_date >= DATE_SUB(#d, INTERVAL 15 DAY)
AND agreement_date <= DATE_ADD(#d, INTERVAL 15 DAY);
Get all the records where the month is same as the month in the given date:
SELECT *
FROM t_tenancy_details
WHERE MONTH(agreement_date) = MONTH(#d)
AND YEAR(agreement_date) = YEAR(#d);
where #d is the input date, in your case - CURRENT_DATE
Should be this
SELECT * FROM t_tenancy_details
WHERE (YEAR(t_tenancy_details) => YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(agreement_date) => MONTH(CURRENT_DATE - INTERVAL 1 MONTH))
AND (YEAR(t_tenancy_details) <= YEAR(CURRENT_DATE)
AND MONTH(agreement_date) <= MONTH(CURRENT_DATE))

How do you calculate how many days in quarter in MYSQL?

I need help calculating the following in MYSQL
how many days in quarter based on current date in MYSQL?
If today is 8/27/2014 - how many days is that in the quarter?
Also how do I calculate how many days in a quarter between two dates in MYSQL?
If user chose 3/1/2014 - 8/27/2014 how many total days for those 3 quarters?
to get the number of days in this quarter use this.
SELECT
DATEDIFF(
MAKEDATE(YEAR(CURDATE()), 1) + INTERVAL QUARTER(CURDATE()) QUARTER - INTERVAL 1 DAY,
MAKEDATE(YEAR(CURDATE()), 1) + INTERVAL QUARTER(CURDATE()) QUARTER - INTERVAL 1 QUARTER
)
to get the difference between two dates just use this
SELECT DATEDIFF(2014-08-27','2014-03-01')
im not sure why you would be doing this in mysql.. there are built in functions in other languages to do this same operation. so I wouldn't recommend doing it in MySQL.
This is what I was looking for:
select datediff(MAKEDATE(YEAR(CurDate()), 1)
+ INTERVAL QUARTER(CurDate()) QUARTER - INTERVAL 1 QUARTER,
case when Quarter(CurDate()) = quarter(curdate())
then CurDate() -- get the number of days in quarter up to today date
else
-- return number of days in quarter totally
DATE (DATE_SUB( DATE_ADD( CONCAT( YEAR( CurDate() ), '-01-01'),
INTERVAL QUARTER(CurDate()) QUARTER ), INTERVAL 1 DAY)) end) * -1 days_in_quarter

Returning records from the last 3 months only in MySQL

I have a table with a timestamp field. How do I get data from the last 3 months?
In particular, March is my current month let say, 03/2012. I need to return records from the months March, February, and January only.
3 months before today:
select * from table where timestamp >= now()-interval 3 month;
Start with first of month:
select * from table where timestamp >= last_day(now()) + interval 1 day - interval 3 month;
To get the first day of the current month, you could use this:
DATE_FORMAT(CURDATE(), '%Y-%m-01')
if current date is 2013-03-13, it will return 2013-03-01, and we can just substract 2 months from this date to obtain 2013-01-01. Your query could be like this:
SELECT *
FROM yourtable
WHERE data >= DATE_FORMAT(CURDATE(), '%Y-%m-01') - INTERVAL 2 MONTH
I know this is an old question, but to possibly save others time and to sum the above answers up for the case of needing (1) dates from current month and (2) dates from the prior 2 months (common when displaying data statistics):
WHERE ((timestamp >= NOW() - DATE_FORMAT(CURDATE(), '%Y-%m-01'))
OR (timestamp >= DATE_FORMAT(CURDATE(), '%Y-%m-01') - INTERVAL 2 MONTH))
Assuming you're using SQL Server (Oracle, MySQL and others have similar date functions), you can use the dateadd function to add or subtract an interval to the current date.
If you want a full three months, you can subtract 3 months from today : DATEADD(m,-3,getdate())
But, as you state, you only want data from January, February and March. You have to make some calculation based on today's date: dateadd(m,-2, CONVERT(datetime, CONVERT(VARCHAR(2), MONTH(getdate())) + '/01/' + CONVERT(VARCHAR(4), YEAR(getdate()))))
And in the end, get a query like
SELECT fields
FROM table
WHERE timestampfield > DATEADD(m,-2, CONVERT(datetime, CONVERT(VARCHAR(2), MONTH(getdate())) + '/01/' + CONVERT(VARCHAR(4), YEAR(getdate()))))
--- edit ---
erf, I just noticed the "mysql" tag... you can get more information on MySQL date functions here : https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
Another possibility would be:
SELECT * WHERE your_date_column > LAST_DAY(CURRENT_DATE - INTERVAL 3 MONTH);
Use this code here to get the previous 3 months from a certain date
SELECT * FROM table WHERE date_column>= DATE_FORMAT(current_date(), '%Y-%m-01') - INTERVAL 3 MONTH and date_column< DATE_FORMAT(current_date(), '%Y-%m-01')
WHERE ((timestamp >= NOW() - DATE_FORMAT(CURDATE(), '%Y-%m-01'))
OR (timestamp >= DATE_FORMAT(CURDATE(), '%Y-%m-01') - INTERVAL 2 MONTH))

group by day for the past 5 days

I am trying to select the sum of an integer field for the past 5 days, and I need to group it for each day.
I'm having a bit of issues figuring out the grouping. Here's my sql query so far:
select
sum(`amount_sale`) as total
from `sales`
where the_date >= unix_timestamp((CURDATE() - INTERVAL 5 DAY))
that works fine for generating the sum for all 5 days together, but I need to break this down so that it shows the sum for each of the past 5 days i.e:
day 1 - $200
day 2- $500
day 3 - $20
etc.
SELECT DATE(FROM_UNIXTIME(the_date)) AS dt, SUM(amount_sale) AS total
FROM sales
WHERE the_date >= UNIX_TIMESTAMP((CURDATE() - INTERVAL 5 DAY))
GROUP BY
dt
To returns 0 for missing dates:
SELECT dt, COALESCE(SUM(amount_sale), 0) AS total
FROM (
SELECT CURDATE() - INTERVAL 1 DAY AS dt
UNION ALL
SELECT CURDATE() - INTERVAL 2 DAY AS dt
UNION ALL
SELECT CURDATE() - INTERVAL 3 DAY AS dt
UNION ALL
SELECT CURDATE() - INTERVAL 4 DAY AS dt
UNION ALL
SELECT CURDATE() - INTERVAL 5 DAY AS dt
) d
LEFT JOIN
sales
ON the_date >= UNIX_TIMESTAMP(dt)
AND the_date < UNIX_TIMESTAMP(dt + INTERVAL 1 DAY)
GROUP BY
dt
This is not a very elegant solution, however, MySQL lacks a way to generate recordsets from scratch.
use the format function to return weekday nr: SELECT DATE_FORMAT(the_date, '%w');
use between
like select * from XXX where date between date(...) and date(...) group by date Limit 0,5
should do it