2017-04-06 103 views
0

我試圖執行以下查詢甲骨文 - ORA-01848錯誤

SELECT w.grid_no, SUM(A) 
FROM TABLE_1 w 
WHERE w.DAY between to_date((select jsow from TABLE_2 t where t.grid_no = w.grid_no and t.crop_no=90) || '-2016','DDD-YYYY') - 0 
     and to_date((select jsow from TABLE_2 t where t.grid_no = w.grid_no and t.crop_no=90) || '-2016','DDD-YYYY') + 0 + 10 - 1 
     and A > 8 
group BY w.GRID_NO 

,但我有錯誤

01848. 00000 - "day of year must be between 1 and 365 (366 for leap year)" 

相反,如果我添加上grid_no查詢工作的過濾器;例如

SELECT w.grid_no, SUM(A) 
FROM TABLE_1 w 
WHERE w.grid_no=1000 -- <---- the added filter 
     and w.DAY between to_date((select jsow from TABLE_2 t where t.grid_no = w.grid_no and t.crop_no=90) || '-2016','DDD-YYYY') - 0 
     and to_date((select jsow from TABLE_2 t where t.grid_no = w.grid_no and t.crop_no=90) || '-2016','DDD-YYYY') + 0 + 10 - 1 
    and A > 8 

涉及的兩個表是:

TABLE_1 [grid_no, day, A] 
TABLE_2 [grid_no, crop_no, jsow] 

JSOW是儒略日:對於給定的一對(grid_no,crop_no)存儲在表2的最大值可以去從1到366

我的目標是有這樣的事情:對於TABLE_1中的每個grid_no,我必須在TABLE_2中獲取相應的jsow值,然後在通過jsow指定的範圍中求和A值。

+0

錯誤提示你實際上有'jsow'值不在1和366之間? –

+0

@AlexPoole我檢查了:MIN(jsow)= 1,MAX(jsow)= 366。 grid_id = 1000(請參閱第二個查詢)擁有jsow = 366 – Fab

+0

網格ID 1000顯然具有良好的jsow值,而其他網格則沒有。你是說'select min(jsow),max(jsow)from table_2'在* all * grid ID中顯示1和366,或者只顯示1000?如果它適用於所有ID,那麼是否帶有'crop_no = 90'過濾器? –

回答

1

如果你有空值table_2,或有在table_1其在table_2(作物90)不匹配的行grid_id,子查詢要麼返回null或沒有數據。無論哪種方式,您最終都會得到一個無效的數據字符串。

隨着一些虛擬的數據:

create table table_1 (grid_no, day, a) as 
    select 1000, date '2016-01-01', 42 from dual 
    union all select 1001, date '2016-01-02', 42 from dual 
    union all select 1002, date '2016-01-03', 42 from dual 
    union all select 1003, date '2016-01-04', 42 from dual; 

create table table_2(grid_no, crop_no, jsow) as 
    select 1000, 90, 1 from dual 
    union all select 1001, 91, 367 from dual 
    union all select 1002, 90, null from dual; 

SELECT w.grid_no, 
    (select jsow from TABLE_2 t where t.grid_no = w.grid_no and t.crop_no=90) as jsow, 
    (select jsow from TABLE_2 t where t.grid_no = w.grid_no and t.crop_no=90) || '-2016' as date_string 
FROM TABLE_1 w; 

    GRID_NO  JSOW DATE_STRING         
---------- ---------- --------------------------------------------- 
     1000   1 1-2016          
     1001   -2016           
     1002   -2016           
     1003   -2016           

如果您嘗試那些'-2016字符串中的一個轉換爲日期,你會得到同樣的錯誤:

select to_date('-2016', 'DDD-YYYY') from dual; 

ORA-01848: day of year must be between 1 and 365 (366 for leap year) 

你可以重寫查詢一個連接而不是兩個子查詢,這使得您可以輕鬆過濾所需的行:

SELECT w.grid_no, SUM(w.A) 
FROM TABLE_1 w 
JOIN TABLE_2 t ON t.grid_no = w.grid_no 
AND w.DAY between to_date(t.jsow || '-2016','DDD-YYYY') - 0 
    AND to_date(t.jsow || '-2016','DDD-YYYY') + 9 
WHERE t.crop_no=90 
AND t.jsow between 1 and 366 
AND w.A > 8 
GROUP BY w.GRID_NO; 

內部連接意味着任何table_1行沒有table_2行被忽略; jsow上的過濾器在萬一匹配項爲空的情況下。你可能更喜歡成爲一個外連接,這取決於你真的在做什麼。