2011-10-25 22 views
7

Tôi có bảng MySQL có cuộc gọi điện thoại. Mỗi hàng có nghĩa là một cuộc gọi điện thoại. Cột là:Dữ liệu MySQL - Đếm số cuộc gọi điện thoại cùng một lúc

start_time 
start_date 
duration 

Tôi cần nhận cuộc gọi điện thoại tối đa được gọi cùng một lúc. Đó là do kích thước trao đổi qua điện thoại.

Giải pháp của tôi là tạo hai cột dấu thời gian timestamp_starttimestamp_end. Sau đó, tôi chạy một vòng lặp thứ hai bằng giây, từng ngày và yêu cầu MySQL cái gì đó như:

SELECT Count(*) FROM tbl WHERE start_date IN (thisday, secondday) AND "this_second_checking" BETWEEN timestamp_start AND timestamp_end; 

Đó là khá chậm. Có giải pháp nào tốt hơn không? Cảm ơn bạn!

EDIT - Tôi sử dụng giải pháp này và nó mang lại cho tôi kết quả phù hợp. Có sử dụng lớp SQL dibi - http://dibiphp.com/cs/quick-start.

$starts = dibi::query("SELECT ts_start, ts_end FROM " . $tblname . " GROUP BY ts_start"); 
if(count($starts) > 0): 
    foreach ($starts as $row) { 
    if(isset($result)) unset($result); 
    $result = dibi::query('SELECT Count(*) FROM ' . $tblname . ' WHERE "'.$row->ts_start.'" BETWEEN ts_start AND ts_end'); 
    $num = $result->fetchSingle(); 
    if($total_max < $num): 
     $total_max = $num; 
    endif;  
    } 
endif; 
echo "Total MAX: " . $total_max; 
+0

bạn chỉ cần kiểm tra thời điểm cuộc gọi mới được bắt đầu cho số lượng cuộc gọi đang chạy, không cần kiểm tra từng giây – Blem

+0

Bạn có chỉ mục trên start_date, timestamp_start và timestamp_end không? – pgl

+0

Có, tôi có chỉ mục. Đó là một cải tiến lớn. Blem: Tôi nghĩ rằng nó hơn, cảm ơn! – Xdg

Trả lời

5

Thay vì chạy từng giây một, bạn nên cho mỗi hàng (phonecall) xem những cuộc gọi điện thoại khác đang hoạt động tại thời điểm đó. Sau đó bạn nhóm tất cả các kết quả theo ID của hàng và kiểm tra xem có số lượng tối đa nào không. Vì vậy, về cơ bản giống như sau:

SELECT MAX(calls.count) 
FROM (
    SELECT a.id, COUNT(*) AS count 
    FROM tbl AS a 
    INNER JOIN tbl AS b ON (
     (b.timestamp_start BETWEEN a.timestamp_start AND a.timestamp_end) 
     OR 
     (b.timestamp_end BETWEEN a.timestamp_start AND a.timestamp_end) 
    ) 
    GROUP BY a.id 
) AS calls 

Tạo chỉ mục trên cột dấu thời gian cũng sẽ giúp ích.

+0

Bạn nhanh hơn một chút rồi tôi :) +1 – Nemoden

+0

Điều này không cho tôi kết quả giống như thuật toán đầu tiên của tôi. Có lẽ tôi đã có một số lỗi trong chương trình của tôi. Tôi xem lại điều này trong 3 giờ tới. – Xdg

+0

Dấu thời gian bao gồm phần ngày, không chỉ là thời gian, phải không? Nếu không, họ nên, theo cách đó bạn không cần phải kiểm tra riêng các cột ngày _and_. –

-1

Làm thế nào về:

SELECT MAX(callCount) FROM (SELECT COUNT(duration) AS callCount, CONCAT(start_date,start_time) AS callTime FROM tbl GROUP BY callTime) 

Điều đó sẽ cung cấp cho bạn số lượng tối đa của cuộc gọi trong một "thời gian" duy nhất. Giả sử start_date và start_time là các chuỗi. Nếu chúng là số nguyên, bạn có thể tối ưu hóa nó một chút.

+0

'CONCAT (start_date, start_time) AS callTime TỪ Tbl GROUP BY callTime' -' Điều đó sẽ cho bạn số lượng cuộc gọi tối đa trong một "thời gian" đơn .' - Thật sao? o_O Ngày kết hợp và nhóm theo kết quả concat không có ý nghĩa với tôi vì mục đích giải quyết vấn đề này ... – Nemoden

+0

Nó sẽ nhóm tất cả các lần giống nhau, tuy nhiên tôi thấy điểm của bạn bây giờ - nó không làm thời gian chồng chéo, chỉ đồng thời bắt đầu lần. Xin lỗi. –

Các vấn đề liên quan