mysql update another column to primary key value - mysql

Is there a way to set the value of another column to primary key (auto increment)?
Basically what I am trying to achieve is this
ID Stuff
---- ------
1 1
2 324
3 64
4 94
5 ...
Now when I am adding the the fifth row with a query like
INSERT into TABLE values(NULL, NULL);
So when the second value is NULL I want it to be equal to ID.
I tried INSERT triggers but it doesnt work. Any ideas?

I don't think you can do that in one step, but you can first insert and then update...

One possibility is to expose a stored procedure, and when the Stuff parameter is null, update the insert with the LAST_INSERT_ID(), otherwise pass the non-null value to the insert.

Try this:
INSERT INTO `TABLE` (`ID`,`Stuff`) VALUES(NULL, `ID`);

Related

Get last ID of a newly inserted element, or of an existing one

I have a following map table, with a unique key on the name column:
id | name
1 aaa
2 bbb
3 ccc
I want to get a newly created ID if I insert a new value to this table, like this:
INSERT IGNORE INTO map VALUES(null, 'ddd');
I know I can do this with getLastId() function. But I also want to get ID if a name already exists, and getLastId() function returns 0 in such case:
INSERT IGNORE INTO map VALUES(null, 'ccc');
Is this possible to do with one SQL, and without checking if a record exists, etc?
I think you need to go the extra mile for that one:
check if exists - when so: get ID of that name
if not: SELECT LAST_INSERT_ID();
Depends on what qualifies as a single query.
When you make use of INSERT INTO ... ON DUPLICATE KEY UPDATE you can control the LAST_INSERT_ID() in such a manner that it will return the new id on insert and the id of the row "updated" on update:
INSERT INTO map (name) VALUE ('ccc')
ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id);
That will make the LAST_INSERT_ID() then return the map.id of the row you're interested in.
Whatever the API is that you name as the getLastId() (I don't know it so I can't provide more pointers on it) this may not work and you would then need to fire a second query to obtain it:
SELECT LAST_INSERT_ID();
See as well:
MySQL ON DUPLICATE KEY - last insert id? (Stackoverflow Q&A, Apr 2009)

Insert into SQL if entry does not exist

I want to insert a row into my database table if the value of the first column does not exist in the table.
Example:
Name Value1 Value2
------------------------
John 2 3
Max 4 6
Alex 0 0
Now I want to insert a new person with the values 0 and 0 but only if the person does not exist. For example if I tried to insert John it would not do anything. All of this should happen in one single query.
Can anyone help?
Regards, Max
You can create a unique index on table(name) and then use insert ignore or insert on duplicate key update:
create unique index unq_t_name on t(name);
insert into t(name, value1, value2)
values ($Name, $value1, $value2)
on duplicate key update name = values(name);
The on duplicate key is a non-operation -- it does nothing if the name is already in the database.
Create an index on Name, make it unique. Thereafter you will not be able to add records where the name is already in there.

How can I insert multiple values from a range into MySQL columns?

I have a MySQL database where I need add multiple values, but I need to specify a range of values just in one column.
I'm not an expert but the logic for what I need is this:
INSERT INTO ps_category_product (id_category, id_product, position) VALUES (56,BETWEEN 3 AND 5,0);
I know that is not possible to use BETWEEN in a insert into query, but how can I do something similar to specify the range of the id_product row?
How can I add all the values between 2 numbers like 3 and 5 (3,4,5) or 50 and 100 (50,51,52,...,98,99,100)
You can create a new table called range with two attributes representing the "range"... then you create a relationship(one to one) between "ps_category_product" and "new_table"...this way, in your ps_category_product table you will have a foreign key that references two values...
No, you can't use range of values while inserting. Rather, you will have to validate your insert values using a BEFORE INSERT TRIGGER something like below (a sample)
CREATE TRIGGER validaterangeTrigger
BEFORE INSERT
ON ps_category_product
FOR EACH ROW BEGIN
IF (NEW.id_product NOT BETWEEN 3 AND 5) THEN
SET NEW.id_product = 3; <-- setting a default value 3
END IF
Then you can call your INSERT statement
INSERT INTO ps_category_product (id_category, id_product, position) VALUES (56,4,0);
If the id_product value is not between 3 and 5 then trigger will set it to default value 3. You can as well choose to throw an error if validation fails.

inserting new rows to table without updating old ones

