2017-10-27 3 views
1

以下のクエリが動作していますが、それがどのように必要なのかはわかりません。複数の列を1つの条件にグループ化する

このクエリはCSRの電話データを取得し、現在15のエージェントのデータを取得しています。現在のクエリは必要な合計を取得しますが、それらをすべて追加して合計を1行にします。私はそれが各CSRの合計を示すようにしたいと思います。この問題は、発信元テーブルの各コールレコードが発信番号または着信番号の4桁の内線番号を持つことです。ただし、各レコードには、そのユーザーの内線番号をコールに結び付ける1つのフィールドはありません。発信番号または着信番号として存在する必要があります。

私はロジックが正しく機能していると思いますが、今は拡張機能をグループ化する必要があります。したがって、15のCSRでは、ステートメントがそれぞれ15個の行を返すようにしたいと思います。各行にはそれぞれ独自の合計があります。しかし、グループ化する普遍的なフィールドはないので、私は両方のフィールドでグループ化する必要があると思う。

つまり、「callingpartynoには7200があり、finallycalledpartynoには7200があり、これを拡張子7200の合計としてグループ化する」と言います。ここで

は、データがソース表にどのように見えるかの例です:

callingpartyno | finallycalledpartyno 
    ------------------------------------- 
    1234    outside 
    1234    outside 
    1234    outside 
    outsidecall   1234   
    outsidecall   1234   
    outsidecall   1234   
    9876    outside 
    9876    outside 
    9876    outside 
    outsidecall   9876   
    outsidecall   9876     
    outsidecall   9876     

あなたが見ることができるように、何も同じCSRに各レコードを識別しません。ここ

とクエリです:

SELECT 

     sum(Duration) AS total_talk_time_seconds 
     , round(sum(Duration)/60,2) AS total_talk_time_minutes 
     , sum(if(LEGTYPE1 = 1,1,0)) AS total_outbound 
     , sum(if(LEGTYPE1 = 2,1,0) and ANSWERED = 1) AS total_inbound 
     , sum(if(LEGTYPE1 = 2,1,0) and ANSWERED = 0) AS total_missed 
     , SUM(IF(LEGTYPE1 = 1, 1, 0)) +     -- outbound calls 
     SUM(IF(LEGTYPE1 = 2, 1, 0)) AS total_calls 
     , NOW() AS time_of_report 
     , curdate() AS date_of_report 
FROM cdrdb.session a 
    INNER JOIN cdrdb.callsummary b 
     ON a.NOTABLECALLID = b.NOTABLECALLID 
    where date(b.ts) = '2017-10-16 00:00:00' 
    AND callingpartyno IN (7276,7314, 7295, 7306,7357,7200,7218,7247 7331,7255,7330,7000,7215, 7240,7358,7312) 
    OR finallycalledpartyno IN (7276,7314, 7295, 7306,7357,7200,7218,7247 7331,7255,7330,7000,7215, 7240,7358,7312) 

だから、もう一度、クエリはこれらの拡張機能のいずれかがcallingpartynoかfinallycalledpartynoのいずれかであるが、私はグループ化する方法を必要とする指定された日、のレコードを引っ張って動作しますそれらの2つで、それぞれのレコードを4桁の内線番号(ユーザーIDとほぼ同じ)として扱います。

+0

"GROUP BY:GROUP BY callingpartyno + finallycalledpartyno'の"ダーティ "トリックです。サンプルデータによると、2つのフィールドのうちの1つが「0」に変換されます。数字が常に数字ではない場合、これは機能しません。 –

答えて

1

これはまさにgroup byの句です。 caseステートメントを挿入することで、独自の条件を使用してIDを作成できます。

select 
    case 
    when callingpartyno  in (7276,7314,7295,7306,7357,7200,7218,7247,7331,7255,7330,7000,7215,7240,7358,7312) 
     then callingpartyno 
    when finallycalledpartyno in (7276,7314,7295,7306,7357,7200,7218,7247,7331,7255,7330,7000,7215,7240,7358,7312) 
     then finallycalledpartyno 
    end as id 
    , sum(duration) as total_talk_time_seconds 
    , round(sum(duration)/60,2) as total_talk_time_minutes 
    , sum(if(legtype1 = 1,1,0)) as total_outbound 
    , sum(if(legtype1 = 2,1,0) and answered = 1) as total_inbound 
    , sum(if(legtype1 = 2,1,0) and answered = 0) as total_missed 
    , sum(if(legtype1 = 1, 1, 0)) +     -- outbound calls 
    sum(if(legtype1 = 2, 1, 0)) as total_calls 
    , now() as time_of_report 
    , curdate() as date_of_report 
from 
    cdrdb.session a 
    join cdrdb.callsummary b 
    on a.notablecallid = b.notablecallid 
where 
    date(b.ts) = '2017-10-16 00:00:00' 
    and (
    callingpartyno   in (7276,7314,7295,7306,7357,7200,7218,7247,7331,7255,7330,7000,7215,7240,7358,7312) 
    or finallycalledpartyno in (7276,7314,7295,7306,7357,7200,7218,7247,7331,7255,7330,7000,7215,7240,7358,7312) 
) 
group by 
    id -- <-- the calculated field we created in the select clause 

私はまた、あなたのor文を修正しました。カッコの外側でそれを使用すると、日付は多かれ少なかれ無関係になりました。

+0

MySQLでは、GROUP BY句でカラムエイリアスを使用することができます。長い式の式をコピーして貼り付ける必要はありません。 –

+0

@PaulSpiegel:更新 – Jacobm001

1

私がお勧めします:

SELECT sum(Duration) AS total_talk_time_seconds, 
     round(sum(Duration)/60, 2) AS total_talk_time_minutes, 
     sum(LEGTYPE1 = 1) AS total_outbound, 
     sum(LEGTYPE1 = 2 and ANSWERED = 1) AS total_inbound, 
     sum(LEGTYPE1 = 2 and ANSWERED = 0) AS total_missed, 
     SUM(LEGTYPE1 in (1, 2)) AS total_calls, 
     NOW() AS time_of_report, 
     curdate() AS date_of_report 
FROM cdrdb.session s INNER JOIN 
    cdrdb.callsummary cs 
     ON s.NOTABLECALLID = cs.NOTABLECALLID 
where date(b.ts) = '2017-10-16' and 
     (callingpartyno IN (7276, 7314, 7295, 7306, 7357, 7200,7218,7247, 7331, 7255, 7330, 7000, 7215, 7240,7358,7312) or 
     finallycalledpartyno IN (7276,7314, 7295, 7306,7357,7200, 7218,7247, 7331, 7255, 7330, 7000, 7215, 7240, 7358, 7312) 
    ) 
group by (case when callingpartyno IN (7276, 7314, 7295, 7306,7357, 7200, 7218, 7247, 7331,7255,7330,7000,7215, 7240,7358,7312) 
       then callingpartyno else finallycalledpartyno 
      end); 

あなたの本当の問題はwhere句のロジックの周りの括弧です。

  • if()削除:

    はまた、私は次の変更を行いました。 MySQL拡張を使用する場合は、ブール値を整数として扱う拡張を使用してください。

  • 連鎖比較の代わりにinを使用してください。
  • 文字列リテラルに日付の時間成分を含める必要はありません。
+0

これはロジックではるかに優れた仕事ですが、各呼び出しの4桁の内線番号を1人のユーザーの内線番号として扱うのではなく、すべての合計の1行を返します。だから、私は15行、各エクステンションの合計で1つをリストする必要があります –

関連する問題