mysql how to update table with same subquery in where clause - mysql

Following is my query, I am trying to update recods but I get an error:
you can't specify target table for update in from clause
UPDATE user_payment_info
SET
ammount='110',
status='failed',
transaction_id='0'
WHERE
id=(SELECT id
FROM user_payment_info
WHERE cust_id='771'
ORDER BY id DESC
LIMIT 1)
how can update record with getting id from same table
how can i resolve these mysql error
you can't specify target table for update in from clause
can some body help me to do these.

Try this instead:
UPDATE user_payment_info AS t1
INNER JOIN
(
SELECT MAX(id) AS MaxId
FROM user_payment_info
WHERE cust_id='771'
) AS t2 ON t1.id = t2.MaxId
SET t1.ammount='110',
t1.status='failed',
t1.transaction_id='0';

You don't have to use a subquery, you could use an UPDATE query with order by and LIMIT 1:
UPDATE
user_payment_info
SET
ammount='110',
status='failed',
transaction_id='0'
WHERE
cust_id='771'
ORDER BY
id DESC
LIMIT 1

Related

Using `limit` with an update sql query

I have the following query where I want to limit the number of rows it updates for the subs table. It keeps hitting an error though, where am I going wrong?
UPDATE subs t1
INNER JOIN imp_subscriptionlog t2
ON t1.subscription_id = t2.subscription_id
SET t1.cancellation_date = t2.date
WHERE t2.event = 'subscription_cancelled'
LIMIT 35
This is the error:
Incorrect usage of UPDATE and LIMIT
Error code 1221.
LIMIT is allowed in single-table updates only, as explained in the documentation:
For the single-table syntax, [...] if the ORDER BY clause is specified, the rows are updated in the order that is specified. The LIMIT clause places a limit on the number of rows that can be updated.
For multiple-table syntax, ORDER BY and LIMIT cannot be used.
You can rewrite the query to use a correlated subquery instead of a join:
update subs
set cancellation_date = (
select t2.date
from imp_subscriptionlog t2
where t2.subscription_id = subs.subscription_id and t2.event = 'subscription_cancelled'
)
order by ???
limit 35
Notes:
you should be specifying an order by clause in the query, otherwise it is undefined which rows will actually be updated
the query implicitly assumes that there is always just one matching row in imp_subscriptionlog for each row in subs; if that's not the case, then you must order by and limit 1 in the subquery as well, or use aggregation
we can also ensure that there is a match before updating by adding a where clause to the query
Here is a "safer" version of the query, that updates to the maximum date value available in the other table, while not modifying rows that have no match:
update subs
set cancellation_date = (
select max(t2.date)
from imp_subscriptionlog t2
where t2.subscription_id = subs.subscription_id and t2.event = 'subscription_cancelled'
)
where exists (
select 1
from imp_subscriptionlog t2
where t2.subscription_id = subs.subscription_id and t2.event = 'subscription_cancelled'
)
order by ???
limit 35
Update sub1
Inner join
(
//your select statement another table
//condition
//Now use limit
Limit 10
)
On
sub.data = table.date
set

How to delete duplicate rows in MySQL table?

I am using the following query, which I saw from another stackoverflow question but I am getting error.
delete from mytable
where myid not in (
select max(myid)
from mytable
group by myid2)
Error:
#1093 - Table 'mytable' is specified twice, both as a target for 'DELETE' and as a separate source for data
Edit 2:
I also tried this query:
delete from mytable
where myid in (
SELECT
myid, COUNT(*)
FROM
mytable
GROUP BY
myid2
HAVING
COUNT(*) > 1)
And got this error:
#1241 - Operand should contain 1 column(s)
In MySQL, you need to use a JOIN for this purpose. I assume you mean something like this:
delete t
from mytable t left join
(select max(myid) as myid
from mytable
group by myid2
) tt
on t.myid = tt.myid
where tt.myid is null;
Where ? is whatever you really want to group by. Your version will not delete anything because the group by and max() use the same column.

How to update a column for a range of row numbers?

