3

次のフィールドとインデックスを含むテーブルがあります。ここに画像の説明を入力
実行するクエリを作成する必要があります。

テーブルを確認してください。ダイヤルイベントがあり、その後 (同じ unique_id で)ブリッジまたはハングアップイベントが発生 しない場合

また

NewCallerIdイベントがあり、その後にHangupイベントがない場合 (同じ unique_id の場合) またはDialイベントがない場合 (call_id = 現在の unique_id の場合)

クエリが 1 つありましたが、うまくいきませんでした。また、ユーザーの回答も役に立ちませんでした。395 秒 (長すぎます) で作業を行うクエリを次に示します。

SELECT t1.* 
FROM   ASTERISK t1 
WHERE  EXISTS (SELECT t2.* 
               FROM   ASTERISK t2 
               WHERE  t1.OPERATOR_DIAL = '$extension' 
                      AND t1.EVENT = 'Dial' 
                      AND NOT EXISTS (SELECT t3.* 
                                      FROM   ASTERISK t3 
                                      WHERE  t3.UNIQUE_ID = t1.UNIQUE_ID 
                                             AND ( t3.EVENT = 'Hangup' 
                                                    OR t3.EVENT = 'Bridge' ))) 
        OR EXISTS (SELECT t4.* 
                   FROM   ASTERISK t4 
                   WHERE  t1.EVENT = 'NewCallerid' 
                          AND t1.OPERATOR_DIAL = '$extension' 
                          AND NOT EXISTS (SELECT t5.* 
                                          FROM   ASTERISK t5 
                                          WHERE  ( t5.UNIQUE_ID = t1.UNIQUE_ID 
                                                   AND t5.EVENT = 'Hangup' ) 
                                                  OR ( t5.CALL_ID = t1.UNIQUE_ID 
                                                       AND t5.EVENT = 'Dial' ))) 
ORDER  BY DATE DESC 
LIMIT  1 

JOINSで書き直そうとしましたが、#1248 - すべての派生テーブルには独自のエイリアスが必要です

これは、JOINクエリを使用した私の試みです:

SELECT t1.*
                    FROM asterisk t1
                    INNER JOIN (SELECT t2.* FROM asterisk t2
                                  WHERE
                                    t1.operator_dial = '$extension'
                                  AND t1.event = 'Dial'
                                  LEFT OUTER JOIN (SELECT t3.* FROM asterisk t3
                                                  WHERE t3.unique_id = t1.unique_id AND (t3.event = 'Hangup' OR t3.event = 'Bridge')))
                          OUTER JOIN (SELECT t4.* FROM asterisk t4
                                    WHERE t1.event = 'NewCallerid'
                                    AND t1.operator_dial = '$extension'
                                    LEFT OUTER JOIN (SELECT t5.* FROM asterisk t5
                                                    WHERE (t5.unique_id = t1.unique_id AND t5.event = 'Hangup') OR (t5.call_id = t1.unique_id AND t5.event = 'Dial')))
                    ORDER BY DATE DESC
                    LIMIT 1

