Reputation: 7788
CUSTOMER
customer_id | email1 | email2 | phone1 | phone2
REGISTRATION
registration_id | email3 | ip
REGISTRATION_TO_CUSTOMER
registration_id | customer_id | email4
BANNED
banned_id | ip | email | phone
DATA SAMPLE:
CUSTOMER
1 | [email protected] | [email protected] | 1 | 11|
2 | [email protected] | [email protected] | 2 | 1 |
3 | [email protected] | [email protected] | 3 | 33|
REGISTRATION
1 | [email protected] | 192.168.1.1
2 | [email protected] | 192.168.1.3
3 | [email protected] | 192.168.1.3
REGISTRATION_TO_CUSTOMER
1 | 1 | [email protected]
2 | 2 | [email protected]
3 | 3 | [email protected]
BANNED
1 | 192.168.1.3 | null | null
3 | null | [email protected] | null
Explanation:
BANNED has 2 records, but I have 3 customers
Query to match banned and customer will return 2 customers with ID#2 and ID#3 because they have matching data in Banned table.
So I tried this (and it returns no results whatsoever):
SELECT DISTINCT customer_id,
email1,
email2,
email3,
email4,
phone1,
phone2,
ip
FROM (
SELECT *
FROM (
SELECT r.ip,
r.registration_id,
r.email3,
rc.email4,
c.customer_id,
c.email1,
c.email2,
c.phone1,
c.phone2
FROM (
SELECT registration_id,
email3,
ip
FROM REGISTRATION
) r
INNER JOIN (
SELECT registration_id,
customer_id,
email4
FROM REGISTRATION_TO_CUSTOMER
) rc
ON r.registration_id = rc.registration_id
INNER JOIN (
SELECT customer_id,
email1,
email2,
phone1,
phone2
FROM CUSTOMER
) c
ON rc.customer_id = c.customer_id
) start WITH (
email1,
email2,
email3,
email4,
phone1,
phone2,
ip
) IN (
SELECT DISTINCT CUST.email1,
CUST.email2,
CUST.email3,
CUST.email4,
CUST.phone1,
CUST.phone2,
CUST.ip
FROM (
SELECT r.ip,
r.registration_id,
r.email3,
rc.email4,
c.customer_id,
c.email1,
c.email2,
c.phone1,
c.phone2
FROM (
SELECT registration_id,
email3,
ip
FROM REGISTRATION
) r
INNER JOIN (
SELECT registration_id,
customer_id,
email4
FROM REGISTRATION_TO_CUSTOMER
) rc
ON r.registration_id = rc.registration_id
INNER JOIN (
SELECT customer_id,
email1,
email2,
phone1,
phone2
FROM CUSTOMER
) c
ON rc.customer_id = c.customer_id
) CUST
INNER JOIN BANNED
ON CUST.ip = BANNED.ip
OR CUST.email1 = BANNED.email
OR CUST.email2 = BANNED.email
OR CUST.email3 = BANNED.email
OR CUST.email4 = BANNED.email
OR CUST.phone1 = BANNED.phone
OR CUST.phone2 = BANNED.phone
) connect BY nocycle email1 = prior email1
OR email2 = prior email2
OR email3 = prior email3
OR email4 = prior email4
OR phone1 = prior phone1
OR phone2 = prior phone2
OR ip = prior ip
)
ORDER BY customer_id
Upvotes: 0
Views: 96
Reputation: 14858
This query looks promising:
select distinct id, ip, email, phone
from (
select id, ip, email, phone,
from customer start with
(ip, email, phone) in (
select distinct c.ip, c.email, c.phone
from customer c join banned b
on b.ip = c.ip or b.email = c.email or b.phone = c.phone)
connect by nocycle ip = prior ip or email = prior email or phone = prior phone)
order by id
Here is fiddle.
Edit: The modified query taking into account new tables, added in question: registration, registration_to_customer
and additional phones and emails.
with cust as (
select customer_id cid, registration_id rid, ip, phone1, phone2,
email1, email2, email3, email4
from registration r
join registration_to_customer rc using (registration_id)
join customer using (customer_id))
select distinct cid, rid, ip, phone1, phone2, email1, email2, email3, email4
from cust
start with (ip, phone1, phone2, email1, email2, email3, email4)
in (
select b.ip, phone1, phone2, email1, email2, email3, email4 from cust
join banned b on b.ip = cust.ip
or b.email in (cust.email1, cust.email2, cust.email3, cust.email4)
or b.phone in (cust.phone1, cust.phone2))
connect by nocycle
email1 in (prior email1, prior email2, prior email3, prior email4) or
email2 in (prior email1, prior email2, prior email3, prior email4) or
email3 in (prior email1, prior email2, prior email3, prior email4) or
email4 in (prior email1, prior email2, prior email3, prior email4) or
phone1 in (prior phone1, prior phone2) or
phone2 in (prior phone1, prior phone2) or
ip = prior ip
order by cid
Upvotes: 2