Ý nghĩa của số ngày trong độ tuổi trung bình?


7

Tôi muốn biết độ tuổi trung bình của người dùng của mình và đã làm như sau để làm điều đó:

# SELECT avg(age(birthday)) FROM "user";
                   avg
------------------------------------------
 33 years 10 mons 32 days 08:33:10.577946

Số ngày có nghĩa là gì? Làm thế nào nó có thể được hơn 31 ngày?

Tôi có 3746 hồ sơ và tôi thuộc múi giờ UTC.

PS: Tôi đang sử dụng Postgres 9.5.3


Bạn có ở múi giờ cách đó hơn 9 giờ không? Đó là điều duy nhất tôi có thể nghĩ về điều đó khiến nó trở thành một vấn đề trình bày (lỗi).
Phil

2
Bạn có thể sử dụng justify_days()(hoặc justify_interval) để "bình thường hóa" khoảng thời gian
a_horse_with_no_name

1
Liệu SELECT age(avg(birthday)) FROM "user";cho kết quả tương tự?
ypercubeᵀᴹ

@ ypercubeᵀᴹ, tôi đã thử điều đó trước đây, nhưng avg(birthday) đưa ra "Không có chức năng nào khớp với tên và loại đối số đã cho."
n1r3

@a_horse_with_no_name đây là mẹo! Cảm ơn bạn. Bất kỳ manh mối tại sao đây không phải là hành vi mặc định nghĩ?
n1r3

Câu trả lời:


1

age()trả về khoảng thời gian. Trong SQL-92 "an Intervallà khoảng thời gian định hướng chưa được lưu trữ của dòng thời gian" [1]. Chúng có hai loại do độ dài tháng khác nhau trong lịch Gregorian (năm này sang tháng khác và ngày này sang ngày thứ hai). Oracle cung cấp cho bạn một thông báo lỗi, nếu bạn cố gắng làm những gì bạn đã làm . Khoảng có thể là tích cực và tiêu cực. Chúng cần được neo để có một ý nghĩa chính xác, như thế nào date + interval = date2. Nói chung, việc lấy trung bình của các giá trị này là không xác định rõ ràng và việc thử giá trị tuổi này vẫn có thể mang lại cho bạn kết quả không mong muốn (như vậy).

Vậy ý nghĩa của a 3 month 32 daystrong Postgres là gì? Vâng, chỉ có mã có thể nói (hoặc người đã viết nó) chắc chắn. Tôi đoán nó có nghĩa là "tạm ứng một tháng, sau đó 32 ngày". Người ta không thể chuyển đổi ngày sang tháng hoặc ngược lại.

Làm thế nào nó có thể xảy ra ở đó? Trung bình là nhạy cảm với các ngoại lệ, vì vậy nếu một số giá trị khá lớn ở đó trong nhiều ngày, nó sẽ có ảnh hưởng. Làm thế nào được nullgiá trị xử lý? Có phải một số người dùng chỉ định ngày trong tương lai hoặc đưa ra các giá trị không hợp lý? Có một số chuyển đổi ngầm đang diễn ra? Các nhà phát triển Postgres đã tạo ra một hàm trung bình đặc biệt trong các khoảng thời gian chưa?

Đối với vấn đề của bạn, tôi khuyên bạn nên sử dụng (xin lỗi nếu điều này không hoạt động, tôi không có cơ sở dữ liệu trong tay):

select avg(extract(epoch from now()) - extract(epoch from birthday)) from "user";

Điều này hoạt động cho người dùng ở độ tuổi hợp lý, nhưng nếu bạn có người dùng từ năm 1700, câu trả lời cũng sẽ phụ thuộc vào địa điểm, vì lịch mới đã được thông qua sau đó ở một số quốc gia.

Đọc cuốn sách sau đây để biết các quirks khác với ngày.

[1] "Phát triển các ứng dụng cơ sở dữ liệu định hướng thời gian trong SQL", Richard T Snodgrass, Morgan-Kaufmann, 1999. Xem trang chủ của anh ấy , Trang 30-32.


extract(epoch FROM age(birthdate));âm thanh tốt hơn với tôi
Evan Carroll

Nếu bạn sử dụng extract(epoch from '1 month')' the value is undefined. A one month delta can be 28, 29, 30 or 31 days. The semantics of tuổi (t) ` now()-tcho phép chuyển đổi chính xác, nhưng bất kỳ giá trị tham chiếu nào khác có thể sai. Lấy đồng bằng ở mức tem thời gian unix cho phép khái quát hóa chính xác (tất nhiên bỏ qua giây nhuận) và do đó là một cách chính xác được sử dụng trong mã sản xuất.
Grimaldi

0

Hàm AGE()trả về intervalgiá trị [1].

Nếu bạn chỉ muốn tính toán số năm bạn phải trích xuất agehàm com , vd:

SELECT AVG(EXTRACT(year FROM AGE(birthday))) FROM user;

Xin vui lòng, xem tài liệu [2] để biết thêm chi tiết.

Người giới thiệu:

  1. https://www.postgresql.org/docs/cản/static/datatype-datetime.html
  2. https://www.postgresql.org/docs/9.5/static/fifts-datetime.html

Tính trung bình số năm dẫn đến mất độ chính xác, không?
n1r3
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.