I need to update the column "myColumn" in "myTable" for rows 5 to 10. I thought I can do the following but apparently it's giving me a syntax error:
UPDATE myTable SET myColumn = 'mamal' LIMIT 5,10;
Thanks
SQL tables represent unordered sets. If you have a primary key, you can use that for the ordering.
MySQL does allow limit, but not offset, so you could update the first five rows:
UPDATE myTable
SET myColumn = 'mamal'
ORDER BY id
LIMIT 5;
But not with an offset.
You could get around this with a JOIN:
UPDATE mytable t JOIN
(SELECT id
FROM mytable tt
ORDER BY id
LIMIT 5, 10
) tt
ON tt.id = t.id
SET myColumn = 'mamal';
You can select and update column value based on primarykey of your table.
if you want to change rows limit means you can change limit values.
in below code id Is nothing but Primay Key of your table
UPDATE myTable SET myColumn='mamal' WHERE id IN ( SELECT id FROM ( SELECT id FROM myTable where id ORDER BY id ASC LIMIT 5,5 ) tmp )
TRY by using subquery and join as below and please replace the join column in <column> with real one
UPDATE myTable mt
INNER JOIN (SELECT <column> FROm myTable LIMIT 5,10) t ON t.<column> = mt.<column>
SET mt.myColumn = 'mamal'
Try this:
update myTable
set myColumn = 'mamal'
where your_primary_key
in (select * from (select your_primary_key from myTable limit 5,5) as t);
MySQL does support offset in a limit clause, but only for SELECT. So the correct syntax is: LIMIT offset,row_count. In this case it should be limit 5,5, not limit 5,10. Check: Select Syntax.
You can also use LIMIT in UPDATE, but you can only specify the row_count in this case. Check: Update Syntax.
If you don't have a primary key, just use any unique key.
For why you need a select * from here, it's just a trick to bypass the error discribed here.
I ran into the same problem and saw the answers but after researching I found that you can use "BETWEEN" to UPDATE the Table.
UPDATE myTable
SET myColumn = "mamal"
WHERE id BETWEEN 5 AND 10;

Delete a row with condition on the same table in mysql

I have to delete a row with max(id) from a table in MySQL.
I am using query::
DELETE
FROM master
WHERE id=(
SELECT MAX(id)
FROM master)
but getting error No. 1093.
Can anybody please help me??
You can't specify target table for update in FROM clause.
you can delete the last row as mentioned below.
DELETE FROM master ORDER BY id DESC LIMIT 1
You cant modify the same table from which you are selecting the data in subquery.
Try this -
DELETE m.*
FROM master m
WHERE id IN (SELECT id_temp from(
SELECT MAX(id) as id_temp
FROM master) x)
You can't specify target table for Delete in FROM clause
Try this
DELETE FROM master
WHERE id IN (SELECT A.MAXid FROM
(SELECT MAX(id) as MAXid FROM master) A
)
DELETE FROM Test WHERE id IN(SELECT MAX(id) FROM Test);
This seems to be cross SQL vendor friendly. The LIMIT option in MySQL becomes this in SQL SERVER.
DELETE FROM Test WHERE id IN(SELECT TOP 1 id FROM Test ORDER BY id DESC );
See here

Single update last row entry for a set of IDs - MySQL

I want to execute an update for a set of Ids in a history table using IN(1,2,3). There is, of course, more than one entry for the same id in the table. For each id, the update should only be performed in the last history entry.
Is there a way to perform this with a single update?
UPDATE table SET fk_something = 123 WHERE id_something IN (1,2,3) AND ...?
Thanks in advance.
If you have a column to determine what the last date is, then you can use an UPDATE with a subquery similar to this:
update yourtable t1
inner join
(
select max(updated_at) MaxDate, id_something
from yourtable
group by id_something
) t2
on t1.id_something = t2.id_something
and t1.updated_at = t2.MaxDate
set t1.fk_something = 123
where t1.id_something IN (1,2,3)
See SQL Fiddle with Demo.
This uses a subquery to get the max(updated_at) value for each id_something. These rows are then joined to your table to make sure that you update the latest row.
Yes:
UPDATE yourtable
SET fk_something = 123
WHERE id_something=1
ORDER BY datecreated DESC
LIMIT 0,1
;
UPDATE yourtable
SET fk_something = 123
WHERE id_something=2
ORDER BY datecreated DESC
LIMIT 0,1
;
...
Just wrap it up in a procedure to simplify. (note you'll need to use prepare/execute if you're passing a CSV list as an argument)