简体   繁体   中英

Query to find one to many relationship between two tables and two columns (exclude anything one to one)

New to this forum, and new to SQL. I'm trying to clean up some data and pull out the errors. I have two tables, which both share the columns FILENAME, TYPE, SEC, I would like to pull out any records from both tables where there is a one to many relationship between SEC and TYPE, anything with a SEC and TYPE where only a one to one relationship can be ignored and is considered valid.

For Example, I have in table1.

FILENAME TYPE SEC

a----------------x----1

b----------------x----2

c----------------y----1

d----------------y----3

in table2 i would have something similar,

FILENAME TYPE SEC

e----------------x----1 

f----------------x----2

g----------------z----1

h----------------y----3

so i would like a query that would find

FILENAME TYPE SEC

a----------------x----1

c----------------y----1

e----------------x----1

g----------------z----1

My database is very large and any help would be much appreciated!

Thanks.

select t1.sec, t1.type, count(*) from table1 as t1 
join table2 as t2 on t1.sec = t2.sec and t1.type = t2.type
group by t1.sec, t1.type
having count(*) > 1

EDIT: That's not quite what you asked, that will show which ones have multiple records but they will be grouped.

You need to find the values of sec that have more than one type . The following query does this and it should work on any database:

select t.*
from ((select t1.*
       from t1
      ) union all
      (select t2.*
       from t2
      )
     ) t join
     (select sec
      from ((select t1.*
             from t1
            ) union all
            (select t2.*
             from t2
            )
           ) t
      group by sec
      having count(distinct type) > 1
     ) s
     on t.sec = s.sec

There may be more efficient ways of doing the query, depending on the database.

select 'table1' which, t.*
from (
    select sec, min(type) typea, max(type) typeb
    from table1
    group by sec
    having min(type) <> max(type)
) x
join table1 t on t.sec = x.sec
UNION ALL
select 'table2', t.*
from (
    select sec, min(type) typea, max(type) typeb
    from table1
    group by sec
    having min(type) <> max(type)
) x
join table2 t on t.sec = x.sec

The 2nd one just duplicates the first, combined using UNION ALL

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM