SQL - Last Day of Month - mysql

I got a Table which looks like this:
DATE | Number
01-01-16 00:00:00 10
02-01-16 00:00:00 10
03-01-16 00:00:00 11
04-01-16 00:00:00 12
05-01-16 00:00:00 13
....
31-01-16 00:00.00 15
........
29-02-16 00:00:00 18
I got this table for the last few months.
I now want to retrieve the value of the rows, which contain the last day of the previous month and the month before the last month. So for today I would like to retrieve the Value of the 31-1-16 and 29-2-16.
My result should look like:
lastmonth | lastmonth2
18-> Corresponding value to Date: 29-02-16 | 15 -> value for 31-01-16
Would appreciate any help.
Cheers

Here is logic for the last day of this month and the previous month:
select last_day(curdate()) as last_day_of_this_month,
last_day(date_sub(curdate(), interval 1 month)) as last_day_of_prev_month
You can get the last day of any month relative to the current month by changing the "1".
And, I have no idea what date "30-2-16". When describing dates, you should use ISO standard formats. The last day of February 2016 was 2016-02-29.

This is Gordon's code for determining the correct dates plus subqueries to fetch the Number values for those rows:
SELECT
(SELECT Number FROM cc_open_csi_view
WHERE last_day(date_sub(curdate(), interval 1 month)) = date(`DATE`)) as lastmonth,
(SELECT Number FROM cc_open_csi_view
WHERE last_day(date_sub(curdate(), interval 2 month)) = date(`DATE`)) as lastmonth2
FROM DUAL;
Hope that's what you wanted! Works for me in a simple example. I don't know if you need the date() part around DATE but it seemed safest.

SELECT CASE
WHEN last_day(curdate()) = `DATE` THEN number
END as number_last_month,
CASE
WHEN last_day(date_sub(curdate(), interval 1 month)) = `DATE`
THEN number
END as number_last_month2
FROM cc_open_csi_view
I can't test it right now on sqlfiddle.

Related

Add weekend values to Monday SQL

I am working in mySQL and I currently have a count of total orders by day, but I would like to add Saturday and Sunday orders to Monday then remove Saturday and Sunday values. I have done some research on this but I cannot seem to find anything similar to what I am trying to do.
My current data table looks like this:
Date | Daily Count
8-6-2020 25
8-7-2020 82
8-8-2020 24
8-9-2020 33
8-10-2020 18
8-11-2020 10
8-12-2020 25
8-13-2020 15
I need it to look something like this:
Date | Daily Count
8-6-2020 25
8-7-2020 82
8-10-2020 75
8-11-2020 10
8-12-2020 25
8-13-2020 15
In this one the Daily counts for the 8th and 9th are added to the 10th, then removed, because they are weekend days. Thank you in advance for your help!
Consider using a case expression to adjust the date:
select
case weekday(date)
when 5 then date + interval 2 day
when 6 then date + interval 1 day
else date
end as new_date,
sum(daily_count) as daily_count
from mytable
group by new_date

MySQL- How can I extract the monday given a number of week?

Essentially what I want to obtain is the monday given the number of the week::
I have week: 9, 7,5
This number of week corresponds to a timestamp:
2019-03-02 02:48:00,
2019-02-15 02:58:00,
2019-01-31 00:25:00
I want to obtain the date of the monday of this week(first day of week):
2/25,
2/11,
1/28
How can extract this outout? it can be extracted from timestamp if it is easier
If you want to get Monday of the week.
You can try to use DATE_ADD and WEEKDAY function.
SELECT DATE_ADD(dt, INTERVAL - WEEKDAY(dt) DAY)
FROM T
sqlfiddle
EDIT
There is another function DATE_FORMAT represent to the date format string.
using "%m/%d"
SELECT DATE_FORMAT(
DATE_ADD(dt, INTERVAL - WEEKDAY(dt) DAY), "%m/%d")
FROM T
sqlfiddle

MySQL year interval that Includes the entire month from the previous year

