MYSQL 30 days query - mysql

i have this kind of query:
SELECT COUNT( * )
FROM `reportinc`
WHERE `Data/ora apertura` >= '21/01/13 00:00:00'
AND `Data/ora apertura` <= '21/01/13 18:00:00'
I have to repeat this query for 30 days past from today.
How automate it?
Instead of daytime: 21/01/13 i have to insert something like TODAY -1, TODAY -2 etc etc but my own specified timestamp.
How to?

SELECT TO_DAYS(NOW()) - TO_DAYS(your_table_column_name) <= 30;
Or use DATEDIFF
mysql> SELECT DATEDIFF('1997-12-31 23:59:59','1997-12-30');
-> 1

You could use BETWEEN
SELECT COUNT( * )
FROM `reportinc`
WHERE `Data/ora apertura`
BETWEEN
CURRENT_DATE - INTERVAL 2 DAY
AND
CURRENT_DATE - INTERVAL 1 DAY + '18:00:00'

Something like this:
WHERE `Data/ora apertura` >= CURRENT_DATE - INTERVAL 2 DAY
AND `Data/ora apertura` <= CURRENT_DATE - INTERVAL 1 DAY
+ INTERVAL '18:00:00' HOUR_SECOND

Related

Inserting one MySQL row with values from multiple, nested SELECT statements

I'm trying to combine the following two statements into one SELECT statement, so that I can insert the returned values into one and the same row with one statement.
SELECT ROUND(AVG(pressure),1) FROM rawinput WHERE timestamp >= SUBDATE(timestamp(now()), INTERVAL 1 HOUR);
SELECT ROUND((SELECT AVG(hourly_average_pressure) FROM hour_numbers WHERE timestamp >= CURTIME() - INTERVAL 1 HOUR)-(SELECT AVG(hourly_average_pressure) FROM hour_numbers WHERE timestamp >= CURTIME() - INTERVAL 2 HOUR AND timestamp < CURTIME() - INTERVAL 1 HOUR),1);
I already tried to format like below (basically adding parentheses around both SELECT statements and replace the semicolon with a comma) but I got syntax error. Is the only way to do this using a UNION ALL or am I missing something in the format? Thanks for the help.
(SELECT ROUND(AVG(pressure),1) FROM rawinput WHERE timestamp >=SUBDATE(timestamp(now()), INTERVAL 1 HOUR)), (SELECT ROUND((SELECT AVG(hourly_average_pressure) FROM hour_numbers WHERE timestamp >= CURTIME() - INTERVAL 1 HOUR)-(SELECT AVG(hourly_average_pressure) FROM hour_numbers WHERE timestamp >= CURTIME() - INTERVAL 2 HOUR AND timestamp < CURTIME() - INTERVAL 1 HOUR),1));
If you format your code properly, it's easy to see that you are missing SELECT statement in front of your code.
(
SELECT ROUND(AVG(pressure),1)
FROM rawinput
WHERE timestamp >=SUBDATE(timestamp(now()), INTERVAL 1 HOUR)
)
, (
SELECT ROUND((SELECT AVG(hourly_average_pressure) FROM hour_numbers WHERE timestamp >= CURTIME() - INTERVAL 1 HOUR)-(SELECT AVG(hourly_average_pressure)
FROM hour_numbers
WHERE timestamp >= CURTIME() - INTERVAL 2 HOUR AND timestamp < CURTIME() - INTERVAL 1 HOUR),1)
);
With SELECT
SELECT (
SELECT ROUND(AVG(pressure),1)
FROM rawinput
WHERE timestamp >=SUBDATE(timestamp(now()), INTERVAL 1 HOUR)
)
, (
SELECT ROUND((
SELECT AVG(hourly_average_pressure)
FROM hour_numbers
WHERE timestamp >= CURTIME() - INTERVAL 1 HOUR
) - (
SELECT AVG(hourly_average_pressure)
FROM hour_numbers
WHERE timestamp >= CURTIME() - INTERVAL 2 HOUR AND timestamp < CURTIME() - INTERVAL 1 HOUR
), 1)
);

Get number of entries per multiple date intervals using single query

SELECT COUNT(*) FROM `table` WHERE `datetime` > SUBDATE(NOW(), INTERVAL 1 DAY)
This will get number of entries during last day. But is it possible to get number of entries for multiple intervals without having to send variation of this query multiple times (INTERVAL 1 DAY, INTERVAL 1 WEEK, INTERVAL 1 MONTH, ...)?
You need CASE WHEN expression to accomplish that.
SELECT
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 1 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END) AS lastDay,
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 7 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END ) AS lastSevenDays,
COUNT(*) AS lastThirtyDays
FROM `table`
WHERE
DATE(`datetime`) >= CURDATE() - INTERVAL 30 DAY
How to use CASE WHEN expression
Note: If your requirement is to get result of last day, last 7 days and last 30 days then go with this query.
EDIT:
If you have an index on datetime field then the above query will fail to use that index. Please use the query given below in order to utilize the index on datetime.
SELECT
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 1 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END) AS lastDay,
COUNT(CASE WHEN DATE(`datetime`) >= CURDATE() - INTERVAL 7 DAY AND DATE(`datetime`) < CURDATE() THEN 1 END ) AS lastSevenDays,
COUNT(*) AS lastThirtyDays
FROM `table`
WHERE
`datetime` >= (NOW() - INTERVAL 30 DAY - INTERVAL HOUR(NOW()) HOUR - INTERVAL MINUTE(NOW()) MINUTE - INTERVAL SECOND(NOW()) SECOND)

