sql query range selection - mysql

Hi i have a table like below
year | month | otherdata
2015 1
2015 1
2015 3
2015 4
2015 4
2016 1
2016 2
2016 2
here how do i select all data of (year 2015/month 4 to year 2016/month 2)
i tried following query.
select * from `schedule_details` where (`year` >= 2015 and `month` >= 4) and (`year` <= 2016 and `month` >= 2)
but its not working. how do i do this? please help

thanks
Solved the problem
Select *
From schedule_details
Where ( year = 2015 And month >= 4 )
Or ( year > 2015 And year < 2016 )
Or ( year = 2016 And month <= 2 )
is there any other better way?

Related

Sql get data based on month an year that are numbers

I have a table with this data :
id quantity month year
1 10 12 2020
2 78 3 2019
3 67 4 2020
4 78 3 2020
5 56 2 2020
6 34 4 2017
7 56 2 2017
I want to get all data's from 2017, month 3 till 2020 month 3
My sql look like :
where (dc.year >= 2017 and dc.month >= 3) and (dc.year <= 2020 and dc.month <= 3)
GROUP BY dc.year, dc.month
this sql get only data for 2017,3 and 2018, 3 and 2019,3 and 2020,3
But I need the whole interval. If I put
where dc.year >= 2017 and dc.year <= 2020
GROUP BY dc.year, dc.month
Getting all datas but I need data from 2017 month 3 -----> 2020 month 3 (all interval)
One method uses arithmetic:
where dc.year * 12 + dc.month between 2017 * 12 + 3 and 2020 * 12 + 3
Alternative, you can use a more complex expression:
where (dc.year = 2017 and dc.month >= 3) or
(dc.year > 2017 and dc.year < 2020) or
(dc.year = 202 and dc.month <= 3)
You could simply build dates from these numbers and use them for comparison. I think that it makes the intent clearer, and really is in the spirit of your logic (which is to filter by date):
In SQL Server:
where datefromparts(year, month, 1) between '2017-03-01' and '2020-03-01'
In MySQL:
where concat_ws('-', year, month, 1) between '2017-03-01' and '2020-03-01'

How to get date increments in between start date and end date in MYSQL

I have sample dates in a table and what I need to get is each of the months between the start date and end date.
sample :
ID Startdate EndDate
1 01-01-2019 01-03-2019
2 01-08-2019 01-02-2020
I need to fetch months and year from these dates.
Desired output :
ID Dates
1 January 2019
1 February 2019
1 March 2019
2 August 2019
2 September 2019
2 October 2019
2 November 2019
2 December 2019
2 January 2020
2 February 2020
How cah I achieve this in MySQL and how to do increment or any loop kind of operation. On the query side I'm not getting any idea to move on this.
Here are a couple of ways to achieve this. The first will only work on MySQL 8+ and uses a recursive CTE to generate the months between StartDate and EndDate:
WITH RECURSIVE CTE AS (
SELECT ID, Startdate AS d, EndDate
FROM dates
UNION ALL
SELECT ID, d + INTERVAL 1 MONTH, EndDate
FROM CTE
WHERE d < EndDate
)
SELECT ID, DATE_FORMAT(d, '%M %Y') AS Dates
FROM CTE
ORDER BY ID, d
The second (which will run on any version of MySQL) uses a numbers table (in this case numbers from 0 to 99, allowing for a range of up to 99 months between StartDate and EndDate; if you need longer, adding more tables to the CROSS JOIN will increase that range by a factor of 10 for each table added) to generate the list of months difference, this is then JOINed to the original table so that the generated date Startdate + INTERVAL n.n MONTH is less than or equal to EndDate:
SELECT ID, DATE_FORMAT(Startdate + INTERVAL n.n MONTH, '%M %Y') AS Dates
FROM dates
JOIN (
SELECT n10.n * 10 + n1.n * 1 AS n
FROM (
SELECT 0 n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
) n10
CROSS JOIN (
SELECT 0 n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
) n1
) n ON Startdate + INTERVAL n.n MONTH <= EndDate
ORDER BY ID, Startdate + INTERVAL n.n MONTH
Having generated our list of dates, we format it using DATE_FORMAT and a format string of %M %Y. For both queries the output is:
ID Dates
1 January 2019
1 February 2019
1 March 2019
2 August 2019
2 September 2019
2 October 2019
2 November 2019
2 December 2019
2 January 2020
2 February 2020
Demo on dbfiddle

Get running totals for each month based on created_at date

I'm trying to get a running total for each month of this year. So my ideal result would be something such as:
January | 4
February | 5
March | 8
April | 10
May | 12
June | 14
July | 16
August | 17
September | 18
October | 21
November | 22
December | 22
The basic count would just check against first of the month such as:
January 1 (sum where created_at < January 1, 2018)
February 1 (sum where created_at < February 1, 2018)
March 1 (sum where created_at < March 1, 2018)
April 1 (sum where created_at < April 1, 2018)
...
Doing it for one month at a time is easy, as I can just do something like this:
SELECT *
FROM businesses
WHERE created_at < CONCAT(YEAR(CURDATE()), "-12-01 00:00:01")
I tried using one of the examples from another Stackoverflow answer, but it's not working quite as desired as it seems like the sort or something is messed up so the counts are not lining up right.
You can see schema build and current SQL here:
http://sqlfiddle.com/#!9/0c23cc/20
Try something like this.
SELECT
MONTHNAME( created_at ) AS theMonth,
(
SELECT
count( * )
FROM
businesses AS u1
WHERE
YEAR ( u1.created_at ) = YEAR ( businesses.created_at )
AND u1.created_at <= date_ADD( last_day( businesses.created_at ), INTERVAL 1 DAY )
) AS totals
FROM
businesses
WHERE
YEAR ( businesses.created_at ) = YEAR ( CURDATE( ) )
GROUP BY
MONTHNAME( businesses.created_at )
ORDER BY
MONTH ( businesses.created_at ) ASC

