Insert ROWS if not exists SQL - mysql

I want to insert rows that not exist in my table
INSERT INTO [Cop].[fact_capacidadOperativa] ([id_empleado],[id_proyecto],[id_rol],[id_categoria],[id_subCategoria],[id_portfolio]
,[id_programa],[horas],[horasPlan],[id_semanaAño],[id_torre])
/*SELECT * FROM [Cop].[timeSheet]*/
SELECT id_empleado,id_proyecto,id_rol,id_categoria,id_subCategoria,
id_portfolio,id_programa,[Cop].[timeSheet].horas,[Cop].[ListaEmpleados].horaPlan,
[Cop].[timeSheet].nroSemana+[Cop].[timeSheet].año AS id_semanaAño,id_torre FROM [Cop].[timeSheet]
JOIN [Cop].[ListaEmpleados]
ON [Cop].[timeSheet].nombre = [Cop].[ListaEmpleados].recurso
LEFT JOIN [Cop].[ListaProyectos]
ON [Cop].[timeSheet].[proyecto] = [Cop].[ListaProyectos].proyecto
JOIN [Cop].[dim_empleados]
ON [Cop].[timeSheet].nombre = [Cop].[dim_empleados].empleado
LEFT JOIN [Cop].[dim_proyectos]
ON [Cop].[timeSheet].proyecto = [Cop].[dim_proyectos].proyecto
JOIN [Cop].[dim_roles]
ON [Cop].[ListaEmpleados].rol = [Cop].[dim_roles].rol
LEFT JOIN [Cop].[dim_categorias]
ON [Cop].[ListaProyectos].categoria = [Cop].[dim_categorias].categoria
LEFT JOIN [Cop].[dim_subCategorias]
ON [Cop].[ListaProyectos].subcategoria = [Cop].[dim_subCategorias].subCategoria
left JOIN [Cop].[dim_portfolios]
ON [Cop].[ListaProyectos].[portfolio] = [Cop].[dim_portfolios].portfolio
LEFT JOIN [Cop].[dim_programas]
ON [Cop].[ListaProyectos].program = [Cop].[dim_programas].programa
JOIN [Cop].[dim_torres]
ON [Cop].[timeSheet].torre = [Cop].[dim_torres].torre
imagen
Insert the values that not exist in [Cop].[fact_capacidadOperativa], i don t know if i need to use the where. this insert into is from one stored procedure that i m making
I think something like this
INSERT INTO [Cop].[fact_capacidadOperativa] ([id_empleado],[id_proyecto],[id_rol],[id_categoria],[id_subCategoria],[id_portfolio]
,[id_programa],[horas],[horasPlan],[id_semanaAño],[id_torre])
/*SELECT * FROM [Cop].[timeSheet]*/
select * from (SELECT id_empleado,id_proyecto,id_rol,id_categoria,id_subCategoria,
id_portfolio,id_programa,[Cop].[timeSheet].horas,[Cop].[ListaEmpleados].horaPlan,
[Cop].[timeSheet].nroSemana+[Cop].[timeSheet].año AS id_semanaAño,id_torre FROM [Cop].[timeSheet]
JOIN [Cop].[ListaEmpleados]
ON [Cop].[timeSheet].nombre = [Cop].[ListaEmpleados].recurso
JOIN [Cop].[ListaProyectos]
ON [Cop].[timeSheet].[proyecto] = [Cop].[ListaProyectos].proyecto
JOIN [Cop].[dim_empleados]
ON [Cop].[timeSheet].nombre = [Cop].[dim_empleados].empleado
JOIN [Cop].[dim_proyectos]
ON [Cop].[timeSheet].proyecto = [Cop].[dim_proyectos].proyecto
JOIN [Cop].[dim_roles]
ON [Cop].[ListaEmpleados].rol = [Cop].[dim_roles].rol
JOIN [Cop].[dim_categorias]
ON [Cop].[ListaProyectos].categoria = [Cop].[dim_categorias].categoria
JOIN [Cop].[dim_subCategorias]
ON [Cop].[ListaProyectos].subcategoria = [Cop].[dim_subCategorias].subCategoria
JOIN [Cop].[dim_portfolios]
ON [Cop].[ListaProyectos].[portfolio] = [Cop].[dim_portfolios].portfolio
JOIN [Cop].[dim_programas]
ON [Cop].[ListaProyectos].program = [Cop].[dim_programas].programa
JOIN [Cop].[dim_torres]
ON [Cop].[timeSheet].torre = [Cop].[dim_torres].torre) a
where not exists (select 1 from [Cop].[fact_capacidadOperativa] b where a.id_empleado = b.id_empleado
and a.id_proyecto = b.id_proyecto and a.id_rol = b.id_rol and a.id_categoria = b.id_categoria
and a.id_subCategoria = b.id_subCategoria and a.id_portfolio = b.id_portfolio and a.id_programa = b.id_programa and
a.horas = b.horas and a.horaPlan = b.horasPlan and a.id_torre = b.id_torre and a.id_semanaAño = b.id_semanaAño);
But i don t know it s the best way

