2011-01-20 41 views
12

Tôi có một bảng MySQL nơi đăng nhập nhân viên và thời gian đăng xuất được ghi lại. Ở đây trong cột trong-1 đại diện cho đăng nhập và 0-đại diện đăng xuất.Nhận tổng số giờ làm việc trong một ngày mysql

[id] [User_id]   [Date_time]     [in_out] 
    1  1   2011-01-20 09:30:03     1 
    2  1   2011-01-20 11:30:43     0 
    3  1   2011-01-20 11:45:12     1 
    4  1   2011-01-20 12:59:56     0 
    5  1   2011-01-20 13:33:11     1 
    6  1   2011-01-20 15:38:16     0 
    7  1   2011-01-20 15:46:23     1 
    8  1   2011-01-20 17:42:45     0 

Có thể truy xuất tổng số giờ làm việc trong một ngày bởi người dùng sử dụng truy vấn đơn không?

Tôi đã thử rất nhiều nhưng tất cả đều vô ích. Tôi có thể làm điều này trong PHP bằng cách sử dụng mảng nhưng không thể làm như vậy bằng cách sử dụng truy vấn duy nhất.

+1

Về mặt kỹ thuật, không phải lúc nào cũng có thể, nhưng nếu bạn đang tìm thời gian giữa thời gian và thời gian ra, đó là có thể! –

+0

@Alan: đúng vậy. – ash

+1

@Jasie: Tôi đã nói đùa về thời gian làm việc không bằng với sự khác biệt giữa thời gian đồng hồ và thời gian ra khỏi đồng hồ. –

Trả lời

4
SELECT `User_id`, time(sum(`Date_time`*(1-2*`in_out`))) 
    FROM `whatever_table` GROUP BY `User_id`; 

Thuật ngữ (1-2 * `in_out`) cung cấp cho mọi sự kiện đăng nhập là một yếu tố -1 và mỗi sự kiện đăng xuất là yếu tố +1. Hàm sum lấy tổng của cột Date_time và GROUP BY `User_id` làm cho tổng của mỗi người dùng khác nhau được tạo.

+0

Khi 'in_out' là 1, cụm từ này là (1-2 * 1) = - 1, làm cho trường' Date_time' cho hàng này âm. Khi 'in_out' là 0, thuật ngữ là (1-2 * 0) = 1 và hàng' Date_time' không bị thay đổi. Vì vậy, hàm 'sum' thấy giá trị dương cho mỗi lần đăng xuất và giá trị âm cho mỗi lần đăng nhập. Vì vậy, kết quả của 'sum' là mỗi sự kiện đăng xuất được trừ bởi mỗi sự kiện đăng nhập. Hàm thời gian xung quanh tổng được sử dụng để làm cho đầu ra rõ ràng hơn, vì kết quả của tổng là giá trị ngày-thời gian, một nơi nào đó gần năm tháng 1 năm thứ nhất 0. – Rudi

+0

đây là một giải pháp thực sự sáng tạo. Tôi thích nó. –

+0

Nó không hoạt động http://sqlfiddle.com/#!9/45870/1/0 –

0

này cung cấp cho một thử:

select [User_id], sum([Time_count])/3600 
from (
    select [User_id], 
     case when [in_out]=1 then UNIX_TIMESTAMP([Date_time]) 
       when [in_out]=0 then - UNIX_TIMESTAMP([Date_time]) 
       end as [Time_count] 
    from my_table 
) as a 
group by [User_id] 

Tôi không biết cú pháp MySQL vì vậy nếu ai đó tìm thấy lỗi, hãy sửa chữa chúng. Có thể không hoạt động. Ví dụ: nếu bạn có người dùng đăng nhập. Trong trường hợp đó, bạn chỉ có thể lọc những người dùng có cùng số lượng 1 và 0 trong trường [in_out].

4

Dòng suy nghĩ của Rudi là chính xác. Nếu bạn muốn số giờ có số thập phân, hãy sử dụng UNIX_TIMESTAMP() trên trường date_time, nếu không kiểu trả về sẽ là DATETIME (khó phân tích cú pháp). Đây là kết quả cho 4 dòng dữ liệu đầu tiên của bạn cộng thêm 2 dòng dữ liệu khác cho một ngày khác nhau:

SELECT 
    `user_id`, 
    DATE(`date_time`) AS `date`, 
    SUM(UNIX_TIMESTAMP(`date_time`)*(1-2*`in_out`))/3600 AS `hours_worked` 
FROM `test` 
GROUP BY date(`date_time`), `user_id`; 
+---------+------------+--------------+ 
| user_id | date  | hours_worked | 
+---------+------------+--------------+ 
|  1 | 2011-01-20 |  3.2567 | 
|  1 | 2011-01-21 |  3.0000 | 
+---------+------------+--------------+ 
+0

Bạn có thể thay thế "ngày (' date_time') "trong GROUP BY chỉ với" ngày "kể từ khi nó được xác định trong biểu thức SELECT đã có. – Clutch

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