Get records in Mysql where unix timestamp is today - mysql

I'm storing records in msyql where a resolve_by column has a unix timestamp.
I'm trying this query:
SELECT id FROM tickets WHERE FROM_UNIXTIME('resolve_by','%Y-%m-%d') = CURDATE()
The basic table structure is:
id|resolve_by|date_created
4, 1506092040, 1506084841
But this is returning 0 records. How can I get records where the unix timestamp value = today's date?
Thanks,

Changed query from :
SELECT id FROM tickets WHERE FROM_UNIXTIME('resolve_by','%Y-%m-%d') = CURDATE()
To:
SELECT id FROM tickets WHERE FROM_UNIXTIME(resolve_by,'%Y-%m-%d') = CURDATE()
It's working now.

In general you'll want to avoid using functions on the columns side of where conditions, as it will most probably disqualify your query to benefit from indexes.
Consider something like:
create table test_table ( id varchar(36) primary key, ts timestamp );
insert into test_table (id,ts) values('yesterday', current_timestamp - interval 1 day);
insert into test_table (id,ts) values('midnight', current_date);
insert into test_table (id,ts) values('now', current_timestamp);
insert into test_table (id,ts) values('next midnight', current_date + interval 1 day);
insert into test_table (id,ts) values('tomorrow', current_timestamp + interval 1 day);
create index test_table_i1 on test_table (ts);
select *
from test_table
where ts >= current_date
and ts < current_date + interval 1 day;
;
PS: you can also use
select *
from test_table
where ts between current_date and current_date + interval 1 day;
if you're not picky about excluding next midnight (between accepts both boundaries)

Related

MySQL: Find birthdays between a date range, but ignoring the year