Calculating Cumulative values using MySQL

I have this table:
Month_Year MV MI
----------------------------------------------------------
August 2016 3 100
October 2016 2 150
September 2016 1 100
January 2017 4 200
I need to create the next output table
Month_Year MV AMV MI AMI
----------------------------------------------------------
January 2016 0 0 0 0
...
July 2016 0 0 0 0
August 2016 3 3 100 100
September 2016 1 4 100 200
October 2016 2 6 150 350
November 2016 0 6 0 350
December 2016 0 6 0 350
January 2017 4 10 200 550
At month M, for column AMV, AMV is the ccumulative value of all the AV ones before that month and month M. For example, AMV is 4 on 'September 2016' because in 'August 16' AV is 3 and 1 for 'September 2016'. Similarly for AMI. How can this be done?. Notice that the Month_Year column is not necessarily ordered. Thanks
ADDITIONAL INFO
After using the DATE_FORMAT(original_Date, '%Y %m') I was able to convert the first table to:
Month_Year MV MI
----------------------------------------------------------
2016 08 3 100
2016 10 2 150
2016 09 1 100
2017 01 4 200
Could this simplify the problem? Why not to use DATE_FORMAT(original_Date, '%m %Y')?
The month-year format is a big big NO, and you have to somehow overcome it. For this example I create a MEMORY table months, and I use several joins with this table.
create table months (month_year_int int, month_year varchar(30)) engine=memory;
insert months
select 201601 as month_year_int, 'January 2016' as month_year
union all select 201602, 'February 2016'
union all select 201603, 'March 2016'
union all select 201604, 'April 2016'
union all select 201605, 'May 2016'
union all select 201606, 'June 2016'
union all select 201607, 'July 2016'
union all select 201608, 'August 2016'
union all select 201609, 'September 2016'
union all select 201610, 'October 2016'
union all select 201611, 'November 2016'
union all select 201612, 'December 2016'
union all select 201701, 'January 2017'
;
All these would have been avoided if you had used a proper model for your data. Anyway, this is a solution whis does not use the My-Sql proprietary variable pattern (a rextester demo here):
select
x.month_year,
coalesce(t.mv, 0) MV,
sum(y.mv) as AMV,
coalesce(t.mi, 0) AMV,
sum(y.mi) as AMI from
(
select
m.month_year_int,
m.month_year,
coalesce(t.mv, 0) as mv,
coalesce(t.mi) as mi
from months m left join test t on m.month_year = t.month_year
) x
left join
(
select
m.month_year_int,
m.month_year,
coalesce(t.mv, 0) as mv,
coalesce(t.mi) as mi
from months m
left join test t on m.month_year = t.month_year
) y on x.month_year_int > y.month_year_int - 1
left join test t on x.month_year = t.month_year
group by x.month_year_int
order by x.month_year_int
;

SQL cumulative previous 12 months - breakdown per month

Can anyone assist in a sql statement I am trying to write? I'm using SSRS r1 (either sql or ssrs solution is fine)
How do I:
show count measure split by month and year
for each of those months, I want to count the previous cumulative 12 months
e.g.
2012 jan: counts feb 2011 - jan 2012
2012 feb: counts mar 2011 - feb 2012
2012 mar: counts apr 2011 - mar 2012
I have started this code but it's incorrect, however it gives you an idea of what I am trying to achieve (this issue is I have to calc month and year from a date)
select
count(a.measure) count
,month(a.StartDate)
,year(a.StartDate)
from
a
where
a.StartDate >= DATEADD(mm,DATEDIFF(mm,0,#datepromt)-12,0) as startdateYrAgo --1st month 1 year ago 01/01/2012
and a.StartDate <= DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#datepromt)+1,0)) as startdateEOM --last day of month 31/01/2013
group by
month(a.StartDate)
,year(a.StartDate)
Here you have an idea for the query, it have to look something like below;
SELECT
periods.year
,periods.month
,measures.cnt
FROM (
SELECT DISTINCT
year = YEAR(StartDate)
, month = MONTH(StartDate)
, month_running = DATEDIFF(mm, 0, StartDate)
FROM a
GROUP BY YEAR(StartDate), MONTH(StartDate), DATEDIFF(mm, 0, StartDate)
) periods
JOIN (
SELECT month_running = DATEDIFF(mm, 0, StartDate), cnt = COUNT(measure)
FROM a
GROUP BY DATEDIFF(mm, 0, StartDate)
) measures
ON measures.month_running BETWEEN periods.month_running - 12 AND periods.month_running - 1