Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Tại sao MYSQL DB trả về một giá trị bị hỏng khi lấy giá trị trung bình trên các mô hình Django.DateTimeField?

Q1:Tại sao cơ sở dữ liệu không trả về giá trị hợp lệ cho giá trị trung bình của hai ngày này?

Đ: Giá trị trả về được mong đợi, đó là hành vi MySQL được xác định rõ.

Hướng dẫn tham khảo MySQL: https:// dev .mysql.com / doc / refman / 5.5 / vi / date-and-time-styles.html

Trong MySQL, AVG hàm tổng hợp hoạt động trên số giá trị.

Trong MySQL, DATE hoặc DATETIME biểu thức có thể được đánh giá bằng số bối cảnh.

Như một minh chứng đơn giản, thực hiện một số hoạt động bổ sung vào DATETIME chuyển đổi ngầm giá trị datetime thành một số. Truy vấn này:

  SELECT NOW(), NOW()+0

trả về một kết quả như:

  NOW()                                NOW()+0  
  -------------------  -----------------------
  2015-06-23 17:57:48    20150623175748.000000

Lưu ý rằng giá trị được trả về cho biểu thức NOW()+0 không một DATETIME , đó là một số .

Khi bạn chỉ định một SUM() hoặc AVG() hoạt động vào DATETIME , điều đó tương đương với việc chuyển đổi DATETIME thành một số, rồi tính tổng trung bình của số đó.

Đó là, trả về từ biểu thức này AVG(mydatetimecol) tương đương với trả về từ biểu thức này:AVG(mydatetimecol+0)

Những gì đang được "tính trung bình" là một giá trị số. Và bạn đã quan sát thấy, giá trị trả về không phải là ngày giờ hợp lệ; và ngay cả trong trường hợp nó trông giống như một ngày giờ hợp lệ, nó có thể không phải là một giá trị mà bạn sẽ coi là "trung bình" thực sự.

Câu hỏi 2:Làm cách nào để lấy giá trị trung bình thực tế của trường này nếu cách được mô tả không thành công?

A2: Một cách để làm điều đó là chuyển đổi ngày giờ thành một giá trị số có thể được tính trung bình "chính xác" và sau đó chuyển đổi lại thành ngày giờ.

Ví dụ:bạn có thể chuyển đổi ngày giờ thành một giá trị số đại diện cho một số giây từ một số thời điểm cố định, ví dụ:

  TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date)

Sau đó, bạn có thể "tính trung bình" các giá trị đó, để có được số giây trung bình từ một thời điểm cố định. (LƯU Ý:hãy cẩn thận khi thêm một số lượng cực lớn các hàng, với các giá trị cực lớn và vượt quá giới hạn (giá trị số tối đa), các vấn đề về tràn số.)

  AVG(TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date))

Để chuyển đổi giá trị đó trở lại ngày giờ, hãy thêm giá trị đó dưới dạng số giây trở lại một điểm cố định trong thời gian:

  '2015-01-01' + INTERVAL AVG(TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date)) SECOND

(Lưu ý rằng DATEIME giá trị được đánh giá trong múi giờ của phiên MySQL; vì vậy có những trường hợp phức tạp trong đó cài đặt của time_zone trong phiên MySQL sẽ có một số ảnh hưởng đến giá trị được trả về.)

MySQL cũng cung cấp một UNIX_TIMESTAMP() hàm trả về giá trị số nguyên kiểu unix, số giây kể từ đầu kỷ nguyên (nửa đêm ngày 1 tháng 1 năm 1970 UTC). Bạn có thể sử dụng điều đó để thực hiện cùng một hoạt động ngắn gọn hơn:

  FROM_UNIXTIME(AVG(UNIX_TIMESTAMP(t.my_date)))

Lưu ý rằng biểu thức cuối cùng này thực sự đang làm điều tương tự ... chuyển đổi giá trị ngày giờ thành một số giây kể từ '1970-01-01 00:00:00' UTC, lấy giá trị trung bình bằng số và sau đó cộng giá trị trung bình đó số giây trở lại '1970-01-01' UTC và cuối cùng chuyển đổi trở lại DATETIME giá trị, được thể hiện trong phiên hiện tại time_zone .

Q3:Có phải Django DateTimeField không được thiết lập để xử lý tính trung bình không?

Đ: Rõ ràng, các tác giả của Django hài lòng với giá trị được trả về từ cơ sở dữ liệu cho biểu thức SQL AVG(datetime) .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nhận điểm đa giác mysql

  2. Mã hóa mật khẩu và tạo muối Crypt (), được thực thi tốt?

  3. Câu lệnh MYSQL IN

  4. Tổng MySQL dựa trên giá trị col

  5. Không thể kết nối với máy chủ MySQL trên (ip hoặc tên miền)