As mentioned in the comment, we can create a UNIQUE constraint on all affected columns.
Then we use INSERT IGNORE to only insert valid rows in our target table from the other table(s).
Assume we have two tables, both with column1, column2 and column3 as integers. Now we want to insert all data from one of these tables to the other, but apply a unique constraint on column1 and column2 of the target table.
This will create the unique constraint:
ALTER TABLE yourtable
ADD UNIQUE (column1, column2);
Then this insert commands will only insert valid data in the table which does not violate the unqiue constraint:
INSERT IGNORE INTO yourtable
(SELECT column1, column2, column3 FROM anothertable);
I created a sample fiddle which shows the complete behaviour with and without this constraint and with or without the usage of INSERT IGNORE.
So replicate this idea here: db<>fiddle
Here is the documentation of INSERT IGNORE: documentation
All you need to do is to create the correct unique constraint for your current situation and to make sure your insert command is basically correct. Then only valid rows will be inserted, as shown in the fiddle.

Related

Can't update two tables in one Query

I've got two Queries to Update two tables:
First Table
UPDATE user_info SET `location` = ".$locationid.", `looking_for` = ".$lookingfor." WHERE `user_info`.`user_id` = ".$infoid.";
Second Table
UPDATE user_personality SET `personality` = '".$changedescription."' WHERE `user_personality`.`user_info_id` = ".$infoid.";
And I'm trying to merge those two Queries, using the same statement.
UPDATE user_info, user_personality
SET user_info.location = ".$locationid.", user_info.`looking_for` = ".$lookingfor.", user_personality.personality = '".$changedescription."'
WHERE `user_info`.`user_id` = ".$infoid."
AND `user_personality`.`user_info_id` = ".$infoid."
I'm not receiving any error message, but is not updating.
What am I doing wrong?
Thanks.
Just a guess...
"
UPDATE user_info i
JOIN user_personality p
ON p.user_info_id = i.user_id
SET i.location = $locationid
, i.looking_for = '$lookingfor'
, p.personality = '$changedescription'
WHERE i.user_id = $infoid;
";
If you set the 2 table fields equal to each other in the where clause it should work, so I believe you'd change your where clause to:
WHERE `user_info`.`user_id` = `user_personality`.`user_info_id`
AND `user_info`.`user_id` = ".$infoid."
MySQL definitely supports updating multiple tables, so the where clause that works for a multi table select statement should also work for an update.

Is it possible to use 'join' in INSERT ON DUPLICATE KEY UPDATE

I am trying to alter my code so when there is no row with a matching ean13 in webshop_stock it needs to INSERT a new row.
MYSQL is currently not accepting my code. i have tried a few things in order to get it working. My search on the worldwide-web did not find a good example with INSERT INTO - JOIN - ON DUPLICATE KEY UPDATE. So my question is, is it possible?
The problem at this moment is that my rows get created when they not exist, but the rows that exist does not get updated.
Tested the following code:
INSERT INTO webshop_stock
(id_warehouse,id_product,id_product_attribute,ean13, physical_quantity, usable_quantity)
SELECT
'1',
pa.id_product,
pa.id_product_attribute,
pa.ean13,
ai.quantity,
ai.quantity
FROM
webshop_product_attribute pa,
Adcount_input ai
WHERE
pa.ean13 = ai.ean13
AND NOT EXISTS
(SELECT id_product_attribute FROM webshop_stock
WHERE id_product_attribute = pa.id_product_attribute)
ON DUPLICATE KEY UPDATE
physical_quantity = ai.quantity,
usable_quantity = ai.quantity
Original code:
UPDATE
webshop_stock AS s
JOIN(
SELECT
pa.ean13,
pa.id_product_attribute,
pa.id_product,
ai.quantity
FROM
webshop_product_attribute pa,
Adcount_input ai
WHERE
pa.ean13=ai.ean13) q
SET
s.id_warehouse = 1,
s.id_product = q.id_product,
s.id_product_attribute = q.id_product_attribute,
s.ean13 = q.ean13,
s.physical_quantity = q.quantity,
s.usable_quantity = q.quantity
WHERE
s.id_product_attribute = q.id_product_attribute
SOLVED this code does what i need.
INSERT INTO webshop_stock
(id_warehouse, id_product, id_product_attribute, ean13, physical_quantity, usable_quantity)
SELECT
'1',
pa.id_product,
pa.id_product_attribute,
pa.ean13,
ai.quantity,
ai.quantity
FROM
webshop_product_attribute pa,
Adcount_input ai
WHERE
pa.ean13 = ai.ean13
ON DUPLICATE KEY UPDATE
physical_quantity = ai.quantity, usable_quantity = ai.quantity
The syntax is:
INSERT <table> <field list>
SELECT ... JOIN ...
There is NO INSERT JOIN SELECT in mysql. It's INSERT SELECT JOIN.
http://dev.mysql.com/doc/refman/5.1/en/insert-select.html

Update table using alias

