mysql query - insert data unix_timestamp ( now ( ) ) issue - mysql

I have an INT (11) column for storing the current timestamp in seconds. The query looks like:
INSERT INTO `abc` (id, timestamp) VALUES ('', UNIX_TIMESTAMP ( NOW () ) )
I don't know why, but the date isn't changed. It doesn't matter when I send the query, the column value isn't changed. It has 1342692014 value, but I don't know why.
Is there any option or other function for timestamps? I must store dates in seconds.

You never refer to the timestamp column in your query. You only have a string:
INSERT INTO `abc` (id, 'timestamp') VALUES ('', UNIX_TIMESTAMP ( NOW () ) )
^^^^^^^^^^^
Edit:
I get this with your updated code:
ERROR 1630 (42000): FUNCTION test.NOW does not exist. Check the
'Function Name Parsing and Resolution' section in the Reference Manual
Assuming it's not still the actual code and after fixing the syntax error, I can't reproduce your results. My educated guess is that id is an auto-incremented integer primary key, your current SQL mode is making MySQL take '' as NULL and inserting a new row... But I haven't really tested this hypothesis.
My working code is this:
CREATE TABLE `abc` (
`pk` INT(10) NOT NULL AUTO_INCREMENT,
`id` VARCHAR(10) NULL DEFAULT NULL,
`timestamp` INT(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`pk`)
)
ENGINE=InnoDB;
INSERT INTO abc (id, timestamp) VALUES ('', UNIX_TIMESTAMP());
-- Wait a few seconds
INSERT INTO abc (id, timestamp) VALUES ('', UNIX_TIMESTAMP());
-- Wait a few seconds
INSERT INTO abc (id, timestamp) VALUES ('', UNIX_TIMESTAMP());
SELECT timestamp FROM abc WHERE id='';
... and returns this:
+------------+
| timestamp |
+------------+
| 1342694445 |
| 1342694448 |
| 1342694450 |
+------------+
3 rows in set (0.00 sec)

Related

mysql merge the same data and keep the updated one later

Table Structure
CREATE TABLE `goods` (
`id` int NOT NULL ,
`name` varchar(25) ,
`updateat` datetime
)
Now there is a piece of data like this in the table
When I want to insert a new piece of data like (1,'new','2021-12-18 12:00:00').First determine whether there is the same data in the table as the data to be inserted (except for the update time),Then compare the update time, keep the latest piece of data.
I want to know how to use sql to achieve this function.
First add primary key to your table:
CREATE TABLE goods (
id int NOT NULL ,
name varchar(25) ,
updateat datetime,
PRIMARY KEY (id, name)
)
Then use ON DUPLICATE KEY UPDATE :
insert into goods values (1, 'john', '2021-01-02');
insert into goods (id, name, updateat)
values (1, 'john', '2021-01-03')
ON DUPLICATE KEY UPDATE
updateat = greatest('2021-01-03',
(select updateat from (select * from goods as g) as g where id = 1))
Fiddle
Mysql uses INSERT ON...DUPLICATE instead of merge. This statement allows you to make modifications in your case an update based on a check when duplicate entries are identified. Duplicate entries may be identified using primary keys or unique indexes. The demo below and working db fiddle gives an example of this based on your criteria.
Using a unique index to identify duplicate entries
Using INSERT ON...DUPLICATE with the VALUES (used to identify currently inserted values) and a case expression to determine which updatedat date is more recent.
CREATE TABLE `goods` (
`id` int NOT NULL ,
`name` varchar(25) ,
`updateat` datetime
);
✓
-- use a unique index if you are interested in ensuring a subset of columns are unique and
-- these columns do not meet the criteria to be a primary/composite key based on your database design
create unique index uk_id_name on goods(id,name);
✓
insert into goods values (1,'new','2021-12-18 12:00:00');
✓
-- this should fail because of the duplicate unique index
insert into goods values (1,'new','2021-12-18 12:00:00');
Duplicate entry '1-new' for key 'uk_id_name'
select * from goods;
id | name | updateat
-: | :--- | :------------------
1 | new | 2021-12-18 12:00:00
insert into goods values (1,'new','2021-12-18 12:00:01')
on duplicate key update updateat= CASE
WHEN updateat > VALUES(updateat) THEN updateat
ELSE VALUES(updateat)
END;
✓
select * from goods;
id | name | updateat
-: | :--- | :------------------
1 | new | 2021-12-18 12:00:01
db<>fiddle here

phpMyAdmin: How to insert rows with restricted columns?

