I am looking to do something like get all rows from table
where date >='2012-05-05' and date<='2012-07-20'
I want MySQL to return "group by" rows mont wise incremented from
2012-05-05 to 2012-06-05(incerement 1 month)
2012-06-06 to 2012-07-06(increment 1` month)
and remaining 2012-07-07 to 2012-07-20 (group the remaining 14 days)
how can i write my query to achieve the same?
Thank you...
Try this solution:
You can GROUP BY the number of months elapsed from your parameter minimum (2012-05-05) + 1 to the date in each row via the TIMESTAMPDIFF() function:
GROUP BY TIMESTAMPDIFF(MONTH, '2012-05-05' + INTERVAL 1 DAY, date)
The reason why we +1 day to your minimum parameter is because:
2012-05-05 to 2012-06-04 is 0 months, but...
2012-05-05 to 2012-06-05 is 1 month
^ Because of that, the row(s) on 2012-06-05 would be grouped separately from dates that had 0 months elapsed when we actually want it grouped WITH them.
Edit: I was fiddling around with this solution not only grouping by the month intervals, but also displaying the from and to dates of each interval.
Check it out:
SQLFiddle Demo
You could use the case expression and then group by on the result of case.
SELECT
CASE
WHEN where date >='2012-05-05' and date<='2012-06-05' THEN 1
WHEN where date >='2012-06-06' and date<='2012-07-06' THEN 2
ELSE 3
END AS period, COUNT(*)
FROM your_table
GROUP BY period
Hope this help, I assumed the date range is dynamic like this :
2012-01-01 to 2012-02-01
2012-02-02 to 2012-03-02
2012-03-03 to 2012-04-03
2012-04-04 to 2012-05-04
2012-05-05 to 2012-06-05
...
So, I can group it using :
SELECT *, IF(day(date)>=month(date), month(date), month(date)-1) as PERIOD
FROM your_tablename
GROUP BY PERIOD;
Related
This is the current table I have.
ID Start_Date End_Date
6446 2018-01-01 00:00:00 2018-04-01 00:00:00
6848 2018-05-01 00:00:00 2018-05-31 00:00:00
3269 2016-11-09 00:00:00 2016-11-21 00:00:00
7900 2018-11-07 00:00:00 2018-11-30 00:00:00
4006 2017-04-06 00:00:00 2017-04-30 00:00:00
Is there a way to get the number of active events per week? Some events might run past a few weeks. Event ID is distinct and can be used to count.
Please help and happy to furnish more info if required.
EDIT 1: The dataset I want is
2019 week 1 - 60 active events
2019 week 2 - 109 active events
I know about WEEK(datetime), however that does not capture the event being active for subsequent weeks.
The issue is that I don't capture the number of active events after the week they are started.
EDIT 2: Week would be defined as the integer returned using the week() function in mysql on a date object. My data is only for 2019.
Try to use count() function in MySQL.
SELECT COUNT(*) FROM your_table WHERE Start > 'start-date' AND End < 'end-date'
Give a try to below query
SELECT
IFNULL(DATE_FORMAT(Start_Date, '%Y WEEK %U'), 0) AS STARTDate,
IFNULL(DATE_FORMAT(End_Date, '%Y WEEK %U'), 0) AS ENDDate,
IFNULL(COUNT(ID),0) AS total,
group_concat(ID)
FROM `event`
where Start_Date < End_Date
Group by STARTDate;
I found an answer, but encountered a new problem.
Building upon Kranti's code, the answer is as follows.
SELECT
EXTRACT(WEEK FROM starting_date) AS STARTDate,
EXTRACT(WEEK FROM ending_date) AS ENDDate,
discount_type,
COUNT(ID) AS total
FROM `event`
where starting_date < ending_date
Group by 1,2
What this gives me is the number of events that have happened from Week 1 - 3, Week 1-4 etc, so on and so forth.
Afterwards, we do a left join with the weeks of interest, on the condition where the week numbers are in between STARTDate and ENDDate. Due to how a left join works, it will duplicate rows for all the rows that fulfill the specific condition.
We follow up with a groupby and sum, which will give us the number of events that were active, for each week.
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.
Let's say we have a simple table like so
DATE VALUE
--------------------
2013-01-01 23
2013-06-12 34
2013-07-22 788
2013-12-16 234
2014-01-23 56
2014-04-19 88
2014-09-23 7987
2014-11-05 66
2015-02-17 987
2015-05-05 896
Now let's suppose we want to extract the mean values grouped by year, we would use
SELECT AVG(`VALUE`) FROM tablename GROUP BY YEAR(`DATE`)
However, what if we define the year not from January to December, but rather from July to June (which makes quite a bit of sense for a lot of data if you're living in the Southern hemisphere).
I am sure there must be an easy way to achieve a July YEAR to June YEAR+1 grouping. It just seems to elude me.
-- EDIT --
Awesome! Two good solutions arrived within minutes of posting this question, that both deserved to be accepted. I accepted Roland's solution because of its brevity, but Leo Tara's reply made me aware that I forgot about outputting the associated austral year. So based on both answers I came up with this solution which does exactly what I was asking for:
SELECT
YEAR(`DATE` - INTERVAL 6 MONTH) as `australyear`,
AVG(`VALUE`)
FROM tablename
GROUP BY YEAR(`DATE` - INTERVAL 6 MONTH)
Just add 6 month to the date when grouping. I don't know the exact syntax in case of mysql, sorry.
Pseudocode:
SELECT AVG(`VALUE`) FROM tablename GROUP BY YEAR(`DATE` + '6 MONTHS');
Try this:
SELECT AVG(`VALUE`)
FROM tablename
GROUP BY
CASE
WHEN MONTH('DATE') BETWEEN 1 AND 6 THEN YEAR('DATE') - 1
ELSE YEAR(`DATE`)
END
If you want to show year on field list you must rewrite your query in this way:
SELECT
CASE
WHEN MONTH('DATE') BETWEEN 1 AND 6 THEN YEAR('DATE') - 1
ELSE YEAR(`DATE`)
END, AVG(`VALUE`)
FROM tablename
GROUP BY
CASE
WHEN MONTH('DATE') BETWEEN 1 AND 6 THEN YEAR('DATE') - 1
ELSE YEAR(`DATE`)
END
Test on Sql Fiddle
We have a table that has a StartDate field which holds a type of datetime. There are thousands of records and I am looking for a way to find the number of days within a given result returned from this table. For instance, if my table had this data:
ID | StartDate
--------------
1 01/01/2013 09:34:54
2 01/01/2013 11:23:21
3 04/11/2013 14:43:23
4 04/11/2013 17:13:03
5 04/25/2013 18:02:59
6 07/21/2013 02:56:12
7 10/01/2013 19:43:10
Then the query should return 5 as the 2 dates on 01/01/2013 count as 1 and the same for 04/11/2013.
The only SQL I've been able to come up with is:
SELECT COUNT(DISTINCT(DATEPART(DAY, StartDate)))
FROM Stats
WHERE StartDate BETWEEN '01/01/2013' AND '12/31/2013' --This is just for filtering
But this returns 4 because it doesn't take the month into account.
Any help is appreciated.
You can CAST as date
SELECT COUNT(DISTINCT CAST(StartDate AS DATE))
FROM Stats
WHERE StartDate >= '20130101' AND StartDate < '20140101'
Also use an unambiguous date format such as yyyymmdd and >= < not BETWEEN.
Your current query would include the 31st December if there was a row with exactly the value 20131231 00:00:00 but not any with different times on that date. I doubt that is intentional.
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