querying varchar date timestamp and ordering by date descending - mysql

I have a database of articles that has the date the article was published as a UNIX timestamp that is saved as a varchar value. For example, one article's datePublished value is 1667865600000 (varchar).
I'm querying the database to return articles with a certain keyword in it from the last 90 days. But I don't think my current approach is successfully querying the database for the 'datePublished' value, since my date published value is a varchar and not a date value. However, I can't verify this because it's not letting me know if ('datePublished' > DATE_SUB(now(), INTERVAL 90 DAY)) is actually doing anything or not. I do think it is ordering by datePublished DESC successfully, though.
How do I properly query the database's datePublished value as a varchar UNIX timestamp?
Here is my query
SELECT *
FROM news
WHERE
(MATCH(snippet) AGAINST("example" IN BOOLEAN MODE))
AND ('datePublished' > DATE_SUB(now(), INTERVAL 90 DAY))
ORDER BY datePublished DESC LIMIT 100

You can filter directly against the Unix timestamp:
datePublished > unix_timestamp(now() - interval 90 day)
That should be good enough for MySQL to implicitly cast the string to a number. But if that's not happening, then we can force it like so:
datePublished + 0 > unix_timestamp(now() - interval 90 day)
Note that I fixed your original query, where you had the column name surrounded with single quotes ; this trivial typo causes the literal column name to be used as fixed value for the whole column...

Related

Mysql Delete and Timestamp

i looking for some help about MySQL, Very easy question, but really breaked my brain for some time.
i have a table called "logs", That have "date" thing, That is INT(11) of Timestamp, So, it use timestamp actual for it.
i gonna make a script that execute a SQL command each minute, That Check ALL rows, if "date" have more/equal than 6 hours, i tired so much, and nothing for help.
Some commands i used and won't worked.
DELETE FROM logs WHERE date < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 6 HOUR));
DELETE FROM logs WHERE date < NOW() - INTERVAL 6 HOUR;
Won't help, So, i asking here if you can help me, Thanks.
You can do something like that :
DELETE FROM logs
WHERE FROM_UNIXTIME(date) < UNIX_TIMESTAMP(NOW() - INTERVAL 6 HOUR);
The date "thing" is called a column. The column has a specific datatype. The question indicates that the column is datatype INT(11). And in that column is stored unix-style 32-bit integer number of seconds since 1970-01-01 UTC.
If that's all true, then the first query form is appropriate. The expression on the right side (of the less than comparison) returns an integer number of seconds.
As a demonstration, consider this expression:
SELECT UNIX_TIMESTAMP( NOW() + INTERVAL -6 HOUR ) ==> 1528450555
or, the way the original is written
SELECT UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 6 HOUR))
returns an equivalent result.
The second query can be evaluated, but the automatic conversion from DATETIME to numeric will return us an integer value like 20180608153555 (i.e. yyyymmddhhmmss), not number of seconds since the beginning of the epoch.
Consider a demonstration, DATETIME dataytpe evaluated in numeric context:
SELECT NOW() + INTERVAL -6 HOUR + 0 ==> 20180608153600
If we use that expression, compare that to an INT(11) column, and delete all rows that have an INT(11) column less than that value, it's going to delete every row in the table that has a non-NULL value in that column.
Your date column must be of Type TIMESTAMP and not INT in order to be able compare timestamps with each other properly, or you can write:
DELETE FROM logs WHERE FROM_UNIXTIME(date) < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 6 HOUR));

Losy comparison between dates

Is there a way I can make MySQL return 1 instead of 0 for SELECT NOW() = '2016-10-10' without casting (CAST('2016-10-10' AS DATE)) or converting to date (DATE('2016-10-10')).
My real case scenario is a comparison between a DATE and a DATETIME column. I want to JOIN on those columns, but that's possible only if I can make MySQL compare only the date, ignoring the time.
I can't do the cast/convert because that is very expensive ( Slow query performance left joining a view ).
It's not the '2016-10-10' string that you need to cast (since it is a valid date literal), but NOW().
NOW() returns your current timestamp, with hours, minutes and seconds. While '2016-10-10' is interpreted as '2016-10-10 00:00:00'. Which, presumably is not equal to the current time.
So
SELECT DATE(NOW()) = '2016-10-10'
UPD:
I can make MySQL compare only the date, ignoring the time.
For the comparison coldate = coldatetime you can compare on range, like:
coldate <= coldatetime AND coldate + INTERVAL 1 DAY > coldatetime
Depending on your actual case it may or may not be beneficial.

MySQL select entries from last hour based on epoch field

