1

我有两张表,一张是“电话号码”表,另一张是“通话”表。呼叫表有两列感兴趣:始发号码列 (c.orig) 和终止号码列 (c.term)。

我正在尝试编写一个 MySQL 查询,它将返回调用表中的所有记录,其中c.orig编号或 c.term 编号都不存在于 numbers 表中(numbers 表中的“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 至少具有可在数字表中找到的两个数字(原始或术语)之一。

呼叫 ID 4 和 5 是两个电话号码都不在号码表中的情况。这些是我试图找到的记录。在号码表中未找到任何电话号码的记录。

4

3 回答 3

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

问题,我删除了您的组子句,因为我没有看到任何聚合函数。你还想做什么?

更新 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

SQLFiddle 演示

Hpe 这是有道理的。

于 2012-09-08T01:34:01.007 回答
0

您应该记住,从逻辑上讲,您的ON子句中的条件适用于每一,而不是其中的很多行,因此您不能真正让任何一个n.num等于两者 c.origc.term,当然,除非这两个是相同的数字(在您的特定情况下没有意义)。

所以,你真正需要检查的是是否n.num等于 。也就是说,只需替换为即可:c.origc.termANDOR

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
于 2012-09-08T15:10:14.027 回答
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
   );

注意:我省略了与实际问题无关的周期条件和限制。

顺便说一句:“日期”是 SQL 中的保留字。最好不要将其用作列名。

于 2012-09-08T15:26:54.963 回答