クエリがどのように機能するかを示すために、2 つのスクリーンショットを作成しました (上部にはクエリ結果に含まれない呼び出しがいくつかあり、下部にはクエリ結果に含まれる必要がある 1 つの呼び出しがあります。画面

4

2 に答える 2

1

ここでスタック交換に投稿し始めたところです。深く掘り下げることなく、t2 と t4 の内部結合に t1 のどの値にも一致する値がないことに気付きました (元のクエリが非常に長い理由である可能性があります)。

古いクエリが削除されました.......

スクリーンショットをありがとう、それは役に立ちます。したがって、クエリに返してもらいたいのは、アクティブな通話 (「ハングアップ」または「ブリッジ」を持たない通話) であり、関連付けられたダイヤル イベントを持たない NewcallerID イベントと、前にブリッジがある最終ダイヤル イベントが必要ですが、彼らの後に橋はありません

SELECT * 
FROM Asterisk t1
WHERE t1.unique_id not in 
    (Select unique_id 
       from Asterisk t2
        Where event = 'Hangup', 'Bridge')
UNION
select *
from asterisk t3
Where event = 'NewCallerID'
    and t3.unique_id not in
      (Select unique_id 
       from Asterisk t4
        Where event = 'Dial')
UNION
Select distinct *
from asterisk t5
    inner join asterisk t6
        on t5.unique_ID = t6.Unique_id
            and t6.event = 'Dial'
Where t5.event = 'Bridge'
         and t6.id > t5.id

ここですべてのケースをカバーしたと思います。(少しハッキーなにおいがしますが)。編集:ダイヤル前およびダイヤル後にブリッジが存在するイベントはカバーされていません

于 2013-08-15T19:53:07.660 に答える
1

あなたはそれを複雑にしすぎたと思います。一意の ID を結合せずに t2 エイリアスに存在することにより、デカルトの結果が得られます。

クエリをインラインでコメントしたので、実行する前にそれらを削除してください。

SELECT 
      t1.*
   FROM   
      ASTERISK t1
         LEFT JOIN ASTERISK t2 
            ON t1.Unique_ID = t2.Unique_ID
            AND ( t2.Event = 'Hangup' 
               OR t2.Event = 'Bridge' )

         LEFT JOIN ASTERISK t3
            ON t1.unique_id = t3.unique_id
            AND t3.EVENT = 'Hangup'

         LEFT JOIN ASTERISK t4
            ON t1.unique_id = t4.call_id
            AND t4.EVENT = 'Dial'
   WHERE
      -- THESE ARE THE PRIMARY CONDITIONS YOU WANT...
      -- a specific operator extension and looking for
      -- either a dial or newcallerid
          t1.OPERATOR_DIAL = '$extension' 
      AND (    t1.EVENT = 'Dial' 
            OR t1.EVENT = 'NewCallerID' ) 

      AND (   
              -- if an outgoing DIAL, you are concerned with 
              -- alias t2 and NOT having any hangup or bridge
              (    t1.EVENT = 'Dial' 
               AND t2.Unique_ID IS NULL )
           OR 
              -- its from the NewCallerID record via t1 alias
              -- and you do not want hangup or dial based on 
              -- the unique ID vs Call ID respectively to the
              -- t3 and t4 aliases
              (    t1.EVENT = 'NewCallerID'
               AND t3.Unique_ID IS NULL
               AND t4.Unique_ID IS NULL )
          )
  ORDER BY 
     t1.`DATE` DESC 
  LIMIT  1 

NewCallerID サンプル データを除くサンプル データに基づく改訂...

これにより、少なくともアウトバウンドコールについては、持っているものが非常に簡素化されます。「NewCallerID」を示すデータがないため、より良いサンプルデータがなければ、その回答を適用できません。

とにかく、特定のオペレーター内線番号のすべての通話を事前にクエリするように変更し、各通話の一意の ID でグループ化された通話データ レコードからの見かけの自動インクリメント ID 列に基づいて、最初と最後のイベントを取得します。そこから、各テーブルに直接結合されるため、通話の開始方法と最後のアクティビティを確認できます。そこから、最後のイベントがまだ「newstate」設定にあるという単純な where 句です。保留中、電話会議などの他の設定がある場合は、これを NOT (ハングアップまたはブリッジ) 状態に調整する必要があります...

SELECT
      PerCallSummary.*,
      StartCall.event as BeginEvent,
      StartCall.id as BeginEventID,
      LastCall.event as EndEvent,
      LastCall.id as EndEventID
   from
      ( SELECT 
              t1.unique_id, 
              t1.id beginCall, 
              MAX(t2.id) as lastActivity
           from 
              asterisk t1
                 join asterisk t2
                   on t1.unique_id = t2.unique_id
           where 
                 t1.operator_dial = '$extension'
             and t1.event = 'Dial'
           group by
              t1.unique_id,
              t1.id ) as PerCallSummary
      JOIN Asterisk as StartCall
         ON PerCallSummary.beginCall = StartCall.id
      JOIN Asterisk as LastCall
         ON PerCallSummary.lastActivity = LastCall.id
   where
      LastCall.Event = 'Newstate'

内部 "PerCallSummary" クエリへの調整

これで解決すると思います...結果が得られなかったのは、operator_dial の値がすべてのレコードに引き継がれていないため、データを内容の簡単なものとして誤って解釈したためです。そのため、内部クエリはアスタリスク AGAIN に結合するように調整されていますが、呼び出しの unique_id のみで行われます (オペレーターのダイヤルは、入力されていないと失敗するため)。そのため、呼び出しは常に最初の t1 レコードで開始されるため、それを基礎として保持しましたが、今は t2 レコード ID の MAX() だけを持っています... これで、この操作を続行するための正しい結果が得られるはずです。

とにかく、「NewCallerID」がどのように見えるかを示すサンプル データを取得します。これを微調整して、それを含めることができます。これは終了基準です。

于 2013-08-16T03:05:41.187 に答える