2017-10-27 79 views
5

Tôi làm việc với Oracle SQL và tôi có một bảng có 3 cột: Process, Start DateEnd Date. Tôi muốn tính toán thời gian cho mỗi quá trình.Thời gian trôi qua của con người có thể đọc được trong nhiều ngày

tôi đã sử dụng truy vấn này:

select 
(enddate.date_value - startdate.date_value) as duration 
from dual 

và kết quả là trong ngày.

Ví dụ: Ngày bắt đầu 30.3.2016 17:14:53 và ngày kết thúc là 8.7.2016 14:51:21

Khi tôi sử dụng các truy vấn, kết quả là 99.90032407407407407407407407407407407407, nhưng tôi muốn kết quả như thế này: 3 months, 7 days, 21 hours, 36 minutes, 28 seconds.

Tôi có thể làm như thế nào?

+0

vấn đề Ngay khi bạn muốn các đơn vị lớn hơn ngày, bạn đã có. Bạn phải chọn xem bạn định nói dối và có các tháng có độ dài tiêu chuẩn (ví dụ: 30 ngày) hay bạn có tình huống "3 tháng, 7 ngày, ..." có thể đại diện cho các khoảng thời gian thực tế khác nhau, tùy thuộc vào chính xác * khi * trong năm thời kỳ xảy ra. Không phải là đặc biệt hấp dẫn.Bạn có chắc bạn thực sự cần những gì bạn đang yêu cầu ở đây, và rằng những người yêu cầu cho nó hiểu những loại thương mại? –

+0

@Damien_The_Unbeliever, Tôi đồng ý với bạn, nếu bạn muốn chuyển đổi chỉ một số ngày, nhưng nếu bạn muốn một repesentation thời gian giữa 2 ngày bạn không cần một số cố định của ngày mỗi tháng (ví dụ: tất cả 30 ngày) hoặc cố định số ngày mỗi năm, hãy xem đề xuất của tôi (tôi chắc chắn rằng chúng tôi có thể đơn giản hóa/tối ưu hóa nó, nhưng có vẻ như hoạt động!) – Indent

+0

@Indent - những gì tôi đang cố chỉ ra là "3 tháng, 7 ngày, ..." có thể đại diện cho các khoảng thời gian khác nhau nếu bạn không áp dụng các tháng có độ dài cố định. I E. đó là khoảng thời gian từ ngày 1 tháng 2 đến ngày 8 tháng 5 năm 2000 và biểu thị thời gian thực tế là 97 ngày. Một năm sau đó giữa những ngày đó, nó đại diện cho 96 ngày. Và trong ví dụ OP, nó đại diện cho 99 ngày. –

Trả lời

1

Sự khác biệt giữa hai giá trị DATEnumber đại diện cho số ngày. Bạn dường như muốn có một interval, điều này có thể được thực hiện bằng cách sử dụng các giá trị TIMESTAMP.

select cast(enddate as timestamp) - cast(startdate as timestamp) 
from the_table 

Kết quả của subtracting a timestamp from a timestamp là một khoảng thời gian.

Định dạng giá trị interval tuy nhiên khá phức tạp trong Oracle. Xem ví dụ format interval with to_char

+0

Trên thực tế, chỉ có thể chọn một, hoặc 'ngày kết thúc' hoặc' ngày bắt đầu'. –

2

này phức tạp truy vấn (Đặc biệt cho NGÀY !!):

Để tính toán một đúng Day tôi thêm Month và 12 * Year với ngày đầu tiên.

with dates as(
select 
    sysdate  as d1, 
    sysdate-99.90032407407407407407407407407407407407-365 as d2 
from 
    dual 
), 
dates_parts as (
SELECT 
    d1, 
    d2, 
    EXTRACT(YEAR FROM (d1 - d2) YEAR TO MONTH) as Year, 
    EXTRACT(MONTH FROM (d1 - d2) YEAR TO MONTH) as Month, 
    EXTRACT(DAY FROM (d1 - d2) DAY TO SECOND) as Day, 
    EXTRACT(HOUR FROM cast(d1 as timestamp) - cast(d2 as timestamp)) as Hour, 
    EXTRACT(MINUTE FROM cast(d1 as timestamp) - cast(d2 as timestamp)) as Minute,  
    EXTRACT(SECOND FROM cast(d1 as timestamp) - cast(d2 as timestamp)) as Second 
FROM dates 
) 
select 
    dates_parts.Year, 
    dates_parts.Month, 
    dates_parts.Day, 
    dates_parts.Hour, 
    dates_parts.Minute, 
    dates_parts.Second, 
    EXTRACT(DAY FROM (d1 - ADD_MONTHS(d2,Month+Year*12)) DAY TO SECOND) as Day_Corrected 
