Retrieve records using epoch date in mysql - mysql

I have a table named as data_stats. Please check below respective schema:
CREATE TABLE `data_stats` (
`uuid` varchar(255) PRIMARY KEY NOT NULL COMMENT 'Primary Key',
`state` varchar(255) NOT NULL DEFAULT 'Active',
`created_at` BIGINT(20) NOT NULL COMMENT 'Timestamp of when the record was created',
`updated_at` BIGINT(20) NOT NULL COMMENT 'Last updated timestamp');
I am storing created_at and update_at timestamp in the epoch format.
Now I need to find all the records that are updated today (i.e update_at date == today's date)
I tried below query
SELECT * FROM `data_stats` where FROM_UNIXTIME(updated_at,"%Y-%m-%d") = CURRENT_DATE
But I am getting empty results. So how can fetch records that are updated today?

Could be a mismatch in the types on the equals. To make sure, check to see if coercing both sides to DATE helps. Replace FROM_UNIXTIME(updated_at,"%Y-%m-%d") = CURRENT_DATE with:
DATE(FROM_UNIXTIME(updated_at)) = DATE(CURRENT_DATE)

Related

Get value of timestamp column value in sql

I am writing a sql query to retrieve the records from date range of a month but I did not get the result. Below is my query that I tried to run.
SELECT uid FROM sessions WHERE TIMESTAMP >= '2021-10-01 00:00:00' AND TIMESTAMP < '2021-10-31 00:00:00'
timestamp column contain value in numeric
see link:
CREATE TABLE sessions (
uid int(10) unsigned NOT NULL COMMENT 'The users.uid corresponding to a session, or 0 for anonymous user.',
sid varchar(128) CHARACTER SET ascii NOT NULL COMMENT 'A session ID (hashed). The value is generated by Drupal''s session handlers.',
hostname varchar(128) CHARACTER SET ascii NOT NULL DEFAULT '' COMMENT 'The IP address that last used this session ID (sid).',
timestamp int(11) NOT NULL DEFAULT '0' COMMENT 'The Unix timestamp when this session last requested a page. Old records are purged by PHP automatically.',
session longblob COMMENT 'The serialized contents of $_SESSION, an array of name/value pairs that persists across page requests by this session ID. Drupal loads $_SESSION from here at the start of each request and saves it at the end.',
PRIMARY KEY (sid),
KEY timestamp (timestamp),
KEY uid (uid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Drupal''s session handlers read and write into the sessions…'
Use UNIX_TIMESTAMP to convert the datetime strings to unix timestamp numbers
SELECT uid
FROM sessions
WHERE `TIMESTAMP` >= UNIX_TIMESTAMP('2021-10-01 00:00:00')
AND `TIMESTAMP` <= UNIX_TIMESTAMP('2021-10-31 23:59:59')
First of all, you should'nt use 'TIMESTAMP' as a column name. But I think if only one example. If not, change it.
You have some options.
Using BETWEEN command
SELECT uid FROM sessions WHERE TIMESTAMP BETWEEN '2021-10-01 00:00:00' AND '2021-10-31 00:00:00'
Using MONTH and YEAR
SELECT uid FROM sessions WHERE MONTH(TIMESTAMP) = MONTH('2021-10-01 00:00:00') AND YEAR(TIMESTAMP) = YEAR('2021-10-01 00:00:00')

When i Create table with Month he only given 0000-00-00

I create table for hour
CREATE TABLE hour (
Name1 varchar(25) not null,
Datee Datetime not null DEFAULT (CURRENT_TIMESTAMP()),
Monthh date not null DEFAULT (MONTH(CURRENT_DATE()))
);
Mysql only give me 0000-00-00 not Name where i use button in php. What is wrong with this and how correct? In my opinion my phpadmin dont have a MONTH function
CREATE TABLE hour ( Name1 varchar(25) not null,
Datee DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
Monthh TINYINT NOT NULL DEFAULT (MONTH(CURRENT_TIMESTAMP))
);
fiddle
PS. HOUR is Reserved word - I'd recommend to rename a table.
Store full timestamp and it's month part in separate columns in same table is absolutely redundant. You can story only datetime and get it's month in select query:
CREATE TABLE Godzina (
Nazwa varchar(25) not null,
Randka Datetime not null DEFAULT CURRENT_TIMESTAMP()
);
INSERT INTO Godzina (Nazwa) VALUES ('TestName');
SELECT
Nazwa,
Randka,
MONTH(Randka) AS Miesiac
FROM Godzina;
Test it on SQLize.online

MySQL - Select unique column with max timestamp

I'm trying to prepare a query and I'm having a hard time with it. I need some MySQL gurus to help please...
Take the following table as an example...
CREATE TABLE order_revision (
id int(11) NOT NULL,
parent_order_id int(11) NOT NULL,
user_id int(11) DEFAULT NULL,
sub_total decimal(19,4) NOT NULL DEFAULT '0.0000',
tax_total decimal(19,4) NOT NULL DEFAULT '0.0000',
status smallint(6) NOT NULL DEFAULT '1',
created_at int(11) NOT NULL,
updated_at int(11) DEFAULT NULL
)
I need a query to select all unique 'parent_order_id' with the max 'updated_at' value. This query should return all rows that have unique 'parent_order_id's based on the max timestamp of the 'updated_at' column.
In other words, each row returned should have an unique 'parent_order_id' and be the maximum timestamp of the'updated_at' column.
Basically this query would find the latest "order revision" for each "parent order"
You mean:
SELECT parent_order_id,max(updated_at) FROM order_revision GROUP BY parent_order_id
For MySQL, the GROUP BY-clause isn't even necessary, nevertheless I would include it for clarification (and most other SQL-conform servers require it).
For anyone interested, this query turned out to be the one I was looking for...
SELECT main.*
FROM order_revision AS main
WHERE main.id = (
SELECT sub.id
FROM order_revision AS sub
WHERE main.parent_order_id = sub.parent_order_id
ORDER BY sub.updated_at DESC
LIMIT 1
);

MySQL filesort on GROUP BY YEAR & Month

I have a large table that stores debug information for my web app. The issue is that the table is now 500,000 rows and one of the queries is slow because the index isn't being used.
SQL:
EXPLAIN SELECT count(*) AS `count`, month(event_date) AS `month`, year(event_date) AS `year`FROM events WHERE 1 = 1 GROUP BY year(event_date) DESC, month(event_date) DESC LIMIT 6;
Result:
SIMPLE events index NULL event_date 8 NULL 139358 Using index; Using temporary; Using file sort
And here is the table structure.
CREATE TABLE IF NOT EXISTS `events` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Event Primary Key',
`event_number` int(11) NOT NULL,
`user_id` int(11) unsigned NOT NULL COMMENT 'User ID',
`server_id` int(11) unsigned DEFAULT NULL COMMENT 'The ID of the remote log client',
`remote_id` int(11) unsigned DEFAULT NULL COMMENT 'The Event Primary Key from the remote client',
`event_date` datetime NOT NULL COMMENT 'Event Datetime in local timezone',
`event_date_utc` datetime NOT NULL COMMENT 'Event Datetime in UTC timezone',
`event_type` varchar(255) NOT NULL COMMENT 'The type of event',
`event_source` varchar(255) NOT NULL COMMENT 'Text description of the source of the event',
`event_severity` varchar(255) NOT NULL COMMENT 'Notice, Warning etc',
`event_file` text NOT NULL COMMENT 'The full file location of the source of the event',
`event_file_line` int(11) NOT NULL COMMENT 'The line in the file that triggered the event',
`event_ip_address` varchar(255) NOT NULL COMMENT 'IP Address of the user that triggered the event',
`event_summary` varchar(255) NOT NULL COMMENT 'A summary of the description',
`event_description` text NOT NULL COMMENT 'Full description of the event',
`event_trace` text NOT NULL COMMENT 'Full PHP trace',
`event_synced` int(1) unsigned DEFAULT '0',
PRIMARY KEY (`id`),
KEY `event_type` (`event_type`),
KEY `event_source` (`event_source`),
KEY `user_id` (`user_id`),
KEY `server_id` (`server_id`),
KEY `event_date` (`event_date`)
)
If anyone has any ideas on getting the same results without a file sort that would be awesome!
GROUP BY implies ORDER BY in MySQL
So try adding ORDER BY NULL: this usually eliminates a filesort
See "ORDER BY Optimization" in the MySQL docs
Your key problem is that you are specifying no WHERE clause. Your use of WHERE 1=1 is pointless. The problem is that you are trying to get the YEAR and MONTH from MySQL without limiting the number of rows, and therefore it processes MONTH(..) and YEAR(...) for each row before it is able to process the GROUP.
The fact it still isn't using the INDEX after my earlier suggestion indicates you have more to your query than you are letting on, if that's the case please let me know and I can help you more easily. Otherwise, I would recommend checking below (though I'm having to guess at your purposes as you haven't stated what you are trying to achieve)
If you are after the last 6 calendar months specifically then the following would also help significantly.
SELECT
COUNT(id) AS `count`,
MONTH(event_date) AS `month`,
YEAR(event_date) AS `year`
FROM events
-- Get the first day of this month, and subtract 6 months
WHERE event_date > SUBDATE(DATE_FORMAT(NOW(), '%Y-%m-01'), INTERVAL 6 MONTH)
GROUP BY `year` DESC, `month` DESC;
If you have additional WHERE criteria though, that would change the advice given so if that's the case please update
In addition to what the others have posted:
If you run an EXPLAIN SELECT... and MySQL reports that it uses no index for that query (or not the one you want), you could solve this by querying the data with SELECT... FORCE INDEX.... For more details about the syntax of this, look here: http://dev.mysql.com/doc/refman/5.6/en/index-hints.html
You are using SELECT * which means select all rows so the whole table is scanned - try selecting specific rows to show
Also there are no parameters to filter the data so the whole table is read and returned, try restricting either by date or some other parameter

MySQL ON UPDATE CURRENT_TIMESTAMP not updating

I've got a table that looks like this:
CREATE TABLE IF NOT EXISTS `Hosts` (
`id` int(128) NOT NULL AUTO_INCREMENT,
`IP` varchar(15) NOT NULL DEFAULT '',
`Port` varchar(5) NOT NULL DEFAULT '',
`Password` varchar(32) NOT NULL DEFAULT '',
`Username` varchar(32) NOT NULL DEFAULT '',
`Tid` varchar(32) NOT NULL DEFAULT '',
`EquipType` varchar(64) NOT NULL DEFAULT '',
`Version` varchar(128) DEFAULT NULL,
`Status` varchar(10) NOT NULL DEFAULT '',
`Location` varchar(128) NOT NULL DEFAULT '',
`Lastconnection` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
`Lastbackup` date NOT NULL DEFAULT '0000-00-00',
`Backupstatus` varchar(64) NOT NULL DEFAULT '',
`Backupmsg` text,
`Backupfile` varchar(30) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `IP` (`IP`),
KEY `Tid` (`Tid`),
KEY `EquipType` (`EquipType`),
KEY `Status` (`Status`),
KEY `Lastbackup` (`Lastbackup`),
KEY `Backupstatus` (`Backupstatus`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=716 ;
In my mind, this means that any time a row is updated, the field 'Lastconnection' should be stamped with the current timestamp. However, when I run something like:
update Hosts set Backupstatus = 'FAIL', Backupmsg = 'Connection timed out' where Tid = 'SITE001'
Lastconnection stays '0000-00-00 00:00:00'. There's either a database issue I'm not seeing, or I'm completely misunderstanding the 'ON UPDATE CURRENT_TIMESTAMP' clause.
Have you tried to use null for that field when updating?
You could also try setting default value to CURRENT_TIMESTAMP, rather than 0000-00-00 00:00:00.
Nevertheless, whenever I want to have creation and update time I always use the following:
...
CREATED timestamp NOT NULL default '0000-00-00 00:00:00',
UPDATED timestamp NOT NULL default now() on update now(),
....
I use now(), because is an alias for CURRENT_TIMESTAMP and it is shorter. At the end, table structure gets CURRENT_TIMESTAMP, so don't worry.
The trick with CREATED field is to remember to use null on both fields for INSERT statements, for UPDATE statements it is not required:
INSERT INTO mytable (field1, field2, created, updated)
VALUES ('foo', 'bar', null, null);
It might be the case that the update statement doesn't change anything. If the row with Tid = 'SITE001' already has Backupstatus set to 'FAIL' and Backupmsg set to 'Connection timed out' (maybe, set by some previous backup attempt), then MySQL will skip this row and therefore won't change the Lastconnection timestamp.
Also, I see ON UPDATE CURRENT_TIMESTAMP more like an administrative feature to keep track of data changes. As a programmer, I would add the timestamp update explicitly:
update Hosts
set Backupstatus = 'FAIL', Backupmsg = 'Connection timed out', Lastconnection = NOW()
where Tid = 'SITE001'.
You must remember that if no value was changed on update it won't set the current time stamp,
You have to set the value in query NOW() to set for the current time stamp !!!
update Hosts set Backupstatus = 'FAIL',Lastconnection = NOW() , Backupmsg = 'Connection timed out' where Tid = 'SITE001'
Remember the value must change in order for the current time stamp to change.
To specify automatic properties, use the DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses. The order of the clauses does not matter. If both are present in a column definition, either can occur first. Any of the synonyms for CURRENT_TIMESTAMP have the same meaning as CURRENT_TIMESTAMP. These are CURRENT_TIMESTAMP(), NOW(), LOCALTIME, LOCALTIME(), LOCALTIMESTAMP, and LOCALTIMESTAMP().
Use of DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP is specific to TIMESTAMP. The DEFAULT clause also can be used to specify a constant (nonautomatic) default value; for example, DEFAULT 0 or DEFAULT '2000-01-01 00:00:00'.
DEFAULT 0 do not work if the NO_ZERO_DATE SQL mode is enabled because that mode causes “zero” date values (specified, for example, as 0 '0000-00-00 00:00:00') to be rejected. Be aware that the TRADITIONAL SQL mode includes NO_ZERO_DATE.
In addition, you can initialize or update any TIMESTAMP column to the current date and time by assigning it a NULL value, unless it has been defined with the NULL attribute to permit NULL values.
If you want the record to automatically update the timestamp whenever the record is changed, here's the four simple steps you need to accomplish (could be all in one step, depending on if you're using command line or GUI to administer):
Create field to hold auto-updated timestamp (I typically call mine 'modified').
Specify field Type as 'TIMESTAMP'
Specify field Default as 'CURRENT_TIMESTAMP'
Specify field Extra as 'ON UPDATE CURRENT_TIMESTAMP'
Now the field that contains your timestamp will always be updated to the current timestamp anytime the record is updated.