1

2 つのテーブルがあります。1 つは「電話番号」テーブルで、もう 1 つは「通話」テーブルです。呼び出しテーブルには、対象となる 2 つの列があります。発信番号列 (c.orig) と着信番号列 (c.term) です。

c.orig 番号または c.term 番号のいずれも番号テーブル (番号テーブルの「n.num」列) に存在するcallテーブルのすべてのレコードを返す MySQL クエリを作成しようとしています。

これが私の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 には、番号テーブルにある 2 つの番号 (orig または term) の少なくとも 1 つがあります。

コール ID 4 と 5 は、2 つの電話番号のどちらも番号テーブルにない状況です。それらは私が見つけようとしている記録です。番号テーブルにどちらの電話番号も見つからないレコード。

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 は、2 つの電話番号のどちらも番号テーブルにない状況です。それらは私が見つけようとしている記録です。番号にどちらの電話番号も含まれていないレコード

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 デモ

これは理にかなっていますね。

于 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
   );

2 つのサブクエリを 1 つに結合することもできます。

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
   );

注: period-condition と LIMIT は省略しましたが、どちらも実際の問題には関係ありません。

ところで:「日付」は SQL の予約語です。列名として使用しない方がよいでしょう。

于 2012-09-08T15:26:54.963 に答える