Get around self-referencing in a DELETE query - mysql

I'm trying to delete all records which aren't the latest version under their name but apparently you can't reference access a table you are modifying in the same query.
I tried this but it doesn't work for the reasons above:
DELETE FROM table
WHERE CONCAT(name, version ) NOT IN (
SELECT CONCAT( name, MAX( version ) )
FROM table
GROUP name
)
How can I get around this?
Cheers

Wrap the inner reference in a derived table.
DELETE FROM table
WHERE Concat(name, version) NOT IN (SELECT nv
FROM (SELECT Concat(name, Max(version))
AS nv
FROM table
GROUP BY name) AS derived)

delete t1
from table_name1 t1, table_name1 t2
where t1.version < t2.version
and t1.name = t2.name;
//creating alias is the need here

Related

MySQL: How to remove duplicate records or check for duplicate when insert?

I know there are many answers indicated using rank() or row_number(), however, they are not supported in SQL-FRONT or Navicat, I tried Microsoft SSMS but it didnot support my sql. I tried many methods, didn't work. So I'm hopeless now.
Table is shown below, I just want to know how to remove duplicate records with the same name and time. Thank you.
Use an EXISTS clause to find duplicates.
delete from mytable
where exists
(
select *
from mytable other
where other.name = mytable.name
and other.time = mytable.time
and other.id < mytable.id
);
As for inserts: Place a unique constraint on the two columns. This is usually done with a unique index:
create unique index idx_unique_name_time on mytable (name, time);
In MySQL, you can use join and aggregation:
delete t
from t join
(select name, time, min(id) as min_id
from t
group by name, time
) tt
on t.name = tt.name and t.time = tt.time and
t.id > tt.min_id;

Unsure how to frame SQL Query for the following task

I have the above mentioned tables in my database. I first receive a COURSE variable from my previous PHP page. I need to print the list of student names along with their student_Ids who haven't taken the course. For the tables above, if the variable I receive is A, then I need to print Jake along with his student_id. As Jake's student id 3, is not associaetd with Course A.
I tried following query, which doesn't seem to work and I'm unsure where I'm wrong
SELECT DISTINCT T1.name, T1.student_id
FROM Table 1 T1, Table 2 T2
WHERE T1.student_id = T2.student_id AND
T2.COURSE != :variable
ORDER BY T1.name ASC,
T1.student_id ASC
variable : A
I appreciate that this must seem very old-fashioned, but then again, so am I...
SELECT DISTINCT x.*
FROM t1 x
LEFT
JOIN t2 y
ON y.student_id = x.student_id
AND y.course = 'a'
WHERE y.student_id IS NULL;
There are lots of options. For instance, you could use a subquery:
SELECT name, student_id FROM t1 WHERE student_id NOT IN (SELECT student_id FROM t2 WHERE course='A')
You can use NOT EXISTS to find a list of students who have not taken the course:
SELECT * FROM T1
WHERE NOT EXISTS (
SELECT * FROM T2
WHERE T1.StudentId = T2.StudentId
AND T2.Course = :variable
)
ORDER BY name ASC, student_id

Deleting duplicates from a database using MySQL

I am working in MySQL trying to insert a bunch of entries into a table. There are many semi-duplicates that I need to get rid of. I want to delete all of the semi-duplicates except for one. When I run the code below, it seems to be deleting everything that I don't want to be deleted by keeping only entries that have multiple semi-duplicates. How can I delete all but one of the semi-duplicates while also keeping the entries of everything else?
delete from t where (ColA, ColB, ColC) in
(select * from (select ColA, ColB, ColC from t
group by ColA, ColB, ColC having count(*) > 1) as t);
Well, i don't think you can solve this without using a where
But you can not operate a SELECT WHERE on a DELETE using the same table
Exemple from my database
delete from tb_test where idtb_test not in (
select idtb_test from tb_test T1
WHERE T1.title in (select title from tb_test T2 group by T2.title having count(*) =1)
)
This query search for non-duplicates rows on col title and delete all the rows except the selected rows
Mysql Error :
Error Code: 1093. You can't specify target table 'tb_test' for update
in FROM clause
If I understand correctly, you want to delete almost all rows which have a duplicate, and you don't care which one remains undeleted.
Also, as I understand - this table has primary key.
In that case, it can be done with this query:
delete test_table t3
where t3.id in (
select t1.id
from test_table t1,
(
select col_a, col_b, col_c
from test_table
group by col_a, col_b, col_c
having count(*) > 1
) s1
where t1.col_a = s1.col_a
and t1.col_b = s1.col_b
and t1.col_c = s1.col_c
and t1.id != (
select min(t2.id)
from test_table t2
where t1.col_a = t2.col_a
and t1.col_b = t2.col_b
and t1.col_c = t2.col_c
group by col_a, col_b, col_c
)
)
Basically, this query deletes all row duplicates except for those with minimal ID, which is PK in my case.
PS: This works in Oracle DB, can't test in MySQL right now.

