2016-04-05 17 views
0

Temel olarak, ne yapmaya çalıştığım, SIP sinyaline dayalı çağrı süresini almaktır. aşağıda gösterildiği gibiTablodaki seçili kayıtlar için bir sütunda MySQL zaman ayarlayıcısı

Ben kayıtlarında bir tablo var ve şu döndüren bir SELECT deyimi yazmaya çalışıyorum:

id callid date     micro_ts   method duration1 duration2 
------------------------------------------------------------------------------------ 
25 123  2016-04-05 00:00:25  1459814425000320 BYE  00:00:04 3.999876 
46 234  2016-04-05 00:01:25  1459814485000000 BYE  00:00:04 4.000000 

kimliği belirli bir CallID için ilk BYE değil. Her bir çağrı için CallID her zaman aynıdır. 00:00:04 tarih ve 3.999876 arasındaki fark micro_ts arasındaki fark olmalıdır.

SQL, her callid için bir kayıt döndürmelidir. Buradaki zor kısım, aramanın başlatılmasını/durdurulduğunu gösteren mesajlar arasındaki farkı elde etmeye çalışıyorum.

o ya da "ilk BYE kadar = yöntemi sonra = Birinci yöntemde 183 200" göre süresini dönmek istiyorum "Birinci yöntemde = 200 yöntemi = 180 ve bir yöntem = 183 birinci BYE bulunana kadar sonra"

Bazı kriterler içeren bir tablo için istediğimi geri getirmek için bu kriterleri nasıl birleştirebilirim?

ben gibi SQL yazmaya çalışıyorlar:

select * from (
select id, callid, micro_ts, method, min(date) as StartTime, max(date) as EndTime, 
timediff(max(date), min(date)) as duration 
from (select t.*, 
      (select count(*) 
       from tableA t2 
       where t2.date <= t.date and 
        t2.method = 'BYE' 
      ) as grp 
     from tableA t 
    ) t where t.method = '200' 
group by callid, method 
order by 3 desc) z; 

Bu tüm çağrılar yalnızca bir kez ve daha sonra bir BYE 200 sahiptir varsayımı altında çalışır inanıyoruz.

id callid date     micro_ts   method 
--------------------------------------------------------------- 
1 123  2016-04-05 00:00:01  1459814401000025 INVITE 
2 123  2016-04-05 00:00:02  145981440200
3 123  2016-04-05 00:00:03  1459814403000941 INVITE 
4 123  2016-04-05 00:00:04  1459814404000392 INVITE 
5 123  2016-04-05 00:00:05  1459814405000539 INVITE 
6 123  2016-04-05 00:00:06  1459814406000101 404 
7 123  2016-04-05 00:00:07  1459814407000007 INVITE 
8 123  2016-04-05 00:00:08  1459814408000948 404 
9 123  2016-04-05 00:00:09  1459814409000784 100 
10 123  2016-04-05 00:00:10  1459814410000192 183 
11 123  2016-04-05 00:00:11  1459814411000482 183 
12 123  2016-04-05 00:00:12  1459814412000561 183 
13 123  2016-04-05 00:00:13  1459814413000392 183 
14 123  2016-04-05 00:00:14  1459814414000751 180 
15 123  2016-04-05 00:00:15  1459814415000012 180 
16 123  2016-04-05 00:00:16  1459814416000384 180 
17 123  2016-04-05 00:00:17  1459814417000498 180 
18 123  2016-04-05 00:00:18  1459814418000533 183 
19 123  2016-04-05 00:00:19  1459814419000841 183 
20 123  2016-04-05 00:00:20  1459814420000492 183 
21 123  2016-04-05 00:00:21  1459814421000444 200   * FIRST 200 after 183 
22 123  2016-04-05 00:00:22  1459814422000901 200   | 
23 123  2016-04-05 00:00:23  1459814423000294 ACK   | 
24 123  2016-04-05 00:00:24  1459814424000732 ACK   | 
25 123  2016-04-05 00:00:25  1459814425000320 BYE   * FIRST BYE 
26 123  2016-04-05 00:00:26  1459814426000020 BYE 
27 123  2016-04-05 00:00:27  1459814427000391 200 
28 123  2016-04-05 00:00:28  145981442800
29 234  2016-04-05 00:01:01  1459814461000000 INVITE 
30 234  2016-04-05 00:01:02  1459814462000000 407 
31 234  2016-04-05 00:01:03  1459814463000000 INVITE 
32 234  2016-04-05 00:01:04  1459814464000000 INVITE 
33 234  2016-04-05 00:01:05  1459814465000000 INVITE 
34 234  2016-04-05 00:01:06  1459814466000000 404 
35 234  2016-04-05 00:01:07  1459814467000000 INVITE 
36 234  2016-04-05 00:01:08  1459814468000000 404 
37 234  2016-04-05 00:01:09  1459814469000000 100 
38 234  2016-04-05 00:01:10  1459814470000000 183 
39 234  2016-04-05 00:01:11  1459814471000000 183 
40 234  2016-04-05 00:01:12  1459814472000000 183 
41 234  2016-04-05 00:01:13  1459814473000000 183 
42 234  2016-04-05 00:01:14  1459814474000000 180 
43 234  2016-04-05 00:01:15  1459814475000000 180 
44 234  2016-04-05 00:01:16  1459814476000000 180 
45 234  2016-04-05 00:01:17  1459814477000000 180 
46 234  2016-04-05 00:01:21  1459814481000000 200   * FIRST 200 after 180 whern no 183 is present 
47 234  2016-04-05 00:01:22  1459814482000000 200   | 
48 234  2016-04-05 00:01:23  1459814483000000 ACK   | 
49 234  2016-04-05 00:01:24  1459814484000000 ACK   | 
50 234  2016-04-05 00:01:25  1459814485000000 BYE   * FIRST BYE 
51 234  2016-04-05 00:01:26  1459814486000000 BYE 
52 234  2016-04-05 00:01:27  1459814487000000 200 
53 234  2016-04-05 00:01:28  1459814488000000 200 
+0

