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

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

Related

Insert ROWS if not exists SQL

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.

update 370 records on a table while inner joined to another for a where statement

Ok, so im pretty new to SQL and im trying to write a query to replace the number 2 with the number 4 if the officeid=10 so what I have at the moment is the following. One table is called Carer_Supervisions and this is linked to another table VIA a secondary key and the officeid is on another table called carer_information.
SELECT Carer_Supervisions.SupervisionID
,Carer_Supervisions.RegionID
,Carer_Supervisions.Date_Created
,Carer_Supervisions.Created_By
,Carer_Supervisions.Complete
,Carer_Supervisions.Completed_Date
,Carer_Supervisions.Completed_By
,Carer_Supervisions.CarerID
,Carer_Supervisions.Visit_Date
,Carer_Supervisions.SSW
,Carer_Supervisions.Location
,Carer_Supervisions.Present
,Carer_Supervisions.Child1
,Carer_Supervisions.Child2
,Carer_Supervisions.Child3
,Carer_Supervisions.Child4
,Carer_Supervisions.Child5
,Carer_Supervisions.Child6
,Carer_Supervisions.Child7
,Carer_Supervisions.Child8
,Carer_Supervisions.Caring_for_Children
,Carer_Supervisions.Education
,Carer_Supervisions.Working_Team
,Carer_Supervisions.Training_and_Development
,Carer_Supervisions.Environment
,Carer_Supervisions.Concerns
,Carer_Supervisions.Personal
,Carer_Supervisions.Agency
,Carer_Supervisions.Day_Care
,Carer_Supervisions.Manager
,Carer_Supervisions.Carer_Signed
,Carer_Supervisions.Cancelled
,Carer_Supervisions.Cancel_Reason
,Carer_Supervisions.Signed_Sent
,Carer_Information.OfficeID
FROM Carer_Supervisions
INNER JOIN Carer_Information ON Carer_Supervisions.CarerID = Carer_Information.CarerID
UPDATE Carer_supervisions
SET RegionID = REPLACE(RegionID, '2', '4')
WHERE (Carer_Information.OfficeID = 10)
is this right or need amending?
This way you can update.
UPDATE CS SET RegionID= REPLACE(RegionID, '2', '4')
FROM Carer_Supervisions CS
INNER JOIN Carer_Information CI ON CS.CarerID = CI.CarerID
WHERE CI.OfficeID = 10
Try this one:
UPDATE Carer_Supervisions SET Carer_Supervisions.RegionID= REPLACE(CS.RegionID, '2', '4')
FROM Carer_Supervisions CS
INNER JOIN Carer_Information CI ON CS.CarerID = CI.CarerID
WHERE CI.OfficeID = 10

"Invalid use of group function" when insert on duplicate key update

I have trouble with my query which I want to insert and update while it is duplicate, but it said "Invalid use of group function" instead.
I have run my only "Select" statement and there was no issue like "Invalid use of group function".
here is my full code :
INSERT INTO tbl_biir_aktual(cabang_kode, periode_thn, periode_bln, pending_pp_volume, pending_pp_value)
SELECT a.cabang_kode, YEAR(a.tanggal) AS tahun, MONTH(a.tanggal)AS bulan,
SUM(a.qty_pending*a.unit_barang)AS tonase_pending, SUM(a.value_pending)AS value_pending
FROM tbl_order a,
(SELECT b.cabang_kode, MAX(b.tanggal)tanggal
FROM tbl_order b
GROUP BY b.cabang_kode, YEAR(b.tanggal), MONTH(b.tanggal)) AS max_cabang
WHERE max_cabang.cabang_kode = a.cabang_kode AND max_cabang.tanggal = a.tanggal
GROUP BY cabang_kode, YEAR(tanggal), MONTH(tanggal)
ON DUPLICATE KEY
UPDATE pending_pp_volume = SUM(a.qty_pending*a.unit_barang), pending_pp_value = SUM(a.value_pending);
well,
Hey I just found this MySQL ON DUPLICATE KEY UPDATE while inserting a result set from a query
INSERT INTO tbl_biir_aktual(cabang_kode, periode_thn, periode_bln, pending_pp_volume, pending_pp_value)
SELECT a.cabang_kode, YEAR(a.tanggal) AS tahun, MONTH(a.tanggal)AS bulan,
#tonase_pending := SUM(a.qty_pending*a.unit_barang)AS tonase_pending, #value_pending := SUM(a.value_pending)AS value_pending
FROM tbl_order a,
(SELECT b.cabang_kode, MAX(b.tanggal)tanggal
FROM tbl_order b
GROUP BY b.cabang_kode, YEAR(b.tanggal), MONTH(b.tanggal)) AS max_cabang
WHERE max_cabang.cabang_kode = a.cabang_kode AND max_cabang.tanggal = a.tanggal
GROUP BY cabang_kode, YEAR(tanggal), MONTH(tanggal)
ON DUPLICATE KEY
UPDATE pending_pp_volume = #tonase_pending, pending_pp_value = #value_pending;
I've tried that and it's done.
Tq Edper for your comment anyway....
Try using the alias in your update:
UPDATE SET pending_pp_volume = tonase_pending, pending_pp_value = value_pending
Also it's more wise to use another name for your alias for your aggregate than using the same name as your existing field name like the value_pending. Might as well changed it to TotalValuePending, so that it would be:
UPDATE SET pending_pp_volume = tonase_pending, pending_pp_value = TotalValuePending

