MySQL INSERT if one of primary key value doesn't match - mysql

I would like to do MySQL query like this:
if((value1 != dbPrimaryValue1) OR (value2 != dbPrimaryValue2))
INSERT ROW
else
DO NOTHING
Lets try example:
CREATE TABLE `tmp` (
`one` int NOT NULL,
`two` int NOT NULL,
`three` int NOT NULL);
ALTER TABLE `tmp`
ADD PRIMARY KEY (`one`, `two`);
INSERT INTO `tmp`
(`one`, `two`, `three`)
VALUES (1,2,3);
INSERT INTO `tmp`
(`one`,`two`,`three`)
VALUES (10,20,30),
(1,999,999),
(999,2,999),
(1,2,999)
ON DUPLICATE KEY
UPDATE `one` = `one`; // or some dummy no-source-drain operation
Result is here:
select * from tmp;
+-----+-----+-------+
| one | two | three |
+-----+-----+-------+
| 1 | 2 | 3 |
| 10 | 20 | 30 |
| 1 | 999 | 999 |
| 999 | 2 | 999 |
+-----+-----+-------+
U would like to have result like this:
select * from tmp;
+-----+-----+-------+
| one | two | three |
+-----+-----+-------+
| 1 | 2 | 3 |
| 10 | 20 | 30 |
+-----+-----+-------+
Is it possible to make this query? I'm operating with huge data and procedure like load -> compare -> save is not possible. THANKS!

Simply make both fields unique separately. For example:
CREATE TABLE `tmp` (
`one` int NOT NULL UNIQUE,
`two` int NOT NULL UNIQUE,
`three` int NOT NULL);
Or add the constraints via:
ALTER TABLE `tmp` ADD UNIQUE (`one`);
ALTER TABLE `tmp` ADD UNIQUE (`two`);

If you create a UNIQUE key constraint, the database will not allow you to insert them automatically.
From MySQL forum:
A UNIQUE index creates a constraint
such that all values in the index must
be distinct. An error occurs if you
try to add a new row with a key value
that matches an existing row. For all
engines, a UNIQUE index permits
multiple NULL values for columns that
can contain NULL.

Related

Generating another column for table based on values in existing table

Assuming following table:
CREATE TABLE `item`(
`item_id` int(11) NOT NULL AUTO_INCREMENT,
`item_serial_number` varchar(255) DEFAULT NULL,
`item_type` varchar(255) DEFAULT NULL,
PRIMARY KEY (`item_id`)
)
and following inserts:
INSERT INTO `item` (`item_id`, `item_serial_number`, `item_type`) VALUES
(1, '11232141', 'laptop'),
(2, '22343252', 'printer'),
(3, '34234244', 'printer'),
(4, '78678678', 'charger');
Which SQL commands should I look at/for if I want to add another column, namely item_type_id which will look up on every item_type varchar field value and generate values like this:
------------------------
|ID| SERIAL | TYPE |
------------------------
|1 | 11232141 | laptop |
|2 | 22343252 | printer|
|3 | 34234244 | printer|
|4 | 78678678 | charger|
------------------------
->
----------------------------------
|ID| SERIAL | TYPE | TYPE_ID |
----------------------------------
|1 | 11232141 | laptop | 1 |
|2 | 22343252 | printer| 2 |
|3 | 34234244 | printer| 2 |
|4 | 78678678 | charger| 3 |
----------------------------------
If you want to do this correctly, create a types table:
create table types (
type_id int auto_increment primary key,
type varchar(255)
);
insert into types (type)
select distinct type
from item;
Then, fix your current table:
alter table item add type_id int;
alter table item add constraint fk_types_type_id
foreign key (type_id) references types (type_id);
Then set the value:
update item i join
types t
on i.type = t.type
set i.type_id = t.type_id;
And finally drop the old column:
alter table item drop column type;
Try this-
SELECT item_id AS ID,
item_serial_number AS Serial,
item_type AS Type,
CASE
WHEN item_type = 'laptop' THEN 1
WHEN item_type = 'printer' THEN 2
WHEN item_type = 'charger' THEN 3
END TYPE_ID
FROM `inventory_item_temp`
You can use a lookup table if the list is big. If I guess you have the lookup table as below-
Table Name: Type_id_lookup
item_type type_id
laptop 1
printer 2
charger 3
Mobile 4 -- Sample other item_type
Then the query will be-
SELECT
A.item_id AS ID,
A.item_serial_number AS Serial,
A.item_type AS Type,
B.type_id TYPE_ID
FROM `inventory_item_temp` A
LEFT JOIN `Type_id_lookup` B ON A.item_type = B.item_type
You can use the DENSE_RANK analytical function:
select ID, SERIAL, TYPE,
DENSE_RANK() OVER (ORDER BY SERIAL DESC NULLS LAST) AS TYPE_ID
FROM YOUR_TABLE
But note that, This will give ID 1 to the printer, 2 to laptop and 3 to the charger. but it will be dynamic so no need to give static values in the query.
Cheers!!