I have a table with auto-incremented ID, colA and colB (with set default value), e.g.:
CREATE TABLE `some_db`.`test` ( `id` INT NOT NULL AUTO_INCREMENT , `colA` INT NOT NULL , `colB` INT NOT NULL DEFAULT '0' , PRIMARY KEY (`id`)) ENGINE = InnoDB;
Now, I want user to be able to insert the new row, but at the same time DO NOT allow to modify id (auto-incremented) or colB (just use default value).
Is that possible?
I tried to give INSERT and UPDATE only for colA, but that still gives me INSERT command denied error:
GRANT SELECT, INSERT (`colA`), UPDATE (`colA`) ON `some_db`.`test` TO 'test_user'#'%';
I don't know if that matters, I'm using MariaDB.
Thanks!
EDIT:
OK, I need to re-state my question now.
After executing e.g.:
INSERT INTO `test` (`colA`) VALUES (10)
Everything is working fine.
But phpmyadmin GUI (that I use as a front-end here) is translating to:
INSERT INTO `test` (`id`, `colA`, `colB`) VALUES (NULL, 10, ``)
...when no values are given, and it can't be executed (#1143 - INSERT command denied to user test_user#...
So, is there any way that rows can be inserted through phpmyadmin GUI (not SQL command) with such restrictions? (I edited the question title).
CREATE TABLE `test` ( `id` INT NOT NULL AUTO_INCREMENT ,
`colA` INT NOT NULL ,
`colB` INT NOT NULL DEFAULT '0' ,
PRIMARY KEY (`id`)) ENGINE = InnoDB;
CREATE TRIGGER tr_bi_test
BEFORE INSERT
ON test
FOR EACH ROW
SET NEW.id = NULL, NEW.colB = 0;
INSERT INTO test (colA) VALUES (11);
INSERT INTO test (colA, colB) VALUES (22, 222);
INSERT INTO test (id, colA) VALUES (3333, 33);
INSERT INTO test (id, colA, colB) VALUES (4444,44,444);
SELECT * FROM test;
id
colA
colB
1
11
0
2
22
0
3
33
0
4
44
0
db<>fiddle here
You cannot use DEFAULT keyword for assigning the value to NEW.colB - in MariaDB it is treated as NULL while using in a trigger. So you need to hardcode this default value, or you may query it from INFORMATION_SCHEMA.COLUMNS.

MySQL INSERT INTO query column value equals another SQL SELECT query

Could anybody kindly guide me on correct direction for below query? It's not working under phpMyAdmin.
INSERT INTO `Setting`
(`id`, `type`, `name`, `value`, `parentId`, `createdAt`, `updatedAt`, `createdById`, `updatedById`)
VALUES
(NULL, 0, 'howItWorks', 'Some URL', NULL, NULL, NULL, -1, NULL),
(NULL, 0, 'howItWorksThumb', 'Some URL', (SELECT id FROM Setting WHERE name = 'howItWorks'), NULL, NULL, -1, NULL);
Same kind of query works under PostgreSQL.
Error I am getting: #1093 - You can't specify target table 'Setting' for update in FROM clause
Question is update to explained issues related to LAST_INSERT_ID() solutions:
To use LAST_INSERT_ID() solutions; child row should be inserting immediately after parent row.
I want to get the parentId for child row not immediately after I insert parent row. What will be the solution?
Also what if I want to add two children for same parent row?
MySQL doesn't allow you to SELECT in a subquery from the same table that you're inserting into in the main query. So you'll need to split this into two INSERT queries:
You can use LAST_INSERT_ID() to get the auto-increment ID that was assigned in the last INSERT, rather than using a subquery.
INSERT INTO `Setting` (`id`, `type`, `name`, `value`, `parentId`, `createdAt`, `updatedAt`, `createdById`, `updatedById`)
VALUES (NULL, 0, 'howItWorks', 'Some URL', NULL, NULL, NULL, -1, NULL);
INSERT INTO `Setting` (`id`, `type`, `name`, `value`, `parentId`, `createdAt`, `updatedAt`, `createdById`, `updatedById`)
VALUES (NULL, 0, 'howItWorksThumb', 'Some URL', LAST_INSERT_ID(), NULL, NULL, -1, NULL);
Unfortunately, using LAST_INSERT_ID() still doesn't allow you to combine them into a single query, because it calls the function before doing any inserts.
If you're doing the second insert later, you can do it with a normal INSERT ... SELECT ...:
INSERT INTO `Setting` (`id`, `type`, `name`, `value`, `parentId`, `createdAt`, `updatedAt`, `createdById`, `updatedById`)
SELECT NULL, 0, 'howItWorksThumb', 'Some URL', id, NULL, NULL, -1, NULL
FROM Setting
WHERE name = 'howItWorks'
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
, type TINYINT NOT NULL
, name VARCHAR(100) NOT NULL
, value VARCHAR(100) NOT NULL
, parentId INT NULL
, createdById INT NOT NULL
);
It would be sensible to bind the following into a transaction.
INSERT INTO my_table
( type
, name
, value
, createdById
)
VALUES
( 0
, 'howItWorks'
, 'Some URL'
, -1
);
INSERT INTO my_table
( type
, name
, value
, parentId
, createdById
)
SELECT 0
, 'howItWorksThumb'
, 'Some URL'
, LAST_INSERT_ID()
, -1
FROM my_table;
End of transaction
SELECT * FROM my_table;
+----+------+-----------------+----------+----------+-------------+
| id | type | name | value | parentId | createdById |
+----+------+-----------------+----------+----------+-------------+
| 1 | 0 | howItWorks | Some URL | NULL | -1 |
| 2 | 0 | howItWorksThumb | Some URL | 1 | -1 |
+----+------+-----------------+----------+----------+-------------+
see the data type of the table that you created. and see also DEFAULT on the field that you create. If ID is NULL should DEFAULT = auto_increment.

