Remove duplicate two way linked rows SQL - sql

I have two columns like the following and I want to delete the duplicates.
Column1 Column2
1 10
2 9
3 8
4 7
5 6
6 5
7 4
8 3
9 2
10 1
I want to delete half of these entries so that there are only 5 rows like this:
Column1 Column2
1 10
2 9
3 8
4 7
5 6
Any ideas? I know how I could do it in C# and remove if there are duplicates then delete but I want to do it in SQL. The values represent ID's and a relationship between the ID's. Order doesnt matter in the relationship so 1-10 is the same as 10-1. So in that way there are duplicate relationships.

One way would be as follows:
DELETE t FROM MyTable t
WHERE t.Column1 > t.Column2 AND EXISTS (
SELECT * FROM MyTable tt
WHERE t.Column1=tt.Column2 AND t.Column2=tt.Column1
)
The t.Column1 > t.Column2 says that if there is a pair of matching rows, delete the one where Column1 is greater than Column2.
Demo.

Related

Mapping columns in oracle-sql

Table:
column 1 column 2 column 3
2 two 3
5 five 8
3 three 10
8 eight 11
12 one 15
I want to create a new column column 4like below:
column 1 column 2 column 3 column 4
2 two 3 three
5 five 8 eight
3 three 10
8 eight 11
12 one 15
I want to map column 3 and column 1 and if there's a match column 4 takes values of column 2.
Example: Value 3 in column 3 is present in column 1, so column 4 will take corresponding column 3 value three.
Thanks!
This looks like a left join:
select t.*, tt.column2 as column4
from table1 t left join
table1 tt
on t.column3 = tt.column1;
EDIT:
If you want to set the value, you can use update:
update table1 t
set column4 = (select tt.column2 from table1 tt where t.column3 = tt.column1)
where exists (select 1 from table1 tt where t.column3 = tt.column1);
However, this seems silly. You can easily get the value in the table using an explicit join or hiding the logic in a view.

Output all duplicate rows (SQL Server)

I have a table which holds what I consider duplicate rows. the values in these records may not be exactly the same, but it’s been calculated that they’re possible duplicates by fuzzy logic. For example:
RecordCD key_in key_out
---------------------------
1 1 2
2 2 2
3 3 3
4 4 6
5 5 5
6 6 6
7 7 7
8 8 11
9 9 9
10 10 10
11 11 11
key_in column has a unique ID of the record.
key_out column has a possible duplicate if it’s not equal to key_in
I need my output to look like this and list all of the possible duplicates:
RecordCD key_in key_out
---------------------------
1 1 2
2 2 2
4 4 6
6 6 6
8 8 11
11 11 11
but I’m struggling to construct a query that would do that.
Thanks.
I think this is what you want:
select t.*
from t
where exists (select 1
from t t2
where t2.key_out = t.key_out and t2.key_in <> t.key_in
)
order by t.key_out;
Here is a db<>fiddle.
It seems like if there is a mismatch between key_in, key_out you want to pull all rows where key_in has either value`
I would create a temp table with all values in rows with mismatched key_in, key_out, call this value bad_match
If either of your key_in, key_out values match this value, include it in output
select mytable.* from mytable
where key_in in
(select key_in bad_match from mytable where key_in <> key_out
union all
select key_out from mytable where key_in <> key_out);
This sample builds your schema and returns the desired output

Querying duplicates table into related sets

We have a process that creates a table of duplicate records based on some arbitrary rules (details not relevant).
Every record gets checked against all other records and if a suspected duplicate is found both it and the duplicate are stored in a dupes table to be manually reviewed.
This results in a table something like this:
dupId, originalId, duplicateId
1 1 2
2 1 3
3 1 4
4 2 3
5 2 4
6 3 4
7 5 6
8 5 7
9 6 7
10 8 9
You can see here record #1 has 3 other records it is similar to (#2,#3 and #4) and they are each similar to each other.
Record #5 has 2 duplicates (#6 and #7) and record #8 has only 1 (#9).
I want to query the duplicates into sets, so my results would look something like this:
setId recordId
1 1
1 2
1 3
1 4
2 5
2 6
2 7
3 8
3 9
But I am too old/slow/tired/rubbish and a bit out of my depth here.
Currently, when checking for duplicates if the record pairing is already in the table we don't insert it twice (i.e. you don't see both sides of the duplicate pairing) but can easily do so if it makes the querying simpler.
Any advice much appreciated!
Duplicates seems to be transitive, so you have all pairs. That is, the "original" id has the information you need.
But it is not included in the duplicates and you want that. So:
select dense_rank() over (order by originalid) as setid, duplicateid
from ((select originalid, duplicateid
from t
where not exists (select 1 from t t2 where t.originalid = t2.duplicateid)
) union all
(select distinct originalid, originalid
from t
where not exists (select 1 from t t2 where t.originalid = t2.duplicateid)
)
) i
order by setid;

Using VBA ADO on Excel, I am looking for an Update query to get an univocal, 1 to 1 match

I have a table similar to the following (tab1):
ID Descr Related_ID
1 a 2
2 a 1
3 a 1
4 a 1
5 b 6
6 b 5
7 b 5
8 b 5
my query is something like:
Update [tab1] as T1 INNER JOIN [tab1] as t2
ON t1.[Descr] = t2.[Descr]
SET t1.[Related_ID] = t2.[ID]
WHERE t1.[ID] <> t1.[Related_ID]
the idea is to create couple/pair between the rows of the table to get for each line one on only one ID of another line.
What the query is actually doing is overwriting each time Related_ID, with the latter table2 ID.
Instead of just use any ID only once.
The result I would like is like:
ID Descr Related_ID
1 a 2
2 a 1
3 a 4
4 a 3
5 b 6
6 b 5
7 b 8
8 b 7
I would like to create a couple / pair of element where the related_id of one is the ID of the other and viceversa.
Could you help me please?
PS:
A. I am using vba adodb on excel not on access
B. I need to maintain a good degree of efficiency, if I would implement sub query such as WHERE not [ID] IN (SELECT [ID] FROM [tab2] WHERE ...)
the efficiency will be highly impacted (from few seconds to half an hour) as the table has hundreds of rows
thanks

Get rows with single values using SQlite

By using SQlite, I'd like to get all rows that show in a specific column only one single distinct value. Like from following table:
A B
1 2
2 1
3 2
4 3
5 1
6 1
7 2
8 4
9 2
Here I'd like to get only row Nr. 4 an 8 as there values (3 and 4) occur only once in the entire column.
You could use a query like this:
SELECT *
FROM mytable
WHERE B IN (SELECT B FROM mytable GROUP BY B HAVING COUNT(DISTINCT A)=1)
Please see fiddle here.
Subquery will return all B values that are present only once (you could also use HAVING COUNT(*)=1 in this case), the outer query will return all rows where B is returned by the subquery.