Insert statement in self-join table

What is the correct statement to make an insert in a table with a self-join?
If I try to make a classic insert I get the error:
Cannot add or update a child row: a foreign key constraint fails
This is my insert query:
insert into mTable(record_name,self_fk,val, note, ref,insert_date, end_date)
values('processo prova',0,1,'nota di prova', 'az12345', NOW(), NOW());
In your INSERT query, you are referencing to a foreign key (the id 0) that doesn't exist -> constraint fails
I saw in your edits, before you roll it back, your CREATE TABLE script.
The field containing the reference to the parent was created this way :
`id_processo_padre` int(11) NOT NULL DEFAULT '1'
I suggest you to edit this field to make it nullable :
ALTER TABLE `mTable` MODIFY `id_processo_padre` int(11) NULL;
This will allow you to INSERT the first top level parent (or any top level parent)
insert into mTable(record_name, self_fk, ...)
values('processo prova', NULL, ...);
-- ^--^----------This
Test it yourself :
Schema (MySQL v5.7)
CREATE TABLE test
(
id INT(6) NOT NULL PRIMARY KEY AUTO_INCREMENT,
parent_id INT(6) NULL,
someData VARCHAR(255),
FOREIGN KEY (parent_id) REFERENCES test(id)
);
INSERT INTO test VALUES (default, null, "parent"),
(default, 1, "child1_1"),
(default, 1, "child1_2"),
(default, 3, "child2_2");
Query #1
SELECT t1.*, t2.someData AS "My parent's name" FROM test t1
LEFT JOIN test t2
ON t2.id = t1.parent_id
ORDER BY t1.id ASC;
Output
| id | parent_id | someData | My parent's name |
| --- | --------- | -------- | ---------------- |
| 1 | null | parent | null |
| 2 | 1 | child1_1 | parent |
| 3 | 1 | child1_2 | parent |
| 4 | 3 | child2_2 | child1_2 |
View on DB Fiddle

Possible to have an ID (auto incremented) as the second column of a MySQL primary key?

Is it possible to have an id (auto incremented) as the second column of a MySQL primary key? see order table below.
My idea is that it would be faster for MySQL to access orders through the primary key index (customer_id, id) when I query the order table with customer_id.Thanks
Customer
+-------------+
| id (autoinc)| --> primary key
|- - - - - - -|
| name |
| address |
+-------------+
|
|
|
A
Order
+------------------+
| customer_id (fk) | --- primary key
| id (autoinc) | --- primary key
|- - - - - - - - - |
| date |
+------------------+
You can do this with the following table syntax, but I'm not really sure what performance benefit that you're going to get. I'll look into it and update my answer.
CREATE TABLE your_table (a INT NOT NULL, b INT NOT NULL AUTO_INCREMENT UNIQUE);
ALTER TABLE your_table ADD PRIMARY KEY (a, b);
But, you can't drop the UNIQUE key on b.
Building on the answer from gr1zzly be4r...
InnoDB actually allows you to use an auto-increment as the first column of any KEY, not necessarily just a UNIQUE KEY.
CREATE TABLE `your_table` (
`a` int(11) NOT NULL,
`b` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`a`,`b`),
KEY `b` (`b`)
) ENGINE=InnoDB;
INSERT INTO your_table (a) VALUES (42), (43);
SELECT * FROM your_table;
+----+---+
| a | b |
+----+---+
| 42 | 1 |
| 43 | 2 |
+----+---+
In other words, the b column doesn't necessarily need to be unique.