I need to return all the entries in a MySQL database from the last hour. The database has a column named time that has epoch values in.
This bit of psuedo code is what I want to be able to achieve but am not sure how to do this in MySQL. In another language I'd check to see that the epoch value of time in each row is no more than 3,600 different.
SELECT * FROM dailyltc WHERE `time` <= 1 hour
Not using functions to convert your stored epoch value enables MySQL the use of an index. Because of that I prefer the calculate the limits with UNIX_TIMESTAMP instead of converting the stored value to a DATETIME value.
SELECT
*
FROM
dailyltc
WHERE
`time` > UNIX_TIMESTAMP(NOW() - INTERVAL 1 HOUR);
Should newer values exist then you can simply add the upper bound:
SELECT
*
FROM
dailyltc
WHERE
`time` > UNIX_TIMESTAMP(NOW() - INTERVAL 1 HOUR)
AND
`time` <= UNIX_TIMESTAMP(NOW());

Select query for two weeks ago

In my database table I have a field for date (varchar field to save date in yy-mm-dd format ), now I want to select records for two weeks ago.
How can i do it ?
Implicit date arithmetic is fairly flexible in MySQL. You can compare dates as strings without explicit use of CAST() or DATE(), but you're trusting MySQL to interpret your format correctly. Luckily for you, it will do just fine with yy-mm-dd.
I would recommend using BETWEEN and INTERVAL so that your query is easily readable; for example:
SELECT * FROM Holidays
WHERE Date BETWEEN (NOW() - INTERVAL 14 DAY) AND NOW();
The only trick with BETWEEN is that you have to put the lower bound first and the upper bound second; for example, if you write BETWEEN 5 AND 2, this always evaluates to FALSE because there is no value that can be greater than or equal to 5 while also being less than or equal to 2.
Here's a demo of the query in action at SQL Fiddle, and a list of the recognized INTERVAL expressions in MySQL.
Note that the parentheses around the expression NOW() - INTERVAL 14 DAY are not required but I would recommend using them here purely for the sake of clarity. It makes the predicate clause just a little bit easier to read in the absence of proper syntax highlighting, at the expense of two characters.
Ideally you should be using date types to store dates, but being that's not the case, you should look into casting to date then comparing.
select * from yourtable where cast (yourdate as Date) BETWEEN Date_Add(CURDATE(), INTERVAL -21 Day) and Date_Add(CURDATE(), INTERVAL -14 Day)
Note, this is untested and may need a little tweaking, but should give you a general idea of what you need to do.
Also, if it's possible, you should really look into converting the varchar field to a date field....they have date types to prevent this sort of thing from happening, although i know changing field types isn't always a possibility.
you can simply do with ADDDATE to get 14 days ago. compare string with date will work.
SELECT *
FROM your_table
WHERE your_date >= ADDDATE(NOW(), -14) AND your_date < NOW()
I use this for select data in past of past
SELECT * FROM Holidays
WHERE a.dDate >= DATE( NOW( ) ) - INTERVAL 14
DAY AND a.dDate <= DATE( NOW( ) ) - INTERVAL 8

How can I get the date difference of a timestamp

I am trying to create a query that will limit insertion into a table based on the last time the poster sent data to the table.
For example if you posted data to the table then you are locked out of the system for another 10 hours. Here is what I came up with so far. But I get nowhere with the actual results on the data. Any help?
SELECT DATE( `date` )
FROM tablename
WHERE DATE( CURDATE( ) ) < CURDATE( ) - INTERVAL 1002
DAY
LIMIT 0 , 30
This will return a single post from the last 10 hours, if it exists:
SELECT *
FROM tablename
WHERE `date` >= NOW() - INTERVAL 10 HOUR
LIMIT 1
I'm assuming date is declared as DATETIME, since actual DATE does not contain the time part and hence is only day-accurate.
If date is an integer UNIX timestamp, use this:
SELECT *
FROM tablename
WHERE `date` >= UNIX_TIMESTAMP(NOW() - INTERVAL 10 HOUR)
LIMIT 1
There are a number of ways you could do this. Perhaps if you have a user settings table you could simply add a "last_insert" field, and store the timestamp as an integer value- that would be a super simple way to do it- you could check the current timestamp vs user_settings.last_insert and voila!
I suppose you could use datetime too. Whatever floats the boat.
First of all, you need a DATETIME column and not a DATE column. Assuming that tablename.date is a DATETIME column, then 10 hours before right now is CURRENT_TIMESTAMP - INTERVAL 10 HOUR.
First of all create a Time (TIMESTAMP DEFAULT CURRENT_TIMESTAMP) columnt in your table. It will be automatically set to current date on row insert
Then check:
SELECT COUNT(*) FROM Table WHERE Time > NOW() - INTERVAL 10 HOUR
If its 1 or more - block
You must compare the time last post was put with current time, not current time with current time :|