MySQL UPDATE based on complex select - mysql

I have a query:
SELECT assets.serial, employees.uid from assets
inner join emp_as on assets.serial = emp_as.serial
inner join employees on concat(emp_as.first_name,emp_as.last_name) = concat(employees.first_name,employees.last_name)
That returns two columns, an asset serial (unique) and an employee ID. I want to update the assets.employee_id field to be the select.employee_id where the asset.serial = select.serial (select being pseudocode for the result from that query).

Without seeing your database, I can't be 100% sure this is what you want, but I believe this should work. Mysql is very kind about allowing updates on joins so you don't need to worry about creating a temp table or a subquery.
update assets
join emp_as on assets.serial = emp_as.serial
join employees on concat(emp_as.first_name,emp_as.last_name) = concat(employees.first_name,employees.last_name)
set assets.employee_id = employees.uid

This should do the job:
UPDATE assets set assets.employee_id = employees.uid
inner join emp_as on assets.serial = emp_as.serial
inner join employees on concat(emp_as.first_name,emp_as.last_name) = concat(employees.first_name,employees.last_name)

Related

how to delete from more than two (2) tables using mysql joins

I'm trying to run a multi delete on a my database but when it runs it runs with no errors but nothing was deleted? is it a case that an inner join will fail if even one of the table doesn't have anything to link to another and on?
using the query in an Express.js api I'm trying to finish us.
I usual test big queries like this in DBMS before i place them in my api.
below is the query:
DELETE task,issue,milestone,help_source,project_task,project_source,project_milestone,task_created_by,mileStone_created_by,issue_created_by,source_created_by,task_issue,milestone_task,project_creation,project
from project_creation
INNER JOIN project_milestone ON project_milestone.projectId = project_creation.projectId
INNER JOIN project_task ON project_task.projectId = project_creation.projectId
INNER JOIN project_source ON project_source.projectId = project_creation.projectId
INNER JOIN task_created_by ON task_created_by.taskId = project_task.taskId
INNER JOIN mileStone_created_by On mileStone_created_by.mileStoneId = project_milestone.mileStoneId
INNER JOIN source_created_by ON source_created_by.sourceId = project_source.sourceId
INNER JOIN task_issue ON task_issue.taskId = project_task.taskId
INNER JOIN issue_created_by ON issue_created_by.issueId = task_issue.issueId
INNER JOIN milestone_task On milestone_task.taskId = project_task.taskId
INNER JOIN task On task.taskId = project_task.taskId
INNER JOIN issue ON issue.issueId = task_issue.issueId
INNER JOIN milestone ON milestone.mileStoneId = project_milestone.mileStoneId
INNER JOIN help_source On help_source.sourceId = project_source.sourceId
INNER JOIN project ON project.projectId = project_creation.projectId
WHERE project.projectId = 59;
is there some error in my logic? and if yes what is it? or is it deleting without me knowing?
Questions you may ask:
Did i try searching stack overflow?
ANS: yes i did but can't seem to find an answer that fits this weird situation
so there is no error?
ANS: no there is no errors when i run the query
try to look on that topic :
How to Delete using INNER JOIN with SQL Server?
As far as I could see you need to specify aliases for each table.
So task, issue... are aliases but cannot see any of then after inner-join table name
(true, same names as tables but maybe alias are required)
Eg: INNER JOIN task task ON...
(now task is an alias, so you delete from table task)
Didn't check it, but if is to be work that should be the fix.

How to combine UPDATE query with subquery?

In my Mysql database I want to update a field fup for all records which I found using this select statement:
SELECT ic.hash
FROM incompany as ic, app
WHERE ic.id = app.ic_id;
So I created the following combined query:
UPDATE incompany
SET fup = 'x'
WHERE hash IN (SELECT ic.hash
FROM incompany as ic, app
WHERE ic.id = app.ic_id);
But this query gives me the following error:
You can't specify target table 'incompany' for update in FROM clause
Does anybody know how I can make this work? All tips are welcome!
You seem to want a condition on two columns, so this is a bit tricky. If I follow the logic correctly:
UPDATE incompany ic JOIN
(SELECT DISTINCT ic.hash
FROM incompany ic JOIN
app
ON ic.id = app.ic_id
) ica
ON ica.hash = ic.hash
SET fup = 'x' ;
You do not need a subquery. You might use INNER JOIN to set the criteria to link the incompany table to the app table and to the another alias for incompany table.
UPDATE incompany I
INNER JOIN app A ON I.id = A.ic_id
INNER JOIN incompany I2 ON I.hash = I2.hash
SET I.fup = 'x'

