I am looking at getting certain data from our user sign-ups. We have data from 2013 up to now, but I need data from the last six months of how many users have signed up each month.
I don't know where to begin with starting the SQL query as what I have done so far is all wrong and doesn't come up with what I need.
I have a c_date (CURRENT_TIMESTAMP) column with the dates the user signed up.
All I have managed to do is get the data for a single month
SELECT
COUNT(c_date) AS total
FROM
accounts
WHERE
c_date BETWEEN '2017-05-01 00:00:00' AND '2017-05-31 23:59:59'
I am using MySQL
Depending on your SQL flavor, I would suggest using the current_date SQL keyword and the interval datatype:
where c_date >= current_date - interval '180 day'
I don't know what system you're using but here is how you might do it in SQL Server. This sums up the counts by month and year
select datepart(month, c_date) as month, datepart(year, c_date) as year, count(*)as total
from accounts
where c_date > dateadd(month, -6, getdate())
group by datepart(month, c_date), datepart(year, c_date)
order by month desc
You want to aggregate the data. Something like this:
SELECT YEAR(c_date) as yyyy, MONTH(c_date) as mm, COUNT(*) AS total
FROM accounts a
WHERE c_date >= (CURDATE() - INTERVAL (1 - DAY(CURDATE())) )- INTERVAL 6 MONTH
GROUP BY yyyy, mm;
The WHERE clause calculates the first day of the month starting six months ago.
Related
I want to display last 12 months sales in a chart. SQL table has year and month field and not a combined date field.
Im not able to give the interval condition of 12months on Year field.
SELECT s_month,s_year,SUM(s_amount) FROM table
WHERE s_month >= Date_add(now(),interval - 12 month)
AND s_year >= Date_add(now(),interval - 12 month)
GROUP BY s_year,s_month
One method is:
select s_year, s_Month, sum(s_amount)
from t
where date(concat_ws('-', s_year, s.month, 1)) >= curdate() - interval 12 month
group by s_year, s_month;
You may want to adjust the date arithmetic, depending on whether you want the date from 12 months ago.
If you want the last 12 months in the data, you can do:
select s_year, s_month, sum(amount)
from t
group by s_year, s_month
order by s_year desc, s_month desc
limit 12;
This is a strong argument against storing date parts (month, year) in separate columns.
The WHERE clause you have does not do what you expect!
It is virtually always better to have a DATE column (or TIMESTAMP or DATETIME) and use date functions as needed to split it apart.
SELECT MONTH(dat), YEAR(dat), SUM(amount)
FROM table
WHERE dat >= CURDATE() - INTERVAL 12 MONTH
GROUP BY LEFT(dat, 7) -- eg, "2017-12"
There is another problem with your query. SUM(amount) will have a partial month at either end. I can't solve that for you without better understanding where the data comes from and when. If it is already a single reading stored on the first of the month, then no problem. If it is daily or hourly amounts, then my point stands.
I have a table with birthdays in them, formatted in YYYY-MM-DD. My aim is to return results if the birthday is within the next 7 days.
I need it to use only the month and day, because if it reads the year also, a birthday in 1993 is never going to be within the next 7 days. It also needs take month changes into consideration.
For example, if its the 28th of Feb, and a birthday in the table is on the 1st March, that would be within 7 days, but not within the same month.
SELECT * FROM user WHERE DATE_FORMAT(birthday, '%m-%d') >= DATE_FORMAT(NOW() - INTERVAL 7 DAY, '%m-%d')
This is where i'm at, at the moment, but I know i'm miles off.
You need to format both of your dates in the WHERE clause.
SELECT *
FROM user
WHERE DATE_FORMAT(birthday, '%m-%d') BETWEEN DATE_FORMAT(NOW(), '%m-%d') AND DATE_FORMAT(DATE_ADD(NOW(), INTERVAL 7 DAY), '%m-%d')
retrieve current year with YEAR(CURDATE(), make a date biy concatenating with month and day coming from birthday and remove 7 days, check if curdate is in the range :
select *
from user
where
Curdate() between date_sub(CONCAT(YEAR(CURDATE()),'-', date_format(birthday, '%m-%d')), interval 7 day)
and CONCAT(YEAR(CURDATE()),'-', date_format(birthday, '%m-%d')) ;
Take year part from today's date and concatenate it with the month and day part of the dob column value. And cast that string to date. Then use that as a sub-query and check whether thet new column day difference is between 0 and 7.
Query
SELECT t.* -- select except the `new_col`
FROM (SELECT *,
CAST((Concat(YEAR(NOW()), '-', DATE_FORMAT(dob, '%m-%d'))) AS DATE
) AS
`new_col`
FROM `user`)t
WHERE DATEDIFF(t.`new_col`, NOW()) BETWEEN 0 AND 7;
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))
I have date time field called transaction_date, in a report i need to select last calendar month, how do i do this ? (this should work for a month like January too)
I came up with following but this only works if the month is NOT january,
SELECT SUM(amount) AS pay_month FROM `users_payment` WHERE MONTH(transaction_datetime)= MONTH(NOW()) AND YEAR(transaction_datetime)=YEAR(NOW())
there are lot of examples using INTERVAL functions but this only select the time interval not the calendar month as i wanted too..
like
SELECT SUM(amount) AS `year_month` FROM `users_payment` WHERE DATE_ADD(NOW(), INTERVAL -1 MONTH) < transaction_datetime
but this is not what i want, i want to select sales sum of the DECEMBER only last year (remember there are other years too in the table which i dont want i.e 1979, 1981...etc)
same report next section, i need to select last 2 calender months, I dont know have any idea on how to do this too.
Have you tried the following
SELECT SUM(amount) AS `year_month` FROM `users_payment`
WHERE MONTH(DATE_ADD(NOW(), INTERVAL -1 MONTH)) = MONTH(transaction_datetime)
The above should work to show previous month; it does not distinguish between years however.
On second thought, I see what you are trying to do - To get all the transactions for a given month. Try something like this instead.
SELECT SUM(amount) AS `year_month` FROM `users_payment`
WHERE transaction_datetime BETWEEN date_format(NOW() - INTERVAL 1 MONTH, '%Y-%m-01')
AND last_day(NOW() - INTERVAL 1 MONTH)
This will list all the transactions for the previous calendar month. Alter the INTERVAL values to select multiple months.
You can try this--
SELECT SUM(amount) AS pay_month FROM `users_payment` WHERE
PERIOD_ADD(DATE_FORMAT(NOW(),'%Y%m'), -1) = DATE_FORMAT(transaction_datetime,'%Y%m')
I have a table with a year and month in different columns, and I need to find all rows between 3 months ago and now.
SELECT * FROM `table`
WHERE DATE(CONCAT(`year`, '-', `month`, '-01')) >=
DATE_FORMAT(NOW() - INTERVAL 3 MONTH, '%Y-%m-01')
It just seems rather verbose, and possibly inefficient as this is a very large table. Is there a better way to do this?
There isn't much optimization to be had when the date is stored as separate fields, but I would re-write your query as:
SELECT *
FROM `table`
WHERE STR_TO_DATE(`year`+ '-'+ `month` + '-01', '%Y-%m-%d') >= DATE_SUB(NOW(), INTERVAL 3 MONTH)
The concatenation renders indexing on the year and month columns useless.
For more info about MySQL date functions, see: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
Well, I had the same issue and I have figured what I think is the solution for this case.
SELECT *
FROM table
WHERE (month >= (month(curdate()) - 3 AND year >= year(curdate()))
AND (month >= month(curdate()) AND year >= year(curdate())))
Supposing you have columns named year and month.