2009-12-26 47 views
37

Có một số TIMESTAMPDIFF() tương đương với PostgreSQL không?Sự khác biệt dấu thời gian trong giờ cho PostgreSQL

Tôi biết tôi có thể trừ hai dấu thời gian để nhận được postgresql INTERVAL. Tôi chỉ muốn sự khác biệt giữa hai dấu thời gian tính bằng giờ được biểu thị bằng một INT.

tôi có thể làm điều này trong MySQL như thế này:

TIMESTAMPDIFF(HOUR, links.created, NOW()) 

Tôi chỉ cần sự khác biệt giữa hai timestamps trong giờ thể hiện dưới dạng một số nguyên.

Giải pháp làm việc cho tôi:

SELECT "links_link"."created", 
"links_link"."title", 
(EXTRACT(EPOCH FROM current_timestamp - "links_link"."created")/3600)::Integer AS "age" 
FROM "links_link" 

Trả lời

62

Những điều đầu tiên nảy lên

EXTRACT(EPOCH FROM current_timestamp-somedate)/3600 

Có thể không đẹp, nhưng unblocks đường. Có thể đẹp hơn nếu phân chia khoảng thời gian theo khoảng thời gian đã được xác định.

Chỉnh sửa: nếu bạn muốn lớn hơn 0 hoặc là sử dụng abs hoặc lớn nhất (..., 0). Cho dù phù hợp với ý định của bạn.

Sửa ++: lý do tại sao tôi không sử dụng ageage với một đối số duy nhất, trích dẫn tài liệu: Subtract từ current_date (vào lúc nửa đêm). Có nghĩa là bạn không nhận được "độ tuổi" chính xác trừ khi chạy vào nửa đêm. Ngay bây giờ đã gần 1 giờ sáng ở đây:

select age(current_timestamp); 
     age   
------------------ 
-00:52:40.826309 
(1 row) 
5

Bạn có thể sử dụng chức năng "trích xuất" hoặc "date_part" trong khoảng thời gian cũng như dấu thời gian, nhưng tôi không nghĩ điều đó là điều bạn muốn. Ví dụ, nó cho 3 trong một khoảng thời gian '2 ngày, 3 giờ'. Tuy nhiên, bạn có thể chuyển đổi một khoảng thời gian thành số giây bằng cách chỉ định 'epoch' làm thành phần thời gian bạn muốn: extract(epoch from '2 days, 3 hours'::interval) trả về 183600 (sau đó bạn chia cho 3600 để chuyển đổi giây thành giờ).

Vì vậy, đặt tất cả những thứ này lại với nhau, về cơ bản bạn sẽ nhận được câu trả lời của Michael: extract(epoch from timestamp1 - timestamp2)/3600. Vì bạn dường như không quan tâm về những dấu thời gian trước đó, có thể bạn muốn quấn rằng trong abs:

SELECT abs(extract(epoch from timestamp1 - timestamp2)/3600) 
+0

Điều này thực sự là gần nhất. Việc bỏ tất cả các số thập phân không phải là một vấn đề mặc dù tôi khá buồn vì thiếu một hàm tích hợp để làm điều này như MySQL. – TheLizardKing

+0

Không được có bất kỳ số thập phân nào vì nó sẽ thực hiện phân chia số nguyên. – araqnid

+0

araqnid, tôi cũng nghĩ như vậy, nhưng tôi đã thử và nó thực sự có năng suất nổi. –

3

Điều này có vẻ điên đến rất nhiều các nhà phát triển người muốn tận dụng lợi thế của các chức năng cơ sở dữ liệu,

Nhưng sau khi có các vấn đề đầy đủ, tạo và sửa lỗi các ứng dụng cho mysql và postgrsql với các hàm so sánh php, tôi đã đi đến kết luận (cho bản thân mình), cách dễ nhất, đó là đơn giản nhất với ít đau đầu SQL hơn. tận dụng lợi thế của bất kỳ người trong số họ.

Tại sao? bởi vì nếu bạn đang phát triển trong một ngôn ngữ trung gian như PHP, PHP có tất cả các hàm này, và chúng dễ thực hiện hơn trong ode ứng dụng khi so sánh các số nguyên. Dấu thời gian PostgreSQL không phải là == UNIX TIMESTAMP và dấu thời gian UNIX của MySQL KHÔNG phải là dấu thời gian của PostgresQL hoặc Oracles .. nó trở nên khó khăn hơn nếu bạn sử dụng dấu thời gian của cơ sở dữ liệu ..

vì vậy chỉ cần sử dụng số nguyên, không phải dấu thời gian, làm số số giây kể từ ngày 1 tháng 1 năm 1970 nửa đêm. và đừng bận tâm đến dấu thời gian của cơ sở dữ liệu. và sử dụng gmdate() và lưu trữ mọi thứ dưới dạng thời gian gmt để tránh các vấn đề múi giờ.

nếu bạn cần tìm kiếm, sắp xếp hoặc so sánh ngày với dữ liệu khác hoặc tháng hoặc năm hoặc ngày trong tuần hoặc bất kỳ thứ gì trong ứng dụng của bạn, và kiểu dữ liệu INTEGER cho time_day, time_hour, time_seconds. hoặc bất cứ điều gì bạn muốn để chỉ mục được tìm kiếm sẽ làm cho cơ sở dữ liệu dễ dàng hơn và di động hơn. bạn chỉ có thể sử dụng một trường, trong hầu hết các trường hợp: INTEGER time_created NOT NULL