Need mysql query to pull data from two tables

So after helpful feedback from my original question, I now have this query:
SELECT sessions.id, sessions.title, sessions.abstract, sessions.presenters, sessions.proposal_id, proposals.outcomes, proposals.CategorySelection, proposals.research3, proposals.research4, proposals.research5, proposals.research6, proposals.innovation3, proposals.innovation4, proposals.innovation5,proposals.innovation6, proposals.application3, proposals.application4, proposals.application5, proposals.application6, proposals.integration3, proposals.integration4, proposals.integration5, proposals.integration6, proposals.references, proposals.organization
FROM sessions, proposals
INNER JOIN proposals ON proposals.id = sessions.proposal_id
WHERE sessions.id = '$id
LIMIT 1;)
that is getting me nowhere fast. What am I doing wrong?
Original question:
I need to pull several fields from one table and several more from a second table. The criteria is that a field called proposal_id match the id field of the second table. I am fairly new so this is what I have so far. It is not working, but not sure how to make it work.
(SELECT `title`,`abstract`,`presenters`,`proposal_id` FROM `sessions` WHERE `id`='$id')
UNION
(SELECT `outcomes`,`CategorySelection`,`research3`,`research4`,`research5`,`research6`,`innovation3`,`innovation4`,`innovation5`,
`innovation6`,`application3`,`application4`,`application5`,`application6`,`integration3`,`integration4`,`integration5`,`integration6`,`references`,`organization` FROM `proposals` WHERE `id`= `sessions`.`proposal_id`)
LIMIT 1;
You need to use JOIN not UNION
select
s.*,p.*
from `sessions` s
inner join `proposals` p on p.id = s.proposal_id
where s.id = '$id'
This is how you can join both the tables using the common key between.
You can select the specific fields instead of .* by specifying the column names as
s.col1,s.col2,p.col1,p.col2
etc
Try to use JOINS, where you can match the related fields from both the tables , this is the most convenient way to fetch records from multiple tables
UNION is used when you want to combine two queries
select a.id,b.some_field from table1 as a
INNER JOIN table2 as b ON b.prospal_id = a.id

Getting Repeated values in SQL