I have MySQL condition that grabs a time interval from now back x number of months. Typically, this will be set to 13 months so you can compare the current month to that of last year.
'created > DATE_SUB(now(), INTERVAL ' . $timeInterval . ' MONTH)'
So for example last January compared to this January, but I'd like to include all of the previous years month. So instead of January 20, 2015 to January 20, 2016 I would have January 01, 2015 to the current date in January this year until February 1st.
I'd use DATE_FORMAT to make it quick and easy, replace the "day" part of the date with a constant. Then subtract your number of months...
... t.created > DATE_FORMAT(NOW(),'%Y-%m-01') - INTERVAL ? MONTH
As a demonstration of what is returned by that expression, we can test it using a simple SELECT statement:
SELECT NOW(), DATE_FORMAT(NOW(),'%Y-%m-01') - INTERVAL 12 MONTH
NOW() DATE_FORMAT(NOW(),'%Y-%m-01') - INTERVAL 12 MONTH
------------------- -------------------------------------------------
2016-01-27 21:01:02 2015-01-01
FOLLOWUP
Are you sure you want a "greater than" comparison, rather than a "greater than or equal to" comparison >= ?
There are other approaches to generating that date value to compare to. You could use DATE(NOW()) or CURDATE() to return the current date with no time component.
And use the DAY() function to get the numeric value of the current day, and then subtract that (minus 1) as a number of days. For example, something like this:
>= DATE(NOW()) - INTERVAL DAY(NOW())-1 DAY - INTERVAL 12 MONTH
That seems messier and more complicated. I think it's easier to understand stuffing in the '-01' as the day part.
created > str_to_date(concat(year(now())-1, '-01-01'), '%Y-%m-%d')
Or if you need not all previous year:
select str_to_date(concat(year(now())-1, '-', month(now()),'-01'), '%Y-%m-%d')

MySQL: need to calculate the last Friday of a month

I'm trying to solve a task: I have a table containing information about ships' battles. Battle is made of name and date. The problem is to get the last friday of the month when the battle occurred.
WITH num(n) AS(
SELECT 0
UNION ALL
SELECT n+1 FROM num
WHERE n < 31),
dat AS (
SELECT DATEADD(dd, n, CAST(battles.date AS DATE)) AS day,
dateadd(dd, 0, cast(battles.date as date)) as fight,
name FROM num,battles)
SELECT name, fight, max(day) FROM dat WHERE DATENAME(dw, day) = 'friday'
I thought there must be a maximum of date or something, but my code is wrong.
The result should look like this:
Please, help!!
P.S. DATE_FORMAT is not available
Possible problem: as spencer7593 noticed - and as I should have done and didn't - your original query is not MySQL at all. If you're porting a query that's OK. Otherwise this answer will not be helpful, as it makes use of MySQL functions.
The day you want is number 4 (0 being Sunday in MySQL).
So you want the last day of the month if the last day of the month is a 4; if the day of the month is a 5 you want a date which is 1 day earlier; if the day of the month is a 3 you want a date which is 1 day later, but that's impossible (the month ends), so you really need a date six days earlier.
This means that if the daynumber difference is negative, you want it modulo seven.
You can then build this expression (#DATE is your date; I use a fake date for testing)
SET #DATE='2015-02-18';
DATE_SUB(LAST_DAY(#DATE), INTERVAL ((WEEKDAY(LAST_DAY(#DATE))+7-4))%7 DAY);
It takes the last day of the month (LASTDAY(#DATE)), then it computes its weekday, getting a number from 0 to 6. Adds seven to ensure positivity after subtracting; then subtract the desired daynumber, in this case 4 for Friday.
The result, modulo seven, is the difference (always positive) from the last day's daynumber to the wanted daynumber. Since DATE_SUB(date, 0) returns the argument date, we needn't use IF.
SET #DATE='1962-10-20';
SELECT DATE_SUB(LAST_DAY(#DATE), INTERVAL ((WEEKDAY(LAST_DAY(#DATE))+7-4))%7 DAY) AS friday;
+------------+
| friday |
+------------+
| 1962-10-26 |
+------------+
Your query then would become something like:
SELECT `name`, `date`,
DATE_SUB(LAST_DAY(`date`),
INTERVAL ((WEEKDAY(LAST_DAY(`date`))+7-4))%7 DAY) AS friday
FROM battles;

Limiting MySQL results to prior days of the week

I have a table like so:
id | gallons_used | date
----------------------
1 2 157263300
2 5 157262000
...
I want to get a result set containing only records that took place on X day of the week (Monday or Tuesday or Wednesday, etc etc)
Use DAYNAME() in your WHERE clause
WHERE DAYNAME(FROM_UNIXTIME(`date`)) = 'Monday' <-- by day of the week
AND `date` < INTERVAL CURRENT_DATE - 7 DAY <-- within the last week
You can use DAYOFWEEK() as well but this is more readable.
Something that would check for Wednesday as an example given that your date column is a timestamp:
DAYOFWEEK(date) = 4
Reference to documentation: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_dayofweek
SQLFiddle: http://www.sqlfiddle.com/#!2/12762/3
I had a FROM_UNIXTIME() call around date as well but I don't think it is required(not 100% sure). http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_from-unixtime
Since you're using a Unix timestamp, you can use the following:
SELECT id, UNIX_TIMESTAMP(`date`)
FROM ...
WHERE DAYNAME(FROM_UNIXTIME(`date`)) = 'Monday'
AND `date` > UNIX_TIMESTAMP() - 604800
See the demo