I have a table with a dozen or so columns and no primary key defined for it. There are several million rows stored in it. Is there a SQL query I could use that would return the combination of columns that will give a unique key for the table? It is specifically an Oracle database.
-
1Do you not have any guesses as to what would be a good unique key? I would start there. As for how to tell, SELECT DISTINCT Col1, Col2, etc FROM table and compare the row counts to the raw table.– Jonathan FiteCommented Jul 29, 2016 at 16:49
-
1When I see a production table without a PK, I often find that the uniqueness of the PK has already been violated. A code-based solution may get you candidates for a unique column set, but the only way to really know what the proper purpose ( and PK ) of the table should be is to talk to people who use it and the application that fronts it.– Peter VandivierCommented Jul 30, 2016 at 4:26
1 Answer
First, it seems like the wrong way of approaching the problem. I would start by investigation what is supposed to be unique according to the business rules.
Nevertheless, you will have to investigate the power set of column combinations. The cardinality of the power set on n is 2^n, but the empty set can be ignored. So if you have 10 columns this means 2^10-1=1023 combinations to investigate. It's probably easiest to use a host language to generate the sql, but you can use group by cube to get the combinations. Assuming columns c1, c2, c3:
with t(a,b,c) as ( values ('c1','c2','c3') )
select a,b,c
from t group by cube (a,b,c)
A B C
-- -- --
- c2 c3
- - c3
- c2 -
- - -
c1 c2 -
c1 - -
c1 - c3
c1 c2 c3
Now you can generate the sql by looping over this result set:
select c2,c3 from t group by c2,c3 having count(1) > 1
if no rows exists the column combination is a candidate for a key. Just verify that no sub set of this combination is also a candidate.
-
The group by is definitely what I was looking for, thanks. The good news is that I have a hunch on which columns look unique, so I will start my search there. Commented Jul 29, 2016 at 18:25
-
Yes, the number of combinations grows exponentially, so it is beneficial if you can remove as many columns as possible from the set of suspects. Commented Jul 29, 2016 at 18:29
-
While this might work it doesn't (and can't) take future records into consideration. Even if you do find a unique combination of columns now, how can you tell if it will apply later? That's why I would (very strongly) suggest you look at the way the data should be identified in the problem domain, first. Figure out the data model based on the reality of the problem, don't try to shoehorn it the other way around. Commented Jul 30, 2016 at 11:33
-
@Juan Carlos Coto, while I agree that the domain should be analysed (as noted first in my answer), I also assume that the whole purpose is to add a unique constraint. Any row that violates this constraint will be rejected. Commented Jul 30, 2016 at 12:27
-
I'd probably start with comparing row count against count of distinct rows, just to see if there are dupes. If so, you may already be out of luck. Commented Jul 31, 2016 at 5:49