I'm trying to query for users with birthdays falling between a given date range.
The users table stores birthdays in a pair of int columns: dob_month (1 to 12) and dob_day (1 to 31). The date range I'm querying with is a pair of date-time strings, including the year.
Here's what I've got so far:
SELECT *
FROM `users`
WHERE DATE(CONCAT_WS('-', 2023, dob_month, dob_day)) BETWEEN '2023-03-01 00:00:00' AND '2023-03-31 23:59:59'
However, this doesn't work when the date range spans multiple years.
For example, 2023-12-15 00:00:00 and 2024-01-10 23:59:59.
How can I work around this? Thanks!
You can solve this by joining to a set of rows with individual dates.
Suppose you had another table called dates which had one row per day, spanning the whole range you need.
mysql> create table dates (date date primary key);
mysql> insert into dates(date)
with recursive cte as (
select '2023-01-01' as date
union
select cte.date + interval 1 day from cte where cte.date < '2025-01-01'
)
select * from cte;
Query OK, 732 rows affected (0.01 sec)
Now it's easy to query a subset of dates:
mysql> SELECT date
FROM dates
WHERE dates.date BETWEEN '2023-12-15 00:00:00' AND '2024-01-10 23:59:59';
...
27 rows in set (0.00 sec)
We create a sample user with a dob of January 3.
mysql> create table users ( id serial primary key, dob_month tinyint, dob_day tinyint);
mysql> insert into users set dob_month = 1, dob_day = 3;
You can join your users table to that subset of dates where the month and day match.
mysql> SELECT date FROM users JOIN dates
ON dob_month = MONTH(date) AND dob_day = DAY(date)
WHERE dates.date BETWEEN '2023-12-15 00:00:00' AND '2024-01-10 23:59:59';
+------------+
| date |
+------------+
| 2024-01-03 |
+------------+
In the below code, the logic is to convert dob_month and dob_day into a date and then do the comparison using BETWEEN operator.
Now the year value used for date conversion is based on the below logic :
Use the year value the same as that of "from date". If the date is less than the "from date", then push it to the next year. Use BETWEEN operator to check if the date is within the given date range. This logic is applied because to use BETWEEN operator the date has to be greater than or equal to the "from date" keeping month and day values intact.
Note Date_add(Date_add(Makedate(some_year_value, 1), INTERVAL (dob_month)-1 month), INTERVAL (dob_day)-1 day) is repeated 3 times. It is for creating a date out of the year, month, and day values.
SET #fromdate = date('2023-09-01 00:00:00');
SET #fromyear = year(#fromdate);
SET #todate = date('2024-02-28 23:59:59');
CREATE TABLE users
(
id SERIAL PRIMARY KEY,
dob_month TINYINT,
dob_day TINYINT
);
INSERT INTO users
SET dob_month = 2,
dob_day = 1;
SELECT *
FROM users
WHERE CASE
WHEN Date_add(Date_add(Makedate(#fromyear, 1),
INTERVAL (dob_month)-1 month),
INTERVAL (dob_day)-1 day) < #fromdate THEN
Date_add(Date_add(Makedate(#fromyear + 1, 1),
INTERVAL (dob_month)-1 month),
INTERVAL (dob_day)-1 day) BETWEEN #fromdate AND #todate
ELSE Date_add(Date_add(Makedate(#fromyear, 1),
INTERVAL (dob_month)-1 month),
INTERVAL (dob_day)-1 day) BETWEEN #fromdate AND #todate
end;
Psuedo code for understanding the crux:
SELECT *
FROM users
WHERE CASE
WHEN Date(from_date_year,dob_month,dob_day) < #fromdate THEN
Date(from_date_year,dob_month,dob_day) BETWEEN #fromdate AND #todate
ELSE Date(from_date_year + 1,dob_month,dob_day) BETWEEN #fromdate AND #todate
end;

mysql if column empty select, if not empty apply conditions

I'm having some difficulties on applying certain conditions if a column is empty or not.
My table is as follows:
CREATE TABLE `meets` (
`id` INT,
`scheduled` VARCHAR(255),
`status` INT
);
INSERT INTO meets(id,scheduled,status) VALUES (1,'','1');
INSERT INTO meets(id,scheduled,status) VALUES (2,'','2');
INSERT INTO meets(id,scheduled,status) VALUES (2,'1613220631','3'); // in 30 minutes
INSERT INTO meets(id,scheduled,status) VALUES (2,'1644756631','3'); // 2022
What I did so far is next:
SELECT * FROM meets WHERE FROM_UNIXTIME(scheduled) BETWEEN DATE_SUB(NOW(), INTERVAL 30 MINUTE) AND DATE_SUB(NOW(), INTERVAL -30 MINUTE) ORDER BY `id` DESC
The above only selects the record that has a timestamp in the following/past 30 minutes.
Other than that record, I also need to select record id 1 because it has status == 1.
So basically
if scheduled column is empty, check for status to be 1 and select if true;
if scheduled column is timestamp, apply condition from the query posted above;
Any ideas? Thank you!
You could add the missing rows using union
SELECT *
FROM meets
WHERE FROM_UNIXTIME(scheduled)
BETWEEN DATE_SUB(NOW(), INTERVAL 30 MINUTE) AND DATE_SUB(NOW(), INTERVAL -30 MINUTE)
ORDER BY `id` DESC
UNION
select * from meets where scheduled = '' AND status = 1

SQL where time in timestamp

I have records like:
2017-07-24 16:59:32
2017-07-24 17:53:38
2017-07-24 22:26:08
2017-07-24 23:04:54
2017-07-25 08:33:43
2017-07-25 10:06:47
And I want to write an sql query which compares only the time part of timestamp, as example:
SELECT * FROM table WHERE date BETWEEN '17:30:00' and '22:30:00'
Check only the time and ignore the date. Is it possible to do so?
I'm using MySQL
SELECT * FROM table WHERE hour('date') = 9;
Takes full hour, as I sometimes need to take only half of an hour.
This should work:
SELECT * FROM table
WHERE
(HOUR(date) BETWEEN 18 AND 21) OR
(HOUR(date) = 17 AND MINUTE(date)>=30) OR
(HOUR(date) = 22 AND MINUTE(date)<=30);
Or another approach would be to convert to DATE, add the hours and minutes and then use between.
SELECT * FROM table
WHERE date BETWEEN
ADDDATE(ADDDATE(DATE(date), INTERVAL 17 HOUR), INTERVAL 30 MINUTE)
AND
ADDDATE(ADDDATE(DATE(date), INTERVAL 22 HOUR), INTERVAL 30 MINUTE);
You can convert the DATETIME to a time and use that in the comparison.
Given the sample code:
CREATE TABLE Table1
(
Column1 VARCHAR(50),
Column2 VARCHAR(50),
Timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO
Table1
(Column1, Column2, Timestamp)
VALUES
('Valid', 'Time', '2017-01-01 17:43:01'),
('Invalid', 'Time', '2017-01-01 16:00:43');
You could query it like the following:
SELECT
*,
DATE_FORMAT(`timestamp`, '%H:%i:%s') AS Time
FROM
Table1
WHERE
DATE_FORMAT(`timestamp`, '%H:%i:%s') BETWEEN '17:30:00' AND '22:30:00';
SQL Fiddle

All MySQL records from yesterday

What is an efficient way to get all records with a datetime column whose value falls somewhere between yesterday at 00:00:00 and yesterday at 23:59:59?
SQL:
CREATE TABLE `mytable` (
`id` BIGINT,
`created_at` DATETIME
);
INSERT INTO `mytable` (`id`, `created_at`) VALUES
(1, '2016-01-18 14:28:59'),
(2, '2016-01-19 20:03:00'),
(3, '2016-01-19 11:12:05'),
(4, '2016-01-20 03:04:01');
If I run this query at any time on 2016-01-20, then all I'd want to return is rows 2 and 3.
Since you're only looking for the date portion, you can compare those easily using MySQL's DATE() function.
SELECT * FROM table WHERE DATE(created_at) = DATE(NOW() - INTERVAL 1 DAY);
Note that if you have a very large number of records this can be inefficient; indexing advantages are lost with the derived value of DATE(). In that case, you can use this query:
SELECT * FROM table
WHERE created_at BETWEEN CURDATE() - INTERVAL 1 DAY
AND CURDATE() - INTERVAL 1 SECOND;
This works because date values such as the one returned by CURDATE() are assumed to have a timestamp of 00:00:00. The index can still be used because the date column's value is not being transformed at all.
You can still use the index if you say
SELECT * FROM TABLE
WHERE CREATED_AT >= CURDATE() - INTERVAL 1 DAY
AND CREATED_AT < CURDATE();
You can use subdate to indicate "yesterday" and use date() to indicate that you want records where just the date part of the column matches. So:
SELECT *
FROM tablename
WHERE DATE(created_at) = SUBDATE(CURRENT_DATE(), INTERVAL 1 DAY)
Here is the same question with an answer. To summarize answer for you, use subdate() as suggested by Sajmon.
subdate(currentDate, 1)
using your table it should be.
select *
from tablename
where created_at between subdate(CURDATE(), 1)
and date (now() )
use:
subdate(current_date, 1)
it's awesome for your case!
SELECT subdate(current_date(), 1)
SELECT * FROM table
WHERE created_at >= subdate(current_date(), 1)
You can use this, just put tablename and columnName (Which Contain 2021/01/09 or 2022-01-11 14:56:07 etc)
select * from (TABLENAME) where DATE(columnNAME) = TODAY - 1;

MySQL Event Scheduler not working how it should?

I am trying to set up an event/scheduler to grab the last minutes worth of data every single minute of the day with phpmyadmin.
Some how it is missing data out, it picks up some of the data but misses some out.
Can anyone advise on how to tweak my queries or another way how to do this ?
Here are the queries/events I'm using . --
GET ALL DATA FROM TRANDATA WITHIN THIS DATE RANGE -
CREATE TABLE TABLE1 AS SELECT ID_NO, POS, DATE,
TIMESTAMP FROM TRANDATA WHERE DATE
BETWEEN '2014-11-01 00:00:00' AND NOW()
AND POS IN ('IW1','IW2','IW3','IW4','IW5');
SET EVENT TO KEEP BRINGING DATA OVER FROM TRANDATA EVERY MINUTE OF DAY
CREATE event TABLE1GENERATOR ON schedule every 1 minute do INSERT INTO
TABLE1(ID_NO,POS, DATE, TIMESTAMP) SELECT ID_NO,
POS, DATE FROM TRANDATA
WHERE DATE BETWEEN DATE_SUB(NOW(), INTERVAL 1 MINUTE) AND NOW() AND POS IN
('IW1','IW2','IW3','IW4','IW5');
CREATE SECOND TABLE AND FILTER ID_NO FOR FIRST DATE IT SEES (MIN)
CREATE TABLE TABLE1FILTERED AS SELECT TABLE1.*
FROM TABLE1
WHERE TABLE1.DATE BETWEEN '2014-11-01 00:00:00' AND NOW() and NOT EXISTS (
SELECT *
FROM TABLE1 T2_MIN
WHERE T2_MIN.ID_NO=TABLE1.ID_NO
AND T2_MIN.TIMESTAMP< TABLE1.TIMESTAMP
);
CREATE EVENT TO KEEP FILTERING DATA EVERY MINUTE -
CREATE event TABLE1FILTER ON schedule every 1 minute do INSERT INTO
TABLE1FILTERED (ID_NO, POS, DATE, TIME_STAMP) SELECT TABLE1.*
FROM TABLE1
WHERE TABLE1.DATE BETWEEN DATE_SUB(NOW(), INTERVAL 1 MINUTE) AND NOW()
and NOT EXISTS (
SELECT *
FROM TABLE1 T2_MIN
WHERE T2_MIN.ID_NO=TABLE1.ID_NO
AND T2_MIN.TIMESTAMP< TABLE1.TIMESTAMP
);