MySQL error #1690 (BIGINT UNSIGNED value is out of range) for UNIX_TIMESTAMP()

i get error #1690 - BIGINT UNSIGNED value is out of range for this query:
SELECT * FROM `user`
WHERE ROUND( ( UNIX_TIMESTAMP() - `expire` ) / 86400 ) = 7
i read about this error in Stackoverflow and see some notes about cast but i can't apply them to this query.
Your second value in table will give negative result, so you get an error.
To make negative results possible in your case, use before query
SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';
Schema
CREATE TABLE IF NOT EXISTS `user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`expire` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;
--
-- Dumping data for table `test`
--
truncate table user;
INSERT INTO `user` (`id`, `expire`) VALUES
(1, 1234567890),
(2, 1923456780),
(3, 1449397282),
(4,1449397282+3600); -- note this is based on this moment I am writing this about a day ahead
Query
select id,expire,seconds from
( select id,expire,TIME_TO_SEC(TIMEDIFF(from_unixtime(expire), now())) as seconds
from user
) xDerived
where seconds>0 and seconds<604800; -- # of seconds in a week
+----+------------+---------+
| id | expire | seconds |
+----+------------+---------+
| 4 | 1449400882 | 2870 |
+----+------------+---------+
So things that have not expired yet, but will within 1 week

How to use INSERT... ON DUPLICATE?

Structure table:
CREATE TABLE IF NOT EXISTS `table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`rows_id` int(11) NOT NULL,
`url_id` int(11) NOT NULL,
`keyword_id` int(11) NOT NULL,
`date` datetime NOT NULL,
`seet` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;
STRUCTURE TABLE WITH TEST ROWS ON SQLFIDDLE
query insert:
INSERT INTO `table` (`id`, `rows_id`, `url_id`, `keyword_id`, `date`, `seet`)
VALUES
(1, 1, 2, 1, '2014-05-01 00:00:00', 1);
I would like insert this row or update row if table already have row with date = '2014-05-01 00:00:00' and rows_id = '1' and keyword_id = '1'.
In dev.mysql.com i see query INSERT ... ON DUPLICATE KEY UPDATE but how make insert or update in my case ?
INSERT...ON DUPLICATE KEY UPDATE (IODKU) does an update only if the values you insert conflict with an existing row based on a PRIMARY KEY or UNIQUE KEY.
So you need to define a UNIQUE KEY over the three columns or else IODKU can't tell if the row conflicts with an existing one.
ALTER TABLE `table` ADD UNIQUE KEY (date, rows_id, keyword_id);
You said in a comment above that you can have more than one row with the same rows_id. That's fine -- the unique constraint says that you can't have two rows that duplicate the same combination of three values in date, rows_id, and keyword_id. But you can have multiple rows that have the same value in any one of those columns, as long as the combination of the three is unique.
Here's a quick demo:
mysql> create table t (
id int auto_increment primary key,
d int,
r int,
k int,
unique key(d,r,k)
);
mysql> insert into t values (1,1,1,1);
Query OK, 1 row affected (0.01 sec)
mysql> insert into t values (1,1,1,1) on duplicate key update d = values(d)+1;
Query OK, 2 rows affected (0.00 sec)
mysql> select * from t;
+----+------+------+------+
| id | d | r | k |
+----+------+------+------+
| 1 | 2 | 1 | 1 |
+----+------+------+------+
From what I'm understanding from your question, this might help. This SQL Query will test if a row exists and update the row or create a new one based on whether or not that row already exists.
IF EXISTS (SELECT * FROM table WHERE date = 2014-05-01 00:00:00 AND rows_id = 1 AND keyword_id = 1)
BEGIN
UPDATE table SET Params=values
END
ELSE
BEGIN
INSERT INTO `table` (`id`, `rows_id`, `url_id`, `keyword_id`, `date`, `seet`) VALUES (1, 1, 2, 1, '2014-05-01 00:00:00', 1)
END
If the row exists (if the SELECT statement returns data) the UPDATE query will run. If the row does not exist (SELECT statement returns no data) then the INSERT INTO statement will run.