Sadece 1 200 aramayla ilgili varsayım üzerinde çalıştığınızı söylemiştiniz, ancak her iki yerde de 200'ü vurguladığınızda, aynı çağrı kimliğinin 200'ünde bir çizgi var. Bir dakika içinde aynı çağrı kimliği olmayacak gibi bir varsayım yaparsınız, ama bye cevabı <1 dakika içinde yapılacaktır? – BugFinder

+0

Hello @BugFinder - SQL örneğim bu varsayımı kullanıyor ancak bunun değişmesini istiyorum. Varsayım, bir çağrı cevaplandığında her bir CallID için sadece 200 görünecektir. Bu varsayım her zaman geçerli olmayacaktır. "İlk yöntem = 200 yöntemden sonra = 183 ilk BYE'ye kadar" veya "İlk yöntem = 200, yöntem = 180'den sonra ve ilk BYE'ye kadar hiçbir yöntem = 183 bulunamaz" durumuna göre dönmesini istiyorum. –

+0

Yeniden yazmama izin ver .. "200, 183'ten sonra 18 veya 183'ten sonra 180 olduğunda ve BYE'den önce, benzersiz CallID'ler için 200 ile BYE arasındaki süre ve" –

cevap

1

ben gitmek yaşadım ve VAKA ifadelerle bazı döküm sorunlar olabilir, ama bu size, orada yol en iyi şekilde olmalıdır:

SELECT id, 
     callid 
     start_date, 
     start_ms, 
     end_date, 
     end_ms, 
     end_date - start_date AS duration1, 
     end_ms - start_ms AS duration2 
FROM (
    SELECT 
      @same_call := @callid = callid, 
      @has_ended := @same_call AND (@has_ended OR @has_bye) AS has_ended, 
      @has_18x := (@has_18x AND @same_call) OR method IN ('180','183'), 
      @has_200 := (@has_200 AND @same_call) OR (@has_18x AND method = '200'), 
      @has_bye := (@has_bye AND @same_call) OR (@has_200 AND method = 'BYE') AS has_bye, 

      @start_date := CASE 
          WHEN @has_200 THEN COALESCE(@start_date, `date`) 
         END AS start_date, 
      @start_ms := CASE 
         WHEN @has_200 THEN COALESCE(@start_ms, micro_ts) 
         END AS start_ms, 
      @end_date := CASE 
         WHEN @has_bye THEN COALESCE(@end_date, `date`) 
         END AS end_date, 
      @end_ms := CASE 
         WHEN @has_bye THEN COALESCE(@end_ms, micro_ts) 
        END AS end_ms, 

      id, 
      @callid := callid AS callid   

    FROM sip_signal 

    JOIN (
     SELECT @callid := NULL, 
      @has_ended := FALSE, 
      @has_18x := FALSE, 
      @has_200 := FALSE, 
      @has_bye := FALSE, 
      @start_date := NULL, 
      @start_ms := NULL, 
      @end_date := NULL, 
      @end_ms := NULL     
     ) init 

ORDER BY callid, micro_ts 

    ) sip_call 
WHERE has_bye 
    AND NOT has_ended 

Eğer iç işleyişini görmek isterseniz sadece iç SELECT'i (+ JOIN ve ORDER BY) kendiniz çalıştırın.

+1

Bu bir çekicilik gibi çalışır - ve "time_date - start_date süresi1" i değiştirirseniz doğru zaman verir "tim_adı" ve @ has_200 ve _has_bye "micro_ts" için. Çok teşekkür ederim! –

+0

Ayrıca uzman olmayan bizim için güzel yazılmış ve anlaşılabilir olduğunu eklemek istiyorum. Saf altın. –

0

ben .. el mySQL yok bu yüzden, bu ciddi çöp olabilir ama kafamın içinde ben kaçmadan önce bunu yazmak istedim Whats bu - Dediğim gibi, bu dağınık

görünüyor
select callid, ,datediff(data,case when start1<=start2 then start1 else start2 end) as duration from 
    (select callid,call_from,call_to,min(starta) as start1,min(startb) as start2,min(data) from 
     (select callid,call_from,call_to, 
      count(case when method = 180 THEN date END) starta, 
      count(case when method = 183 THEN date END) startb, 
      count(case when method = 200 THEN date END) data, 
     from mydata) group by callid, call_from,call_to)) 

Bu yardımcı olur mu? bu size fikir veriyor mu?

İlgili konular