(nhiều trường trong hàng cơ sở dữ liệu của bạn là nhược điểm duy nhất của giải pháp này mà không tìm thấy) coffee :)

Chức năng ngày của php là nổi bật so với ngày tháng, nhưng trong mysql hoặc postgresql, so sánh ngày tháng? nah .. sử dụng so sánh số nguyên sql

tôi nhận thấy có thể SEEM dễ sử dụng CURRENT_TIMESTAMP trên hàm chèn. HA! không bị lừa.

Bạn không thể làm DELETE FROM SESSION_TABLE WHERE time-initialized < '2 days' nếu thời gian intitialized là dấu thời gian postgresql. nhưng bạn có thể làm:

DELETE FROM SESSION_TABLE WHERE time_initialized < '$yesterday'

Chừng nào bạn đặt $ ngày hôm qua trong php là số nguyên giây kể từ năm 1970 mà ngày hôm qua đã.

Việc dọn dẹp bản ghi phiên làm việc dễ dàng hơn so sánh các dấu thời gian trong các câu lệnh chọn postgresql.

CHỌN tuổi(), CHỌN trích xuất() và asbtime là những cơn đau đầu của chính chúng. Đây chỉ là ý kiến ​​của tôi.

bạn có thể làm thêm, trừ, <,>, tất cả với ngày php đối tượng

_peter_sysko U4EA Networks, Inc.

+2

Vậy làm thế nào để bạn đảm bảo rằng chỉ những ngày hợp lệ mới được đưa vào "ngày nguyên"? Bạn kiểm tra xem liệu '2012-02-29' có hợp lệ hay không. Làm thế nào để bạn biết nếu thời gian '02: 14' là hợp lệ cho ngày 24 tháng 3? (Gợi ý nó không hợp lệ ở mọi nơi do các quy tắc DST). Và việc xóa khá dễ dàng: 'DELETE FROM SESSION_TABLE WHERE time-initialized

1

extract(hour from age(now(),links.created)) cung cấp cho bạn một số sàn làm tròn số chênh lệch giờ.

+3

Sau ba năm ... tôi nghi ngờ. Bên cạnh đó: Cố gắng 'chọn trích xuất (giờ từ '11 mons 30 ngày 23:00:00 ':: khoảng thời gian);' bạn sẽ chỉ '23' và không phải 11 tháng, 30 ngày và 23 giờ được biểu thị theo giờ (khoảng 8660) . –

3

postgresql có được giây chênh lệch giữa timestamps

SELECT (
    (extract (epoch from (
     '2012-01-01 18:25:00'::timestamp - '2012-01-01 18:25:02'::timestamp 
         ) 
      ) 
    ) 
)::integer 

mà in:

-2 

Vì timestamps hai giây ngoài. Lấy số và chia cho 60 để lấy số phút, chia cho 60 lần nữa để nhận giờ.

17

lĩnh vực Nhận nơi một dấu thời gian lớn hơn ngày trong postgresql:

SELECT * from yourtable 
WHERE your_timestamp_field > to_date('05 Dec 2000', 'DD Mon YYYY'); 

phút Subtract từ timestamp trong postgresql:

SELECT * from yourtable 
WHERE your_timestamp_field > current_timestamp - interval '5 minutes' 

giờ Subtract từ timestamp trong postgresql:

SELECT * from yourtable 
WHERE your_timestamp_field > current_timestamp - interval '5 hours' 
9

Câu trả lời của Michael Krelin là không hoàn toàn an toàn, vì nó có thể sai trong những trường hợp hiếm hoi. Vấn đề là khoảng thời gian trong PostgreSQL không có bối cảnh liên quan đến những thứ như tiết kiệm ánh sáng ban ngày. Khoảng thời gian lưu trữ nội bộ theo tháng, ngày và giây. Tháng không phải là một vấn đề trong trường hợp này vì trừ hai dấu thời gian chỉ sử dụng ngày và giây nhưng 'ngày' có thể là một vấn đề.

Nếu phép trừ của bạn liên quan đến việc thay đổi tiết kiệm ánh sáng ban ngày, một ngày cụ thể có thể được xem là 23 hoặc 25 giờ tương ứng. Khoảng thời gian sẽ tính đến điều đó, điều này rất hữu ích khi biết số ngày trôi qua theo nghĩa biểu tượng nhưng nó sẽ cho số giờ không chính xác đã trôi qua. Epoch trên khoảng thời gian sẽ chỉ nhân tất cả các ngày trước 24 giờ.

Ví dụ: nếu ngày đầy đủ 'ngắn' trôi qua và một giờ bổ sung của ngày tiếp theo, khoảng thời gian sẽ được ghi lại là một ngày và một giờ. Chuyển đổi thành epoch/3600 là 25 giờ. Nhưng trong thực tế 23 giờ + 1 giờ nên là tổng cộng 24 giờ.

Vì vậy, các phương pháp an toàn hơn là:

(EXTRACT(EPOCH FROM current_timestamp) - EXTRACT(EPOCH FROM somedate))/3600 

Như Michael đề cập trong bình luận tiếp theo của mình, bạn cũng sẽ có thể muốn sử dụng sàn() hoặc tròn() để có được kết quả như một giá trị số nguyên .

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