How to add colum with INT data type to an already created table using mysql

Regarding the question, I was able to create the table using the following command:
mysql> alter table contact_list ADD contact_ID int;
Based on the command above, is there a way to add incremental number values when creating added column?
The new column doesn't need to be a primary key, as some people think. It just needs to be AUTO_INCREMENT, which only requires that it be the first column in any index (but not strictly the primary key index).
Here's a demo:
create table foo (id int primary key);
insert into foo values (123), (456), (789);
alter table foo add column x int auto_increment, add key (x);
select * from foo;
+-----+---+
| id | x |
+-----+---+
| 123 | 1 |
| 456 | 2 |
| 789 | 3 |
+-----+---+
If you already have an AUTO_INCREMENT column in this table, you can't define a second one in the same table.
create table foo (id int auto_increment primary key);
insert into foo values (123), (456), (789);
alter table foo add column x int auto_increment, add key (x);
ERROR 1075 (42000): Incorrect table definition; there can be only one auto
column and it must be defined as a key
So you can't automatically populate the new column as you create it. You have to assign the incrementing values manually with an UPDATE statement.
alter table foo add column x int;
select * from foo;
+-----+------+
| id | x |
+-----+------+
| 123 | NULL |
| 456 | NULL |
| 789 | NULL |
+-----+------+
update (select #x:=0) t, foo set foo.x = (#x:=#x+1);
select * from foo;
+-----+------+
| id | x |
+-----+------+
| 123 | 1 |
| 456 | 2 |
| 789 | 3 |
+-----+------+
You can do it only if your table does not have a primary key, and you are willing to make the contact_id a new primary key:
alter table test add contact_id int not null auto_increment primary key;
Demo:
create table test (name varchar(10));
insert into test(name) values ('quick');
insert into test(name) values ('brown');
insert into test(name) values ('fox');
insert into test(name) values ('jumps');
insert into test(name) values ('over');
insert into test(name) values ('the');
insert into test(name) values ('lazy');
insert into test(name) values ('dog');
alter table test add contact_id int not null auto_increment primary key;
select contact_id, name from test
id name
__ ______
1 quick
2 brown
3 fox
4 jumps
5 over
6 the
7 lazy
8 dog
Demo on sqlfiddle.

How can I set an AUTO_INCREMENT field to start with the value 6000 in MySQL?

How can I set a non-auto-increment field to auto increment in MySQL? And how can I set the auto increment start value to 6000?
... how set a field auto increment with start value 6000 in mysql?
If your table already exists:
ALTER TABLE your_table AUTO_INCREMENT = 6000;
If you are creating your table from scratch:
CREATE TABLE your_table () AUTO_INCREMENT = 6000;
Source and further reading:
MySQL 5.1 Reference Manual :: Using AUTO_INCREMENT
Test case:
CREATE TABLE users (
user_id int NOT NULL,
name varchar(50),
PRIMARY KEY (user_id)
);
INSERT INTO users VALUES (1, 'Bob');
INSERT INTO users VALUES (2, 'Joe');
INSERT INTO users VALUES (3, 'Paul');
ALTER TABLE users MODIFY user_id int NOT NULL AUTO_INCREMENT;
ALTER TABLE users AUTO_INCREMENT = 6000;
INSERT INTO users (name) VALUES ('Keith');
INSERT INTO users (name) VALUES ('Steve');
INSERT INTO users (name) VALUES ('Jack');
SELECT * FROM users;
+---------+-------+
| user_id | name |
+---------+-------+
| 1 | Bob |
| 2 | Joe |
| 3 | Paul |
| 6000 | Keith |
| 6001 | Steve |
| 6002 | Jack |
+---------+-------+
6 rows in set (0.01 sec)
ALTER TABLE tbl_name AUTO_INCREMENT = 6000
but be aware you should have no PK lager 6000 in this table !
mysql will show you the correct syntax for this, and more, if you execute the following for a table that contains an auto increment PK & some data already:
SHOW CREATE TABLE your_tablename;