I need to fill some fields in a table getting informations from other records of the same table.
I tried to write a query to explain what I want to do:
update globale2
set
nita = t.nita,
tita = t.tita,
notaita = t.notaita
where
neng = t.neng and
nita is null
(select nita, neng, tita, notaita from globale where uris='mma' and nita is not null) as t
edit to eplain better:
every records have these fields: "nita", "tita", "notaita", "neng" ("neng" cannot be null)
I want to fill these fields: "nita", "tita", "notaita" (where "nita" is empty)
with the same values from another record where "neng" equals the other "neng"
You can however, join the two tables.
UPDATE globale2 g
INNER JOIN globale gg
ON g.neng = gg.neng
SET g.nita = gg.nita,
g.tita = gg.tita,
g.notaita = gg.notaita
WHERE g.nita IS NULL
AND gg.uris = 'mma'
AND gg.nita IS NOT NULL
assume there is a table A_temp, with two columns 'one' and 'two'.
TABLE A_temp
ONE TWO
1 2
this is the present status of the table.
The query
UPDATE (SELECT * FROM A_temp ) A SET one = A.two where one = '1'
updates the table as
ONE TWO
2 2
Hope you get the idea and that it helps..

Operation with values in query inside stored procedure (mysql)

i have a stored procedure in mysql with a couple of queries and i need to perform some operations with that query.
This is some the code from the stored procedure:
BEGIN
SET ##session.collation_connection = ##global.collation_connection;
DROP TEMPORARY TABLE IF EXISTS innerContainers;
CREATE TEMPORARY TABLE `innerContainers` (
`id_container` INT(10) NOT NULL,
`display_name` VARCHAR(100) NOT NULL,
PRIMARY KEY (`id_container`)
)
ENGINE = memory;
INSERT INTO innerContainers(id_container, display_name)
(SELECT c1.id_container, c1.display_name
FROM container_presentation cp
LEFT JOIN presentation p USING(id_presentation)
LEFT JOIN container c1 ON p.id_container = c1.id_container
WHERE c1.isDeleted = 0 AND c1.isActive = 1 AND
cp.id_container = in_id_container)
UNION
(SELECT c1.id_container, c1.display_name
FROM container_assembly_item cp
LEFT JOIN presentation p USING(id_presentation)
LEFT JOIN container c1 ON p.id_container = c1.id_container
WHERE c1.isDeleted = 0 AND c1.isActive = 1 AND
cp.id_container = in_id_container);
SELECT mad.id_container,
mat.sign_stock,
ma.id_management_start_point,
ma.id_management_end_point,
mad.quantity
FROM management_activity ma
LEFT JOIN management_activity_type mat ON ma.id_management_activity_type = mat.id_management_activity_type
LEFT JOIN management_activity_detail mad ON ma.id_management_activity = mad.id_management_activity
LEFT JOIN management_stock_point msp ON ma.id_management_end_point = msp.id_management_stock_point
LEFT JOIN management_stock_point msp1 ON ma.id_management_start_point = msp1.id_management_stock_point
WHERE mad.id_container IN (SELECT id_container FROM innerContainers)
ORDER BY mad.id_container ASC;
END
Now, after the last query.. i need to do some operations and return a value for each id_container inside the temporary table depending on the values in the second query.
Something like this:
foreach id_container in the second query i have a resultValue and i need to:
if the sign_stock == 1 and some other conditions then resultValue -= quantity and if sign_stock == 2 and some other conditions then resultValue += quantity.
And the final resultValue after iterating over the id_container lines will be the one i want for that id_container in the temporary table.
I dont know how to do that operation.. can some one help me with that?
Don't create a temporary table unless you need the data after the procedure call. Either way, in order to iterate over the results of a SELECT query, use a CURSOR.
A simple example is provided in the linked manual page.

Merge not inserting. No error

Can someone tell me why this insert is failing but not giving me an error either? How do I fix this?
merge table1 as T1
using(select p.1,p.2,p.3,p.4,p.5 from #parameters p
inner join table1 t2
on p.1 = t2.1
and p.2 = t2.2
and p.3 = t2.3
and p.4 = t2.4) as SRC on SRC.2 = T1.2
when not matched then insert (p.1,p.2,p.3,p.4,p.5)
values (SRC.1,SRC.2,SRC.3,SRC.4,SRC.5)
when matched then update set t1.5 = SRC.5;
The T1 table is currently empty so nothing can match. The parameters table does have data in it. I simply need to modify this merge so that it checks all 4 fields before deciding what to do.
You can't select from a variable: from #parameters
See the following post: Using a variable for table name in 'From' clause in SQL Server 2008
Actually, you can use a variable table. Check it out:
MERGE Target_table AS [Target]
USING #parameters AS [Source]
ON (
[Target].col1 = [Source].col1
AND [Target].col2 = [Source].col2
AND [Target].col3 = [Source].col3
AND [Target].col4 = [Source].col4
)
WHEN NOT MATCHED BY TARGET
THEN INSERT (col1,col2,col3,col4,col5)
VALUES (
[Source].col1
,[Source].col2
,[Source].col3
,[Source].col4
,[Source].col5
)
WHEN MATCHED
THEN UPDATE SET [Target].col5 = [Source].col5;