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.
Related
how to delete duplicate rows in mysql version 5.7?
here's my code and im getting error
Error Code: 1241 Operand should contain 1 column(s)
How to fix please?
DELETE FROM table1 WHERE code AND cl_date IN (
SELECT code, cl_date FROM( SELECT
code, cl_date,
COUNT(cl_date)
FROM
table1) AS a
WHERE code = "code1" AND cl_date BETWEEN '2021-03-21' AND '2021-04-1'
GROUP BY cl_date
HAVING COUNT(cl_date) > 1)
ORDER BY cl_date ASC LIMIT 1;
According to my experience, it is not possible to have two columns with the "IN" operator. You can use the following command if you want to delete duplicate rows based on "code" and "cl_date" columns:
DELETE FROM table1 WHERE id Not IN (
SELECT
MIN(id)
FROM
table1
WHERE code = "code1" AND cl_date BETWEEN '2021-03-21' AND '2021-04-1'
GROUP BY cl_date
) and code = "code1"
This query keeps the first occurance of duplicate rows in the table by using "MIN(id)" and discards the others. The last row can be kept by using "MAX(id)" instead.
Here's code that works for me.
DELETE table1
FROM table1
INNER JOIN (
SELECT MAX(id) AS lastId, cl_date
FROM table1
WHERE code = "code1" AND closed BETWEEN '2021-03-01' AND '2021-04-30'
GROUP BY cl_date
HAVING COUNT(*) > 1) dup ON dup.cl_date = table1.cl_date
WHERE table1.id < dup.lastId
I'm trying to delete a lot of duplicate rows from a SQL table with businesses' codes and businesses' descriptions but I have to keep one for each entry, I have something like 1925 rows and I have 345 rows with duplicates and triple entries, this is the query I used to find duplicates and triple entries:
SELECT codice_ateco_2007, descrizione_ateco_2007, COUNT(*) AS CNT FROM codici_ateco_il_leone GROUP BY codice_ateco_2007, descrizione_ateco_2007 HAVING CNT > 1;
I tried the following but won't work, any of them, when I use CTE I get and error saying unknown function after WITH statement and when I use the other codes like
DELETE
FROM MyDuplicateTable
WHERE ID NOT IN
(
SELECT MAX(ID)
FROM MyDuplicateTable
GROUP BY DuplicateColumn1, DuplicateColumn2, DuplicateColumn3)
it won't work anyway it says I cannot select the table inside the in function.
Is CTE and the other code out of date or what?How can somebody fix this?By the way there also is id PRIMARY KEY in the codici_ateco_il_leone table.
One method is row_number() with a join:
delete mdt
from MyDuplicateTable mdt join
(select mdt2.*,
row_number() over (partition by DuplicateColumn1, DuplicateColumn2, DuplicateColumn3 order by id) as seqnum
from MyDuplicateTable mdt2
) mdt2
on mdt2.id = mdt.id
where seqnum > 1;
A similar approach uses aggregation:
delete mdt
from MyDuplicateTable mdt join
(select DuplicateColumn1, DuplicateColumn2, DuplicateColumn3, min(id) as min_id
from MyDuplicateTable mdt2
group by DuplicateColumn1, DuplicateColumn2, DuplicateColumn3
having count(*) > 1
) mdt2
using (DuplicateColumn1, DuplicateColumn2, DuplicateColumn3)
where mdt.id > mdt2.min_id;
Both of these assume that id is a global unique identifier for each row. That seems reasonable based on the context. However, both can be tweaked if the id can be duplicated for different values of the three key columns.
Your delete statement is fine and works in about every DBMS - except for MySQL where you get this stupid error. The solution to this is simple: replace from sometable with from (select * from sometable) somealias:
DELETE
FROM MyDuplicateTable
WHERE ID NOT IN
(
SELECT MAX(ID)
FROM (SELECT * FROM MyDuplicateTable) t
GROUP BY DuplicateColumn1, DuplicateColumn2, DuplicateColumn3
);
I am running this query on MySQL
SELECT ID FROM (
SELECT ID, msisdn
FROM (
SELECT * FROM TT2
)
);
and it is giving this error:
Every derived table must have its own alias.
What's causing this error?
Every derived table (AKA sub-query) must indeed have an alias. I.e. each query in brackets must be given an alias (AS whatever), which can the be used to refer to it in the rest of the outer query.
SELECT ID FROM (
SELECT ID, msisdn FROM (
SELECT * FROM TT2
) AS T
) AS T
In your case, of course, the entire query could be replaced with:
SELECT ID FROM TT2
I think it's asking you to do this:
SELECT ID
FROM (SELECT ID,
msisdn
FROM (SELECT * FROM TT2) as myalias
) as anotheralias;
But why would you write this query in the first place?
Here's a different example that can't be rewritten without aliases ( can't GROUP BY DISTINCT).
Imagine a table called purchases that records purchases made by customers at stores, i.e. it's a many to many table and the software needs to know which customers have made purchases at more than one store:
SELECT DISTINCT customer_id, SUM(1)
FROM ( SELECT DISTINCT customer_id, store_id FROM purchases)
GROUP BY customer_id HAVING 1 < SUM(1);
..will break with the error Every derived table must have its own alias. To fix:
SELECT DISTINCT customer_id, SUM(1)
FROM ( SELECT DISTINCT customer_id, store_id FROM purchases) AS custom
GROUP BY customer_id HAVING 1 < SUM(1);
( Note the AS custom alias).
I arrived here because I thought I should check in SO if there are adequate answers, after a syntax error that gave me this error, or if I could possibly post an answer myself.
OK, the answers here explain what this error is, so not much more to say, but nevertheless I will give my 2 cents, using my own words:
This error is caused by the fact that you basically generate a new table with your subquery for the FROM command.
That's what a derived table is, and as such, it needs to have an alias (actually a name reference to it).
Given the following hypothetical query:
SELECT id, key1
FROM (
SELECT t1.ID id, t2.key1 key1, t2.key2 key2, t2.key3 key3
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id = t2.id
WHERE t2.key3 = 'some-value'
) AS tt
At the end, the whole subquery inside the FROM command will produce the table that is aliased as tt and it will have the following columns id, key1, key2, key3.
Then, with the initial SELECT, we finally select the id and key1 from that generated table (tt).
I have seen very similar if not same questions on here but my trials of trying to convert following query into an UPDATE statement failed.
SELECT table.* FROM table JOIN (
SELECT column, COUNT(*) AS rank
FROM table
GROUP BY column
) AS t USING (column) WHERE t.rank = 1
ORDER BY t.rank DESC
I want to update column of all results selected using the query above.
How can I convert this into an update statement?
Thank you.
This should do it:
update table
set column = 'somevalue'
where id in
(select id from (
SELECT table.* FROM table JOIN (
SELECT column, COUNT(*) AS rank
FROM table
GROUP BY column
) AS t USING (column) WHERE t.rank = 1) x)
not entirely sure but i think it's something like
update tblname set columname = value where tblname.columncompare = (select statement)
INSERT INTO table (id, value)
SELECT table.id, table.value
FROM table
JOIN (
SELECT column, COUNT(*) AS rank
FROM table
GROUP BY column
) AS t USING (column)
WHERE t.rank = 1
ORDER BY t.rank DESC
ON DUPLICATE KEY UPDATE value = VALUES(value)
Insert on duplicate to the rescue!
Basicly this allows you to do any SELECT as normal and then you prepend INSERT INTO and append ON DUPLICATE.
I guess that this query is made up, but what's the point of filtering and ordering the same column?
I need to update a table, and the Where clause should contain the last (or max) from a certain column, so I made this query:
UPDATE Orders
SET Ordermethod='Pickup'
WHERE orderid IN (
SELECT MAX(orderid)
FROM Orders);
But, for some reason I don't understand, mysql returns this error:
1093 - You can't specify target table 'Bestellingen' for update in FROM clause
I tried different queries, which aren't working either...
Can someone help??
Sorry for the crappy english
This is a MySQL limitation. (As the documentation puts it: "Currently, you cannot update a table and select from the same table in a subquery.") You can work around the limitation by writing your subquery as (SELECT * FROM (SELECT ...) t), so that MySQL will create a temporary table for you:
UPDATE Orders
SET Ordermethod='Pickup'
WHERE orderid IN
( SELECT *
FROM ( SELECT MAX(orderid)
FROM Orders
) t
)
;
UPDATE Orders
SET Ordermethod='Pickup'
WHERE orderid IN( SELECT MAX(orderid) FROM
(
SELECT * FROM Orders
)
AS c1
)