MySQL UPDATE with SELECT (mark "item" as read) - mysql

I have the following query which selects personal messages (PM) from "ac_pms" table. Additional info is fetching from other table - "ac_accounts" using LEFT JOIN. There is "pm_read" column in "ac_pms" table which define a PM is read or not. I need to set that field (pm_read) to "1" while selecting PMs.
SELECT p.*, a.seller_id, a.winner_id
FROM `ac_pms` AS p
LEFT JOIN `ac_accounts` AS a ON p.pm_for_lot = a.id
WHERE (p.pm_from=[user_id] OR p.pm_to=[user_id])
AND p.pm_for_lot=[account_id]
ORDER BY p.pm_date DESC;
I cannot imagine where to insert UPDATE expression to SET pm_read = 1.

You can't SELECT with UPDATE in the same SQL statement.
However, you can UPDATE with JOIN like this:
UPDATE ac_pms AS p
LEFT JOIN ac_accounts AS a ON p.pm_for_lot = a.id
SET p.pm_read = 1
WHERE (p.pm_from=[user_id] OR p.pm_to=[user_id])
AND p.pm_for_lot = [account_id];
Then you can make another SELECT after that.

Related

MySQL update with a subquery in safe update mode

I have the following database:
The following query calculates the total amount, that comes from multiplying the products prices and the respective quantity bought, from the orders that have the amount field equals to NULL:
SELECT SUM(i.qtde * p.preco_unitario) FROM Produtos p
INNER JOIN ItensPedido i ON i.id_produto = p.id_produto
INNER JOIN Pedidos pd ON pd.id_pedido = i.id_pedido
WHERE pd.vlr_total IS NULL
GROUP BY i.id_pedido);
I can update a row in the Pedidos table using the following query:
UPDATE Pedidos p
SET p.vlr_total = (SELECT SUM(i.qtde * p.preco_unitario) FROM Produtos p
INNER JOIN ItensPedido i ON i.id_produto = p.id_produto
WHERE i.id_pedido = 1
GROUP BY i.id_pedido)
WHERE p.id_pedido = 1;
But I have to re-run this query for each row that I want to update, changing the two WHERE clauses.
What I need help to is to build a query that updates all registries with NULL amount using a single query (if possible), similar to the second one. My attempt in using the first query as a subquery gives an 1093 error: using the same target table in update in the subquery.
You should be able to do that by changing this one line in your subquery this will set the subquery WHERE clause to match your records in the outer table.
WHERE i.id_pedido = 1
TO
WHERE i.id_pedido = p.id_pedido
Then you can remove the outer WHERE, unless you really want to just restrict it to p.id_pedido=1

INNER JOIN selects only one row from second table

I would like to get last value of the second table using mysql inner join.
This is my first table name 'tb_reg'
Second table 'tb_stud_qulification'
I want to get the last date of the 'candidate_no' where first table 'id' equqal to the second table 'candidate_no'.
I wrote inner join code like this but i'm getting error
SELECT reg.*, quli.course, quli.total_per
FROM tb_reg AS reg
INNER JOIN tb_stud_qulification AS quli ON reg.stage = '2' AND reg.id = quli.candidate_no AND
ORDER BY quli.id
LIMIT 1
I would like to get the result like this
you can show:
`http://stackoverflow.com/questions/8821920/sql-sqlite-select-with-inner-join`
example:
SELECT doctors.doctor_id,doctors.doctor_name,visits.patient_name
FROM doctors
INNER JOIN visits
ON doctors.doctor_id=visits.doctor_id
WHERE doctors.degree='MD';
I would write it like this (watch the different ON and WHERE clauses)
SELECT reg.*, quli.course, quli.total_per
FROM tb_reg AS reg
INNER JOIN tb_stud_qulification AS quli ON reg.id = quli.candidate_no
WHERE reg.stage = '2'
ORDER BY quli.id
LIMIT 1
but apart from that, I don't see a stage field in your tb_reg table...

UPDATE SET = SELECT FROM

