Update value in one table with result from another - mysql

OK I have 2 tables:
holdings: (id, long_name, value, date, sedol)
asset_key: (id, long_name, sedol)
My issue is that in holdings there are many records where the sedol wasn't filled in. I have the asset_key table however that maps a given long_name to a sedol.
Is there a query that can populate holdings.sedol with the result from asset_key?
Something like:
UPDATE holdings SET holdings.sedol =
SELECT asset_key.sedol FROM asset_key
WHERE sedol.long_name = asset_key.long_name

This will do the trick:
UPDATE
holdings
LEFT JOIN asset_key ON sedol.long_name = asset_key.long_name
SET
holdings.sedol=asset_key.sedol

This should work:
UPDATE `holdings`
SET `holdings`.`sedol` = (SELECT `asset_key`.`sedol`
FROM `asset_key`
WHERE `asset_key`.`long_name` = `holdings`.`long_name`)
However, if I am not wrong, you should be sure that this SELECT subquery returns only one row or MySQL will throw an error.

Try the below Query:
update holdings
SET holdings.sedol = asset_key.sedol
from holdings
inner join asset_key on sedol.long_name = asset_key.long_name
Note: The inner join should result in single value only

Related

Mixed UPDATE SELECT query

I need to run an UPDATE query:
UPDATE products
SET fcategory = SELECT fcategory
FROM categories
WHERE categories.scategory = products.scategory
i.e. for the rows in "products" where column scategory = categories.scategory, products.fcategory must be updated to categories.fcategory
Example:
categories.scategory monkies, categories.category gorilla
products.scategory monkies
=> products.fcategory must be updated to gorilla since products.scategory = monkies = products.scategory
Anyone knows how to write such an UPDATE query?
Thanks.
Use a JOIN
UPDATE products AS p
JOIN categories AS c ON p.scategory = c.scategory
SET p.fcategory = c.scategory

How to copy 3 columns from one table into another in mysql

I have two tables and both include 2 columns, sureness and kindness and and they are related to each other by dataitemID and id. Just to show you the structure I will put 2 selects that I got from database:
SELECT ID,sureness,kindness FROM omid.tweet ;
SELECT ID,DataitemID,sureness,kindness FROM omid.entity_epoch_data ;
and I want to copy all value of sureness and kindness in omid.tweet into entity_epoch_data where entity_epoch_data.entityID is equal to entityID coming from entity_relation where tweet.ID =entity_relation.ID
I want just to do it in mysql rather than reading the whole table in java and updating the database in the loop but I am so confused. How can I do that?I appreciate any help:)
Update:
I wrote the code as follow but it does not work:
update tweet, entity_epoch_data
set entity_epoch_data.sureness= tweet.sureness,
entity_epoch_data.kindness = tweet.kindness ,
entity_epoch_data.calmness = tweet.calmness ,
entity_epoch_data.happiness = tweet.happiness
WHERE entity_epoch_data.EntityID in(
SELECT EntityID FROM omid.entity_dataitem_relation
INNER JOIN omid.tweet t ON entity_dataitem_relation.DataitemID = t.ID)
It's actually pretty straight forward. The UPDATE clause works like a JOIN and then use SET to set the values
UPDATE tweet INNER JOIN entity_epoch_data
ON tweet.id = entity_epoch_data.id
SET entity_epoch_data.sureness= tweet.sureness,
entity_epoch_data.kindness = tweet.kindness

Update using Select Statement

I wanna write a query like this :
UPDATE `test_credit`
SET `test_credit`.`credit`=(`test_credit`.`credit`-((`test_credit`.`credit`/100)*5))
WHERE `test_credit`.`name` = `users`.`uname`
in fact i want to get a query on users.uname = test_credit.name but mysql say it has error and realize users.uname as column
what is correct query ?
You need to explicitly join it with table users. As far from my understanding based on your query, you want to calculate the credit if the names exists on both tables.
Give this a try,
UPDATE test_credit a
INNER JOIN users b
ON a.name = b.uname
SET a.credit = (a.credit - ((a.credit/100) * 5.0))
-- WHERE b.parent= "example"

LEFT JOIN query returns multiple results