Delete duplicates in mySQL table

I am trying to write my first mySQL query. I need to delete rows if they have the same article-number field. I wrote this query:
SELECT
article_number, COUNT(*)
FROM
article_numbers
GROUP BY
article_number
HAVING
COUNT(*) > 1
It shows me all the rows that are duplicate. But how can I delete all but 1 for each duplicate?
Thanks
EDIT:
I tried this query:
delete article_numbers from article_numbers inner join
(select article_number
from article_numbers
group by article_number
having count(1) > 1) as duplicates
on (duplicates.article_number = article_numbers.article_number)
but it gives me this error:
Cannot delete or update a parent row: a foreign key constraint fails (api.products, CONSTRAINT products_article_number_id_foreign FOREIGN KEY (article_number_id) REFERENCES article_numbers (id))
EDIT 2:
I disabled the foreign key temporarily, and now my delete query works. But how can I modify it that one of the duplicate rows is not deleted?
Use a CROSS JOIN.
Query
delete t1
from article_numbers t1,
article_numbers t2
where t1.id > t2.id
and t1.article_number = t2.article_number;
Fiddle demo
I use a rather simple query to remove dupes:
;WITH DEDUPE AS (
SELECT ROW_NUMBER() OVER(
PARTITION BY article_number
ORDER BY (SELECT 1)) AS RN
FROM article_numbers)
DELETE FROM DEDUPE
WHERE RN != 1
Delete c
from (select *,rank() over(order by article_number) as r from article_numbers )c
where c.r!=1
Delete a row if same article_number but higher id exists:
delete from article_numbers t1
where exists (select 1 from article_numbers t2
where t2.article_number = t1.article_number
and t2.id > t1.id)
Core ANSI SQL, so I suppose it works with both MySQL and SQL Server.
I think this would help:
WITH tblTemp as
(
SELECT ROW_NUMBER() Over(PARTITION BY Name,Department ORDER BY Name)
As RowNumber,* FROM <table_name>
)
DELETE FROM tblTemp where RowNumber >1
I modified my query and I think it works now:
SET FOREIGN_KEY_CHECKS=0;
delete article_numbers from article_numbers inner join
(select min(id) minid, article_number
from article_numbers
group by article_number
having count(1) > 1) as duplicates
on (duplicates.article_number = article_numbers.article_number and duplicates.minid <> article_numbers.id)
But it seems very complex. I will check #Ullas method to see if it works, too.

Select Pairs in MySQL

Have a table where certain rows come in couples which have a matching GUID. Just wondering how to SELECT all data from the table but ONLY if the rows exist as a couple with a matching GUID.
You can use a query like this:
SELECT *
FROM yourtable
WHERE GUID IN (SELECT GUID FROM yourtable GROUP BY GUID HAVING COUNT(*)=2)
The subquery will return all GUIDs that appears exactly twice, the outer query will return all rows associated to those GUIDs.
Please see fiddle here.
Try something like this:
SELECT t1.*
FROM
table t1
, table t2
WHERE
t1.guid = t2.guid
AND t1.id <> t2.id
;
table: your table name
id: some field that you know is different for both rows
Try
SELECT t.*
FROM Table1 t JOIN
(
SELECT guid
FROM Table1
GROUP BY guid
HAVING COUNT(*) = 2
) q ON t.guid = q.guid
Here is SQLFiddle demo