Mysql DATE_FORMAT and timing

i have a table called "reportinc" where i have to extract -it is VARCHAR field- items from 1 or some days past at 18:01 (time format as %H:%i) to today at 18:00.
I tried with this query
SELECT `ID incidente`, `Data/ora apertura`
FROM `reportinc`
WHERE `Data/ora apertura`
BETWEEN
(
SELECT date_format( now( ) - INTERVAL 1
DAY , "%d/%m/%y at 18:01 " )
)
AND
(
SELECT date_format( now( ) , "%d/%m/%y at 18:00 " )
I want to extract from yesterday at 18:01 to today 18:00.
But the results are form 00:00 yesterday to today.
It dont consider 18:00 or 18_01 as valid time format.
How specify time into query?
MANY THANKS AGAIN
The Data/ora apertura field must be a DATETIME field, or you have to make a CAST.
Then you must do this:
SELECT `ID incidente`, `Data/ora apertura`
FROM `reportinc`
WHERE `Data/ora apertura`
BETWEEN
(
SELECT date_format( now( ) - INTERVAL 1 DAY , "%Y-%m-%d 18:01:00" )
)
AND
(
SELECT date_format( now( ) , "%Y-%m-%d 18:00:00"
)
Between do not work as you expected when the field type is VARCHAR.
At first change the format from varchar to valid date format. varchar takes the value as string and you will have to use regex to bifurcate date and time. Better to go with former option.
EDIT added more specific date time format
I ran in to the same problem the combination between time and date. Time is ignored therefore you get the results form the whole day.
Try PHP or another programming language to manipulate the MySQL out. Or try as I suggest to change the import method of the CSV file.
SELECT *,CAST((STR_TO_DATE(`Data/ora apertura`, '%d/%m/%Y %H.%i')) AS DATETIME)
AS DATE_TIME
FROM reportinc
WHERE (CAST((STR_TO_DATE(`Data/ora apertura`, '%d/%m/%Y %H.%i')) AS DATETIME)) >= ('2012-22-01 21:00');
SELECT *,CAST((STR_TO_DATE(`Data/ora apertura`, '%d/%m/%Y %H.%i')) AS DATETIME)
AS DATE_TIME
FROM reportinc
WHERE (STR_TO_DATE(`Data/ora apertura`, '%d/%m/%Y %H.%i')) >= ('2012-22-01 21:00');
Sample data:
CREATE TABLE reportinc (
`ID_incidente` int auto_increment primary key,
`Data/ora apertura` varchar(30)
);
INSERT INTO reportinc (`Data/ora apertura`)
VALUES
("31/07/2012 10.46"),
("31/07/2012 10.47"),
("22/01/2013 20.00"),
("23/01/2013 10.00");
SQL FIDDLE demo
---
Try something like:
Using the cast function:
SELECT * FROM reportinc WHERE (CAST(`Data/ora apertura` AS DATETIME)) >= NOW() - INTERVAL 3 hour;
Using the str_to_date function:
SELECT * FROM reportinc WHERE (STR_TO_DATE(`Data/ora apertura`,'%Y-%m-%d %H:%i:%s')) >= NOW() - INTERVAL 3 hour;
You are a bit unclear about the time range so I took 3 hours as a example. You can also use a specific date and time.
Using cast:
`SELECT * FROM reportinc WHERE (CAST(`Data/ora apertura` AS DATETIME)) >= ('2013-01-22 20:00:00');`
Using str_to_date
SELECT * FROM reportinc WHERE (STR_TO_DATE(apertura, '%Y-%m-%d %H:%i:%s')) >= ('2013-01-21 20:00:00');
Sample data:
CREATE TABLE reportinc (
`ID_incidente` int auto_increment primary key,
`Data/ora apertura` varchar(30),
`Data/ora apertura1` datetime
);
INSERT INTO reportinc ( `Data/ora apertura`, `Data/ora apertura1`)
VALUES (NOW() - INTERVAL 1 day, NOW() - INTERVAL 1 day),
(NOW() - INTERVAL 1 hour, NOW() - INTERVAL 1 hour),
(NOW() - INTERVAL 3 hour, NOW() - INTERVAL 3 hour),
(NOW() - INTERVAL 6 hour, NOW() - INTERVAL 6 hour),
(NOW() - INTERVAL 9 hour, NOW() - INTERVAL 9 hour),
(NOW() - INTERVAL 1 year, NOW() - INTERVAL 1 year);
SQL FIDDLE DEMO
B.T.W. My advices is to stop using slashes, spaces etc in column and table names.
I would appreciated it if you would accept answers that have helped you.

truncate now() to only hour in mysql

How do I truncate now() to get only upto hour precision in mysql?
In
select id from Run where submitTs <= now() and submitTs >= (now() - interval 1 hour);
I really want the records from 12.00 PM to 1 PM instead of 12.23 PM to 1.23 PM if I am running at 1.23 PM.
So how do I say
submitTs<= truncate_to_hour(now())
Try thsi query -
SELECT
id
FROM
Run
WHERE
DATE(submitTs) = CURDATE() AND
EXTRACT(HOUR FROM NOW()) = EXTRACT(HOUR FROM submitTs)
This query has better performance than first one -
SELECT
id
FROM
Run
WHERE
submitTs >= CURDATE() + INTERVAL EXTRACT(HOUR FROM NOW()) HOUR AND
submitTs < CURDATE() + INTERVAL EXTRACT(HOUR FROM NOW()) + 1 HOUR
something like this should work:
SELECT id
FROM Run
WHERE submitTs BETWEEN CAST(CONCAT(DATE_FORMAT(NOW(), '%Y-%m-%d %h'), ':00:00') AS DATETIME)
AND CAST(CONCAT(DATE_FORMAT(DATE_SUB(NOW(), INTERVAL 1 HOUR), '%Y-%m-%d %h'), ':00:00') AS DATETIME);
I think some thing like this can help you to get hour of now():
HOUR(TIME(NOW())
Please see the reference at http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html to get more date-time function in mysql.

Query to get all rows from previous month

I need to select all rows in my database that were created last month.
For example, if the current month is January, then I want to return all rows that were created in December, if the month is February, then I want to return all rows that were created in January. I have a date_created column in my database that lists the date created in this format: 2007-06-05 14:50:17.
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
Here's another alternative. Assuming you have an indexed DATE or DATETIME type field, this should use the index as the formatted dates will be type converted before the index is used. You should then see a range query rather than an index query when viewed with EXPLAIN.
SELECT
*
FROM
table
WHERE
date_created >= DATE_FORMAT( CURRENT_DATE - INTERVAL 1 MONTH, '%Y/%m/01' )
AND
date_created < DATE_FORMAT( CURRENT_DATE, '%Y/%m/01' )
If there are no future dates ...
SELECT *
FROM table_name
WHERE date_created > (NOW() - INTERVAL 1 MONTH);
Tested.
Alternatively to hobodave's answer
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)
You could achieve the same with EXTRACT, using YEAR_MONTH as unit, thus you wouldn't need the AND, like so:
SELECT * FROM table
WHERE EXTRACT(YEAR_MONTH FROM date_created) = EXTRACT(YEAR_MONTH FROM CURDATE() - INTERVAL
1 MONTH)
SELECT *
FROM yourtable
where DATE_FORMAT(date_created, '%Y-%m') = date_format(DATE_SUB(curdate(), INTERVAL 1 month),'%Y-%m')
This should return all the records from the previous calendar month, as opposed to the records for the last 30 or 31 days.
Even though the answer for this question has been selected already, however, I believe the simplest query will be
SELECT *
FROM table
WHERE
date_created BETWEEN (CURRENT_DATE() - INTERVAL 1 MONTH) AND CURRENT_DATE();
WHERE created_date >= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 2 MONTH)), INTERVAL 1 DAY)
AND created_date <= DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH)), INTERVAL 0 DAY)
This worked for me (Selects all records created from last month, regardless of the day you run the query this month)
Alternative with single condition
SELECT * FROM table
WHERE YEAR(date_created) * 12 + MONTH(date_created)
= YEAR(CURRENT_DATE) * 12 + MONTH(CURRENT_DATE) - 1
select fields FROM table
WHERE date_created LIKE concat(LEFT(DATE_SUB(NOW(), interval 1 month),7),'%');
this one will be able to take advantage of an index if your date_created is indexed, because it doesn't apply any transformation function to the field value.
Here is the query to get the records of the last month:
SELECT *
FROM `tablename`
WHERE `datefiled`
BETWEEN DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH )
AND
LAST_DAY( DATE_SUB( DATE( NOW( ) ) , INTERVAL 1
MONTH ) )
Regards
- saqib
if you want to get orders from last month, you can try using
WHERE MONTH(order_date) = MONTH(CURRENT_DATE()) -1
One more way to do this in:
MYSQL
select * from <table_name> where date_created >= DATE_ADD(NOW(), INTERVAL -30 DAY);
SELECT * FROM table
WHERE YEAR(date_created) = YEAR(CURRENT_DATE - INTERVAL 1 MONTH)
AND MONTH(date_created) = MONTH(CURRENT_DATE - INTERVAL 1 MONTH)