I have the query below which looks at a table of data in which each line has an ID, date/time and key action (as well as other data). This table cannot be changed and is out of my control.
The query finds an occurrence of the Create action (which is always the first) pulls the ID and Date/Time for Creation and then pulls the Date/Time of the other key actions (Add Info, Book Appt, Accept) in one row of data:
SELECT _create.ID AS ID,
_create.`datetime` AS Create,
_inform.`datetime` AS Add_Info,
_bookap.`datetime` AS Book_Appt,
_accept.`datetime` AS Accept,
FROM table AS _create
LEFT JOIN table AS _inform ON (_create.ID = _inform.ID AND _inform.action = 'Add Info')
LEFT JOIN table AS _bookap ON (_create.ID = _bookap.ID AND _bookap.action = 'Book Appt')
LEFT JOIN table AS _accept ON (_create.ID = _accept.ID AND _accept.action = 'Accept')
WHERE _create.action="Create"
So I get something like:
ID - Create Date - Inform Date - Bookap Date - Accept Date
1234 01/02/2013 02/02/2013 09/02/2013 10/02/2013
This works well.
However if the query finds 2 events of the same type ie 'Book Appt' for the same ID, which can happen sometimes, it pulls two lines of data for that ID. So I get:
ID - Create Date - Inform Date - Bookap Date - Accept Date
1234 01/02/2013 02/02/2013 09/02/2013 10/02/2013
1234 01/02/2013 02/02/2013 15/02/2013 10/02/2013
I need it to ignore the second occurence and only return one line per ID. Or, even better return a line showing Bookap Date1 and Bookap Date2.
Any ideas?
Use GROUP BY to group the records into one row, and min() to select the earliest event date.
SELECT _create.ID AS ID,
min(_create.`datetime`) AS Create,
min(_inform.`datetime`) AS Add_Info,
min(_bookap.`datetime`) AS Book_Appt,
min(_accept.`datetime`) AS Accept,
FROM table AS _create
LEFT JOIN table AS _inform ON (_create.ID = _inform.ID AND _inform.action = 'Add Info')
LEFT JOIN table AS _bookap ON (_create.ID = _bookap.ID AND _bookap.action = 'Book Appt')
LEFT JOIN table AS _accept ON (_create.ID = _accept.ID AND _accept.action = 'Accept')
WHERE _create.action="Create"
GROUP BY _create.ID;
A quick and dirty way to show all event dates but still return one row is to use the group_concat() function instead of min() in the query above. This would put multiple datetimes into single columns which your app layer would then need to parse.
Sure, use GROUP BY _create.ID after your WHERE clause.
If you want to return multiple Book_Appt values in a single row, you can use GROUP_CONCAT like this:
SELECT _create.ID AS ID,
_create.`datetime` AS Create,
_inform.`datetime` AS Add_Info,
GROUP_CONCAT(_bookap.`datetime`) AS Book_Appt,
_accept.`datetime` AS Accept,
FROM table AS _create
LEFT JOIN table AS _inform ON (_create.ID = _inform.ID AND _inform.action = 'Add Info')
LEFT JOIN table AS _bookap ON (_create.ID = _bookap.ID AND _bookap.action = 'Book Appt')
LEFT JOIN table AS _accept ON (_create.ID = _accept.ID AND _accept.action = 'Accept')
WHERE _create.action="Create"
GROUP BY `ID`
This would return a comma-seperated list of datetime values in your case.
So your output might look like
ID - Create Date - Inform Date - Bookap Date - Accept Date
1234 01/02/2013 02/02/2013 09/02/2013,15/02/2013 10/02/2013
For your first question (to return only one row) I would use an ORDER BY clause to sort your result set, followed by a LIMIT 1 expression to only return one row.

how to update one table using data from second table

I am bit stuck with this one.. what i want is update app_name (first table). It returns no error.. but does nothing...
UPDATE tbl_m_app AS tma, tbl_measure AS tm
SET tma.app_name='Ap1'
WHERE (tm.mesure_id = tma.mesure_id
AND tm.live = 1)
This query will do the same work in more obvious way and without joins
UPDATE tbl_m_app AS tma
SET tma.app_name='Ap1'
WHERE tma.mesure_id IN (SELECT tm.mesure_id FROM tbl_measure AS tm WHERE tm.live = 1)
I think this SQL is fine, it's just not matching any rows.
Check this by using a select with the same where clause:
SELECT * FROM tbl_measure tm WHERE tm.live=1;
0 rows returned, right?