I was desperately trying harder and harder to get this thing done but didn`t yet succeed. I am getting repeated values when i run this query.
select
tbl_ShipmentStatus.ShipmentID
,Tbl_Contract.ContractID,
Tbl_Contract.KeyWinCountNumber,
Tbl_Item.ItemName,
Tbl_CountryFrom.CountryFromName,
Tbl_CountryTo.CountryToName,
Tbl_Brand.BrandName,
Tbl_Count.CountName,
Tbl_Seller.SellerName,
Tbl_Buyer.BuyerName,
Tbl_Contract.ContractNumber,
Tbl_Contract.ContractDate,
tbl_CountDetail.TotalQty,
tbl_CostUnit.CostUnitName,
tbl_Comission.Payment,
tbl_Port.PortName,
Tbl_Contract.Vans,
tbl_Comission.ComissionPay,
tbl_Comission.ComissionRcv,
tbl_CountDetail.UnitPrice,
tbl_Comission.ComissionRemarks,
tbl_CountDetail.Amount,
tbl_LCStatus.LCNumber,
tbl_ShipmentStatus.InvoiceNumber,
tbl_ShipmentStatus.InvoiceDate,
tbl_ShipmentStatus.BLNumber,
tbl_ShipmentStatus.BLDate,
tbl_ShipmentStatus.VesselName,
tbl_ShipmentStatus.DueDate
from tbl_ShipmentStatus
inner join tbl_LCStatus
on
tbl_LCStatus.LCID = tbl_ShipmentStatus.LCStatusID
inner join Tbl_Contract
on
tbl_LCStatus.ContractID = Tbl_Contract.ContractID
inner join Tbl_CountDetail
on Tbl_Contract.ContractID = Tbl_CountDetail.ContractId
inner join tbl_Comission
on
tbl_Comission.ContractID = Tbl_Contract.ContractID
inner join Tbl_Item
on
Tbl_Item.ItemID = Tbl_Contract.ItemID
inner join Tbl_Brand
on Tbl_Brand.BrandID = Tbl_Contract.BrandID
inner join Tbl_Buyer
on Tbl_Buyer.BuyerID = Tbl_Contract.BuyerID
inner join Tbl_Seller
on Tbl_Seller.SellerID = Tbl_Contract.SellerID
inner join Tbl_CountryFrom
on Tbl_CountryFrom.CountryFromID = Tbl_Contract.CountryFromID
inner join Tbl_CountryTo
on
Tbl_CountryTo.CountryToID = Tbl_Contract.CountryToID
inner join Tbl_Count
on
Tbl_Count.CountID = Tbl_CountDetail.CountId
inner join tbl_CostUnit
on tbl_Comission.CostUnitID = tbl_CostUnit.CostUnitID
inner join tbl_Port
on tbl_Port.PortID = tbl_Comission.PortID
where tbl_LCStatus.isDeleted = 0
and tbl_ShipmentStatus.isDeleted =0
and tbl_LCStatus.isDeleted = 0
and Tbl_CountDetail.isDeleted = 0
and Tbl_Contract.isDeleted = 0
and tbl_ShipmentStatus.LCStatusID = 5
I have also attached a picture of my result set of rows.
Any suggestions why this is happening would really be appreciable.
Result Set
Typically this happens when you have an implicit partial cross join (Cartesian product) between two of your tables. That's what it looks like to me here.
This happens most often when you have a many-to-many relationship. For example, if a single Album allows both multiple Artists and multiple Songs and the only relationship between Artists and Songs is Album, then there's essentially a many-to-many relationship between Artists and Songs. If you select from all three tables at once you're going to implicitly cross join Artists and Songs, and this may not be what you want.
Looking at your query, I see many-to-many between Tbl_CountDetail and tbl_Comission through Tbl_Contract. Try eliminating one of those joins to test to see if the behavior disappears.
Try using the DISTINCT keyword. It should solve your issue
Select DISTINCT ....
Wait as far as I can see your records are not duplicates.
HOWEVER
Notice the CountName column and Shipment ID column
The combination is unique for every row. Hence the values are unique as far as I can see. Try not selecting CountName.
Well if you have distinct rows its not a duplication problem. The issue is during the join a combination is occurring you don't want it to duplicating the results.
Either don't select CountName or you have a mistake in your data.
Only one of those rows should be true either 6 with Count2 or 6 with Count1. Likewise for 7. The fact that your getting both when your not supposed to indicates a logic mistake

UPDATE affecting less rows than equivalent SELECT

The following query returns 2303 rows:
SELECT a.*
FROM cur_analises a
INNER JOIN cur_materias_subsidiarias ms
ON ms.materia_id = a.materia_id
AND ms.subsidiaria_id IN(SELECT id FROM cur_subsidiarias WHERE cliente_id = 134)
INNER JOIN cur_materias m
ON m.id = a.materia_id
INNER JOIN cur_clientes c
ON c.carga_id = ms.subsidiaria_id
WHERE a.cliente_id = 134;
I need to update the cliente_id field of all those 2303 rows from table cur_analises with the value from cur_clientes.id. However, when I try to turn that SELECT query into the following UPDATE, it only affects 2297 rows, according to MySQL Workbench:
UPDATE cur_analises a
INNER JOIN cur_materias_subsidiarias ms
ON ms.materia_id = a.materia_id
AND ms.subsidiaria_id IN(SELECT id FROM cur_subsidiarias WHERE cliente_id = 134)
INNER JOIN cur_materias m
ON m.id = a.materia_id
INNER JOIN cur_clientes c
ON c.carga_id = ms.subsidiaria_id
SET a.cliente_id = c.id
WHERE a.cliente_id = 134;
I have no idea why it's missing 6 rows. What am I doing wrong?
You are probably not joining on a unique value or set of values at some point in the query causing denormalization of your result set. Then when you do the update it only updates the rows that actually meet the criteria of the joins for the table aliased as a. Only you can know what are truly non denormalizing joins in your query and fix them.
We had a similar case, the issue was with mysql partitioning. Once we revert partitioning everything is ok again.