from 
    dates_parts 

sẽ sản xuất phần ngày khác nhau:

| YEAR | MONTH | DAY | HOUR | MINUTE | SECOND | DAY_CORRECTED | 
|------|-------|-----|------|--------|--------|---------------| 
| 1 |  3 | 464 | 21 |  36 |  28 |    7 | 
1

Dựa trên câu trả lời trước đây của tôi, bạn có thể tạo ra một chức năng Oracle sinceHumanReadable:

dụ từ https://momentjs.com/docs/#/plugins/preciserange/ sản xuất cùng một kết quả

moment("2014-01-01 12:00:00").preciseDiff("2015-03-04 16:05:06"); 
// 1 year 2 months 3 days 4 hours 5 minutes 6 seconds 

http://sqlfiddle.com/#!4/d6783/1

create or replace FUNCTION sinceHumanReadable(start_date IN date,end_date IN date) 
    RETURN VARCHAR2 
IS result VARCHAR2(255); 

    BEGIN 

    with 
    dates_parts as (
    SELECT 
     EXTRACT(YEAR FROM (end_date - start_date) YEAR TO MONTH) as Year, 
     EXTRACT(MONTH FROM (end_date - start_date) YEAR TO MONTH) as Month,  
     EXTRACT(HOUR FROM cast(end_date as timestamp) - cast(start_date as timestamp)) as Hour, 
     EXTRACT(MINUTE FROM cast(end_date as timestamp) - cast(start_date as timestamp)) as Minute,  
     EXTRACT(SECOND FROM cast(end_date as timestamp) - cast(start_date as timestamp)) as Second 
    FROM dual 
    ), 
    dates_parts_with_day as (
    select   
     Year,Month,Hour,Minute,Second, 
     EXTRACT(DAY FROM (end_date - ADD_MONTHS(start_date,Month+Year*12)) DAY TO SECOND) as Day 
    from dates_parts 
    ) 
    select 
     decode(dates_parts_with_day.Year, 0,'', dates_parts_with_day.Year || ' years ')|| 
     decode(dates_parts_with_day.Month,0,'', dates_parts_with_day.Month || ' months ')|| 
     decode(dates_parts_with_day.Day,0,'', dates_parts_with_day.Day || ' days ')|| 
     decode(dates_parts_with_day.Hour,0,'', dates_parts_with_day.Hour || ' hours ')|| 
     decode(dates_parts_with_day.Minute,0,'', dates_parts_with_day.Minute || ' minutes ')|| 
     dates_parts_with_day.Second || ' seconds' 
    into result 
    from 
     dates_parts_with_day; 

    RETURN(result); 

    END sinceHumanReadable; 
GO 

Truy vấn

with dates as ( 
    select sysdate-99.90032407407407407407407407407407407407 as d1,sysdate as d2 from dual 
    union all 
    select to_date('2016-03-30 17:14:53','yyyy-mm-dd hh24:mi:ss') as d1,to_date('2016-07-08 14:51:21','yyyy-mm-dd hh24:mi:ss') as d2 from dual 
    union all 
    select to_date('2014-01-01 12:00:00','yyyy-mm-dd hh24:mi:ss') as d1,to_date('2015-03-04 16:05:06','yyyy-mm-dd hh24:mi:ss') as d2 from dual 
    union all 
    select sysdate as d1,add_months(sysdate,35) as d2 from dual 
    union all 
    select sysdate as d1,sysdate as d2 from dual 
) 
select 
    d1,d2, 
    sinceHumanReadable(d1,d2) as since 
from 
    dates; 

sẽ sản xuất:

|     D1 |     D2 |            SINCE | 
|----------------------|----------------------|-----------------------------------------------------| 
| 2017-07-19T17:50:00Z | 2017-10-27T15:26:28Z |  3 months 7 days 21 hours 36 minutes 28 seconds | 
| 2016-03-30T17:14:53Z | 2016-07-08T14:51:21Z |  3 months 7 days 21 hours 36 minutes 28 seconds | 
| 2014-01-01T12:00:00Z | 2015-03-04T16:05:06Z | 1 years 2 months 3 days 4 hours 5 minutes 6 seconds | 
| 2017-10-27T15:26:28Z | 2020-09-27T15:26:28Z |       2 years 11 months 0 seconds | 
| 2017-10-27T15:26:28Z | 2017-10-27T15:26:28Z |           0 seconds | 
Các vấn đề liên quan