I am trying to update table based on a select query using this:
UPDATE branches SET name =
(SELECT CONCAT(comp.name," ",bra.subsurb) as newname
FROM companies comp
RIGHT JOIN branches bra
ON comp.id = bra.company_id)
Which, according to this question, should work
but this produces an error: You can't specify target table 'branches' for update in FROM clause
Not sure what I am doing wrong.
EDIT:
Eventually this query did what I'm after:
UPDATE branches bra LEFT JOIN companies comp
ON comp.id = bra.company_id
SET bra.name = CONCAT(comp.name," ",bra.subsurb)
The error itself is pretty self explanatory, you are selecting from the table you are updating. Instead, you can use JOIN in the update statement. Try this:
UPDATE branches b
LEFT JOIN companies c ON c.id = b.company_id
SET b.name = CONCAT(c.name, " ", b.subsurb);
Note that because you're using a left join here to select all branches, regardless of whether or not they have a company, you may get null values for some names, so be careful about that.
In MySQL, you can't modify the same table which you use in the SELECT part.
This behaviour is documented at: http://dev.mysql.com/doc/refman/5.6/en/update.html
You will need to stop using the nested subquery and execute the operation in two parts, or alternatively use a simple where clause.
For more information please go through the following link
MySQL Error 1093 - Can't specify target table for update in FROM clause
The error you are getting is a restriction in MySQL.
To approach this problem, first write a SELECT statement that returns both the existing column value, and the new value you want to assign to the column:
e.g.
SELECT b.company_id
, b.name AS old_name
, CONCAT(c.name,' ',b.subsurb) AS new_name
FROM branches b
LEFT
JOIN companies c
ON c.id = b.company_id
NOTE: beware of NULL values returned for c.name (possible because of the outer join). CONCAT including a NULL may return NULL.
Once that is returning the rows you want to update, convert that to an UPDATE by replacing the SELECT ... FROM with the keyword UPDATE, and add a SET clause immediately before the WHERE clause:
UPDATE branches b
LEFT
JOIN companies c
ON c.id = b.company_id
SET b.name = CONCAT(c.name,' ',b.subsurb)

MySql dynamic select

Table Name: Look
FieldName: LookUp
example fieldname value : Country.CountryCode
While making a select inside table 'Look' I should dynamically split on value of the fieldname 'LookUp' and get the first value as Tablename and second value as Fieldname to do a dynamic select. I have the split function in place the problem is how to make it work in a case statement or maybe somebody has an alternative solution. currently i have this which is clearly not working
SELECT l.Id,
case when l.lookup is not null then
SELECT t.Id
FROM (SPLIT_STR(l.LOOKUP,'.',1)) AS t
WHERE t.(SPLIT_STR(l.LOOKUP,'.',2)) = l.attValue
LIMIT 1
END AS attValue
FROM look as l
Don't believe it is possible to pick up the table name from a field. Does suggest that there is an issue with your database design though.
Previous similar question:-
MYSQL query using variable as table name in LEFT JOIN
If there is a limited number of related tables / fields to join on and you know them all in advance then something like the following might do it:-
SELECT l.Id,
CASE
WHEN SPLIT_STR(l.LOOKUP,'.',1) = 'tableA' THEN tableA.Id
WHEN SPLIT_STR(l.LOOKUP,'.',1) = 'tableB' THEN tableB.Id
WHEN SPLIT_STR(l.LOOKUP,'.',1) = 'tableC' THEN tableC.Id
WHEN SPLIT_STR(l.LOOKUP,'.',1) = 'tableD' THEN tableD.Id
ELSE NULL
END AS SubId
FROM look as l
LEFT OUTER JOIN tableA ON tableA.ColA = l.attValue
LEFT OUTER JOIN tableB ON tableA.ColB = l.attValue
LEFT OUTER JOIN tableC ON tableA.ColC = l.attValue
LEFT OUTER JOIN tableD ON tableA.ColD = l.attValue
Ie, join against every possible sub table and use a CASE to return the field from the one you want.
But if you are reduced to doing this then I would suggest redesigning the database at the earliest opportunity.

MYSQL Update with 2 INNER JOINs hangs

I am trying to update a field in my table based on if it exists in two join tables.
update quotes
inner join collection_records ON quotes.id <> collection_records.record_id
inner join subcollection_records ON quotes.id <> subcollection_records.record_id
set quotes.status_id = 1
where collection_records.type = 'Quote'
or subcollection_records.type = 'Quote'
this query runs, but hangs. If I remove on inner join it works, but I need to check both join tables for the existance of the quote id.
Have to be careful, because using JOINs risks duplicated data for the sake of the unique supporting data. I re-wrote your query as:
UPDATE QUOTES
SET status_id = 1
WHERE id NOT IN (SELECT cr.record_id
FROM COLLECTION_RECORDS cr
WHERE cr.type = 'Quote')
AND id NOT IN (SELECT sr.record_id
FROM SUBCOLLECTION_RECORDS sr
WHERE sr.type = 'Quote')
Using LEFT JOIN/IS NULL:
UPDATE QUOTES
LEFT JOIN COLLECTION_RECORDS cr ON cr.record_id = id
AND cr.type = 'Quote'
LEFT JOIN SUBCOLLECTION_RECORDS sr ON sr.record_id = id
AND sr.type = 'Quote'
SET status_id = 1
WHERE cr.record_id IS NULL
AND sr.record_id IS NULL
My guess is that it's mainly due to the <> (NOT EQUALS) operator. Is that really what you're looking for here?
Also, if you have a Quote record in both the joinging tables....you will get 2 records back. Seems that taking one of the joins out returns only one record to you. Try doing a select instead of the update on a certain Quote that exists in both tables and see if you get two records back. You will have to modify the joins down in order to get one quote record returned.