I have two tables contacts
and calllist
. contacts
has multiple columns containing phone numbers. calllist
has only one column from_number
containing phone numbers. I’m trying to get all phone numbers from the column from_number
which do not match the phone numbers in the table calllist
.
Here is my working but probably very inefficient and slow SQL query:
SELECT from_number AS phone_number, COUNT(from_number) AS number_of_calls
FROM calllist
WHERE from_number NOT IN (
SELECT businessPhone1
FROM contacts
WHERE businessPhone1 IS NOT NULL
)
AND from_number NOT IN (
SELECT businessPhone2
FROM contacts
WHERE businessPhone2 IS NOT NULL
)
AND from_number NOT IN (
SELECT homePhone1
FROM contacts
WHERE homePhone1 IS NOT NULL
)
AND from_number NOT IN (
SELECT homePhone2
FROM contacts
WHERE homePhone2 IS NOT NULL
)
AND from_number NOT IN (
SELECT mobilePhone
FROM contacts
WHERE mobilePhone IS NOT NULL
)
AND (received_at BETWEEN '$startDate' AND DATE_ADD('$endDate', INTERVAL 1 DAY))
GROUP BY phone_number
ORDER BY number_of_calls DESC
LIMIT 10
How do i rewrite this SQL query to be faster? Any help would be much appreciated.
2
Answers
try this
I don’t like the schema design. You have multiple columns holding ‘identical’ data — namely phone numbers. What if technology advances and you need a 6th phone number??
Instead, have a separate table of phone numbers, with linkage (id) to
JOIN
back tocalllist
. That gets rid of all the slowNOT IN ( SELECT... )
, avoids a messyUNION ALL
, etc.If you desire, the new table could have a 3rd column that says which type of phone it is.
The simplified query goes something like