Alright, i have revised the question to also include what i have so far, and what i want to do. So here goes it:
CREATE ORDER (
product_nat_id int(3) NOT NULL,
name VARCHAR(20),
PRIMARY KEY (product_nate_id)
)
INSERT INTO ORDER(product_nat_id, name) VALUES(1, 'Product 1');
INSERT INTO ORDER(product_nat_id, name) VALUES(2, 'Product 2');
INSERT INTO ORDER(product_nat_id, name) VALUES(3, 'Product 3');
CREATE TABLE INT_PRODUCT (
product_id INTEGER NOT NULL AUTO_INCREMENT,
product_nat_id INTEGER NOT NULL,
title TINYTEXT,
dateCreate TIMESTAMP CURRENT_TIMESTAMP,
CONSTRAINT INT_PRODUCT_PK PRIMARY KEY (product_id),
UNIQUE INT_PRODUCT_NK (product_nat_id));
But what i want is, whenever a record arrives with an updated value but duplicate key, i need to insert it (and not updated), but avoid duplicate constraint based on the difference in time inserted. Hope this makes sense now.
I would suggest the following:
Look up the previous record. I assume you should know what that would be
SELECT Count(*) FROM dim WHERE recordId = '$recordid'
If in step 1 the records returned are larger than 0 then invalidate the 'previous' record:
UPDATE dim SET datevalid = '$datevalue' where recordId = '$recordid' and status = 2
Continuing with step 1 where the ecords return in the check are larger than 0 now do the insert:
INSERT INTO dim (recordId,field1,field2,date,status) VALUES (1,'sad','123123','2013-03-26',1)
If step 1 was false then just do the insert:
INSERT INTO dim (recordId,field1,field2,date,status) VALUES (1,'sad','123123','2013-03-26',1)
I would add a status field just as an extra measure when you need to find records and distinguish between valid or invalid then you do not need to filter between dates. You can then use the status field. Also have a unique auto-increment key for every record even though the data might be the same for a set of valid and invalid records. recordId and unique key will not be the same in this case. You assign the recordId and the system will assign the unique key on the table. status = 1 is valid and status = 2 is invalid.
Hope this helps!
sample code of your post like as:
Insert query syntax looks like this:
INSERT INTO table (primarykeycol,col1,col2)
VALUES (1,2,3) ON DUPLICATE KEY UPDATE col1=0, col2=col2+1
If there is already a row with primarykeycol set to 1 this query is equal to:
UPDATE table SET col1=0, col2=col2+1 WHERE primarykeycol = 1
explanation as:
Ordinarily to achieve the same result you would have to issue an
UPDATE query, then check if there were affected rows and if not
issue an INSERT query.
This way, you can do everything in one step – first try insert and
then update if insert fails.
One situation for which this type of syntax is perfect is when you
work with daily counters. For example, you might have a table with
PostID, Date and Count columns.
Each day you’d have to check if you already created an entry for
that day and if so increase the count column – and this can be
easily substituted with one INSERT … ON DUPLICATE KEY UPDATE query.
Unfortunately there are some caveats. One being that when you have
multiple unique indexes it will act as if you had an OR condition in
WHERE clause of UPDATE query.
This means that multiple rows should be update, but INSERT … ON
DUPLICATE KEY UPDATE will update only one row.
MySQL manual: INSERT ON DUPLICATE KEY UPDATE Syntax

mysql - after insert ignore get primary key

i am running a query in mysql insert ignore into........ using Python
after running the query I want to know the primary key of the row. I know there is the query
SELECT LAST_INSERT_ID();
but i'm not sure if it will work with insert ignore
what is the best way to do this?
The documentation for LAST_INSERT_ID() says:
If you use INSERT IGNORE and the row is ignored, the AUTO_INCREMENT counter is not incremented and LAST_INSERT_ID() returns 0, which reflects that no row was inserted.
Knowing this, you can make this a multi-step process:
INSERT IGNORE
if LAST_INSERT_ID(), then done (new row was inserted)
else SELECT your_primary key FROM yourtable WHERE (your inserted data's UNIQUE constraints)
Example with U.S. states:
id | abbrev | other_data
1 | AL | ...
2 | AK |
UNIQUE KEY abbr (abbrev)
Now, inserting a new row:
INSERT IGNORE INTO `states` (`abbrev`,`other_data`) VALUES ('AZ','foo bar');
> OK
SELECT LAST_INSERT_ID();
> "3"
// we have the ID, we're done
Inserting a row which will be ignored:
INSERT IGNORE INTO `states` (`abbrev`,`other_data`) VALUES ('AK','duplicate!');
> OK
SELECT LAST_INSERT_ID();
> "0"
// oops, it already exists!
SELECT id FROM `states` WHERE `abbrev` = 'AK'; // our UNIQUE constraint here
> "2"
// there we go!
Alternately, there is a possible workaround to do this in one step - use REPLACE INTO instead of INSERT IGNORE INTO - the syntax is very similar. Note however that there are side effects with this approach - these may or may not be important to you:
REPLACE deletes+recreates the row
so DELETE triggers are, um, triggered
also, the primary ID will be incremented even if the row exists
INSERT IGNORE keeps the old row data, REPLACE replaces it with new row data
Try using ON DUPLICATE KEY instead of INSERT IGNORE, maybe this can work for you:
INSERT INTO your_table (`id`,`val`) VALUES(1,'Foo') ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(`id`);
SELECT LAST_INSERT_ID();
Also see related question: MySQL ON DUPLICATE KEY - last insert id?