Cancel Insert if inner query find nothing

I got the following query :
INSERT INTO contracts_settings (contract_id, setting_id, setting_value)
VALUES (:contract_id, (
SELECT setting_id
FROM settings
WHERE setting_type = :setting_type
AND setting_name = :setting_name
LIMIT 1
), :setting_value)
ON DUPLICATE KEY UPDATE setting_value = :setting_value
The value with the prefix : is replaced with data using PHP PDO::bindBalue.
If the inner query find nothing (it return NULL) but also INSERT a NULL statement. How to avoid that ?
Thanks.
Convert the INSERT ... VALUES syntax to INSERT ... SELECT:
INSERT INTO contracts_settings
(contract_id, setting_id, setting_value)
SELECT
:contract_id,
setting_id,
:setting_value
FROM settings
WHERE setting_type = :setting_type
AND setting_name = :setting_name
LIMIT 1
ON DUPLICATE KEY UPDATE
setting_value = :setting_value ;

sql insert multiple rows with inner selects

I need to insert multiple rows , but some of the data have to come from inner select
i having problem to construct the right sql statement for example i have :
insert into game_friends(
game_users_id,
game_users_id_name,
created_to_app_users_id,
created_to_app_users_id_name
) VALUES ......
now the problematic part is that the created_to_app_users_id_name and game_users_id_name i can get only by using select like this:
SELECT app_users_game_users_id_name
FROM `app_users` WHERE app_users_game_users_id = $game_users_id
and
SELECT app_users_created_to_app_users_id_name
FROM `app_users`
WHERE app_users_created_to_app_users_id = $created_to_app_users_id
how can i combine it to one sql statement using mysql
UPDATE:
Thanks to all for answering , but i guess didnt explain my problem right ...
i need to insert multiple rows that means i will have like 5-7 game_users_id coming
and it needs in the end look like ( with out the select here .. )
insert into game_friends(
game_users_id,
game_users_id_name,
created_to_app_users_id,
created_to_app_users_id_name
)
VALUES
($game_users_id, app_users_created_to_app_users_id_name, $created_to_app_users_id,app_users_created_to_app_users_id_name ),
($game_users_id, app_users_created_to_app_users_id_name, $created_to_app_users_id,app_users_created_to_app_users_id_name ),
($game_users_id, app_users_created_to_app_users_id_name, $created_to_app_users_id,app_users_created_to_app_users_id_name ),
($game_users_id, app_users_created_to_app_users_id_name, $created_to_app_users_id,app_users_created_to_app_users_id_name );
where each Values entry need to be composed from select.
try this code for PHP:
$query = "insert into game_friends(
game_users_id,
game_users_id_name,
created_to_app_users_id,
created_to_app_users_id_name
) SELECT
app_users_game_users_id,
app_users_game_users_id_name,
app_users_created_to_app_users_id,
app_users_created_to_app_users_id_name
FROM `app_users` WHERE
app_users_game_users_id = $game_users_id
AND
app_users_created_to_app_users_id = $created_to_app_users_id";
this is UNTESTED.
insert into game_friends
(
game_users_id,
game_users_id_name,
created_to_app_users_id,
created_to_app_users_id_name
)
VALUES
SELECT game_users_id,
created_to_app_users_id,
FinalTable.game_users_id_name,
FinalTable.created_to_app_users_id_name
FROM
((SELECT app_users_game_users_id as game_users_id,
app_users_game_users_id_name as game_users_id_name
FROM app_users
WHERE app_users_game_users_id = game_users_id) as iGameID
INNER JOIN
(SELECT app_users_created_to_app_users_id as created_to_app_users_id,
app_users_created_to_app_users_id_name as created_to_app_users_id_name
FROM app_users
WHERE app_users_created_to_app_users_id = created_to_app_users_id) as iCreatedID
ON iGameID.game_users_id = iCreatedID.created_to_app_users_id) as FinalTable
Simple SELECT over two tables without any JOINs should do the trick (assuming each select statement returns only one row):
INSERT INTO game_friends (
game_users_id,
game_users_id_name,
created_to_app_users_id,
created_to_app_users_id_name
)
SELECT u_game.app_users_game_users_id,
u_game.app_users_game_users_id_name,
u_created.app_users_created_to_app_users_id,
u_created.app_users_created_to_app_users_id_name
FROM `app_users` u_game,
`app_users` u_created
WHERE u_game.app_users_game_users_id = $game_users_id
AND u_created.app_users_created_to_app_users_id = $created_to_app_users_id
Another note: I am guessing that you app_users table does really have a column app_users_game_users_id or app_users_created_to_app_users_id. In which case you should replace those in the SQL with the real column name, which again I guess is either user_id, app_user_id or id. It is just that your model looks very strange otherwise assuming that both of the above mentioned columns are supposed to be unique in the table.