2012-06-08 73 views
1

我想從範圍表中選擇值。 事情是這樣的:Oracle:在缺失值的日期內選擇日期範圍內的值

SELECT 
    date_values.date_from, 
    date_values.date_to, 
    sum(values.value) 
FROM values 
    inner join date_values on values.id_date = date_values.id 
    inner join date_units on date_values.id_unit = date_units.id 
WHERE 
    date_values.date_from >= '14.1.2012' AND 
    date_values.date_to <= '30.1.2012' AND 
    date_units.id = 4 
GROUP BY 
    date_values.date_from, 
    date_values.date_to 
ORDER BY 
    date_values.date_from, 
    date_values.date_to; 

但此查詢還給我只有幾天的範圍,這裏是任意值。就像這樣:

14.01.12 15.01.12 66 
15.01.12 16.01.12 4 
17.01.12 18.01.12 8 
...etc 

(這裏失蹤12年1月16日至12年1月17日)

但我想選擇缺失值太多,像這樣:

14.01.12 15.01.12 66 
15.01.12 16.01.12 4 
16.01.12 17.01.12 0 
17.01.12 18.01.12 8 
...etc 

我不能使用PL/SQL,如果你能建議更通用的解決方案,我可以擴展使用小時,月,年;會很棒。

+1

在我看來,你需要一個外連接。日期16.01.12到17.01.12在date_units表中似乎沒有相應的記錄。我對嗎? – LeftyX

+0

date_values表中缺少日期16.01.12至17.01.12。 Date_units是表格,我在那裏存儲範圍類型(​​如days(date_units.id = 4),hours,months,weeks,years ...)。我認爲,我「只是」需要生成第二個臨時表日期並與這兩個表相交。問題是如何生成此表? – user1444155

回答

2

我打算假設您提供date_fromdate_to。如果是這樣,你可以先生成你的日期列表,然後加入它來獲得結果的剩餘部分。或者,您可以union此查詢到您的date_values表,因爲union做了明確的刪除任何額外的數據。

如果這是如何生成的日期列表:

select to_date('14.1.2012','dd.mm.yyyy') + level - 1 as date_from 
     , to_date('14.1.2012','dd.mm.yyyy') + level as date_to 
    from dual 
connect by level <= to_date('30.1.2012','dd.mm.yyyy') 
        - to_date('14.1.2012','dd.mm.yyyy') 

你的查詢可能成爲

with the_dates as (
select to_date('14.1.2012','dd.mm.yyyy') + level - 1 as date_from 
     , to_date('14.1.2012','dd.mm.yyyy') + level as date_to 
    from dual 
connect by level <= to_date('30.1.2012','dd.mm.yyyy') 
        - to_date('14.1.2012','dd.mm.yyyy') 
     ) 
SELECT 
    dv.date_from, 
    dv.date_to, 
    sum(values.value) 
FROM values 
    inner join (select the_dates.date_from, the_dates.date_to, date_values.id 
       from the_dates 
       left outer join date_values 
        on the_dates.date_from = date_values.date_from) dv 
    on values.id_date = dv.id 
    inner join date_units on date_values.id_unit = date_units.id 
WHERE 
    date_units.id = 4 
GROUP BY 
    dv.date_from, 
    dv.date_to 
ORDER BY 
    dv.date_from, 
    dv.date_to; 

with語法被稱爲子查詢保理是不是真的需要在這種情況下,但它使代碼更清潔。

我也假定的date列是日期。這是不明顯的,因爲你正在做一個字符串比較。您應該始終明確地將日期轉換爲適用的日期,並且應該始終將日期存儲爲日期。它從長遠來看可以節省很多麻煩,因爲事情不可能被錯誤地輸入或被錯誤地比較。