我有两个表,一个是“电话号码”表,另一个是“电话”表。调用表有两列感兴趣的:原始数字列(c.orig)和终止数字列(c.term)。
我正在尝试编写一个MySQL查询,它将返回调用表中的所有记录,其中 NEITHER c.orig编号或c.term编号存在于数字表中(“n” .num“数字表中的列。”
这是我的SQL查询:
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
有什么想法吗?
以下是一些进一步的澄清:
------------------------------
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
------------------------------
呼叫ID 1,2和3至少有两个数字(orig或术语)中的一个可以在数字表中找到。
呼叫ID 4和5是这两个电话号码都不在号码表中的情况。那些是我想要找到的记录。记录数字表中没有找到电话号码的记录。
答案 0 :(得分:1)
你应 Join
表twice
,
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
问题,我删除了你的group子句因为我没有看到任何聚合函数。你还想做什么?
更新1
根据您的上述示例,尝试使用此编辑过的。
呼叫ID 4和5是这两个电话号码都不是的情况 不在数字表中。这些是我正在尝试的记录 找。记录数字中未找到电话号码的记录
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这是有道理的。
答案 1 :(得分:0)
您应该记住,从逻辑上讲,ON
子句中的条件适用于每个单个行,而不是适用于其中的很多行,因此您无法真正拥有任何单个n.num
等于 c.orig
和c.term
,除非两者是相同的数字(在您的特定情况下会不会义)。
因此,您实际需要检查的是n.num
是否等于 c.orig
或c.term
。也就是说,只需将AND
替换为OR
,您就完成了:
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 OR 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
答案 2 :(得分:0)
这个问题已经使用了EXIST这个词。嗯,这就是存在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
);
这两个子查询甚至可以组合成一个:
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
);
注意:我省略了期间条件和LIMIT,它们都与实际问题无关。
BTW:“date”是SQL中的保留字。最好不要将它用作列名。