I have two tables, one is a "phone number" table and the other is a "calls" table. The calls table has two columns of interest: the originating number column (c.orig) and the terminating number column (c.term).
I'm trying to write a MySQL query that will return all records in the call table where NEITHER the c.orig number or the c.term number exist in the numbers table (the "n.num" column in the numbers table).
Here is my SQL query:
SELECT
c.id, c.date, c.orig, c.term, c.duration
FROM calls as c
LEFT JOIN numbers as n ON (n.num = c.orig AND n.num = c.term)
WHERE
c.period = '2012-08' AND
n.num IS NULL
GROUP BY c.call_id
ORDER BY c.call_id
LIMIT 0,300
Any ideas?
Here is some further clarification:
------------------------------
table: numbers
nid num
1 111-222-3333
2 222-333-4444
3 333-444-5555
------------------------------
------------------------------
table: calls
id orig term
1 333-444-5555 999-999-9999
2 999-999-9999 111-222-3333
3 222-333-4444 999-999-9999
4 888-888-8888 999-999-9999
5 777-777-7777 999-999-9999
------------------------------
Call IDs 1, 2, and 3 have at least one of the two numbers (orig or term) that can be found in the numbers table.
Call IDs 4 and 5 are situations where neither of the two phone numbers are not in the numbers table. Those are the records that I'm trying to find. Records where neither phone number is found in the numbers table.
You should
Join
table
twice
for this,
SELECT c.id, c.date, c.orig, c.term, c.duration FROM calls as c LEFT JOIN numbers as n ON (n.num = c.orig) LEFT JOIN numbers m ON m.num = c.term WHERE c.period = 'date here' AND m.num IS NULL -- GROUP BY c.call_id ORDER BY c.call_id LIMIT 0,300
question, i removed your group clause cause i don't see any aggregated function.
What else do you want to do?
UPDATE 1
based on your examples above, try this edited one.
Call IDs 4 and 5 are situations where neither of the two phone numbers are not in the numbers table . Those are the records that I'm trying to find. Records where neither phone number is found in the numbers
SELECT a.*
FROM calls a
LEFT JOIN numbers b
ON a.orig = b.num
LEFT JOIN numbers c
ON a.term = c.num
WHERE b.num IS NULL AND
c.num IS NULL
Hpe this makes sense.
You should keep in mind that, logically, the condition in your ON
clause is applied to every single row, not to the lot of them, so you can't really have any single n.num
be equal to both c.orig
and c.term
, unless, of course, the two are the same number (which in your particular case would make no sense).
So, what you actually need to be checking there is whether n.num
is equal to either c.orig
or c.term
. That is, just replace AND
with OR
and you are done:
SELECT
c.id, c.date, c.orig, c.term, c.duration
FROM calls as c
LEFT JOIN numbers as n ON (n.num = c.orig n.num = c.term)
WHERE
c.period = '2012-08' AND
n.num IS NULL
GROUP BY c.call_id
ORDER BY c.call_id
LIMIT 0,300
The question already uses the word EXIST. Well, this is axactly why EXISTS exists:
SELECT c.id, c.date, c.orig, c.term, c.duration
FROM calls c
WHERE NOT EXISTS ( SELECT *
FROM numbers a
WHERE a.num = c.orig
)
AND NOT EXISTS ( SELECT *
FROM numbers b
WHERE b.num = c.term
);
The two subqueries could even be combined into one:
SELECT c.id, c.date, c.orig, c.term, c.duration
FROM calls c
WHERE NOT EXISTS ( SELECT *
FROM numbers ab
WHERE ab.num = c.orig
OR ab.num = c.term
);
NOTE: I omitted the period-condition and the LIMIT, which are both irrelevant to the actual problem.
BTW: "date" is a reserved word in SQL. Better not use it as a column name.
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.