2013-02-25 50 views
1

在我們的數據庫中,我們有一些使用十進制日期格式的表格:yyyymmdd,全部作爲一個大小數(即今天將是20130225)。我正在嘗試創建一個SQL查詢,以每月一桶的方式將事情拉回。從我的研究中看來,最好的方法是將數字除以100以截斷最右邊的日期(20130225/100等於201302,如果餘數被移除)。劃分「SELECT列表中的表達式無效」。

我似乎無法弄清楚如何使其功能。我開始在我的Select和Group by中使用類似(INVOICE_DATE/100) As "INVOICE_MONTH"的東西。當沒有工作時,我把集團減少到"INVOICE_MONTH",然後到(INVOICE_DATE/100),這兩者都沒有工作。所以我把選擇和分組減少到INVOICE_DATE/100,這似乎還沒有工作。

這是我在當前的代碼(有一對夫婦的小刪節)

Select Count(COMPETITOR_NAME) as "STORE COUNT", 
    COMPETITOR_NAME, 
    INVOICE_DATE/100, 
    CUSTOMER_NUMBER, 
    OVERRIDE_TYPE, 
    Sum (QTY_SOLD) as "Quantity Sold", 
    Sum (EXT_ORIGINAL_PRICE) as "Sum Original Price", 
    Sum (EXT_OVERRIDE_PRICE) as "Sum Override Price", 
    Sum (EXT_VARIANCE) As "Sum Variance", 
    Sum (INTERNAL_COST) as "Internal Cost" 
From DA*****.DW*******.PRCOVRWK 
Where INVOICE_DATE/100 between 201002 and 201302 
Group By ROLLUP(COMPETITOR_NAME, 
    INVOICE_DATE/100), 
    OVERRIDE_TYPE, 
    CUSTOMER_NUMBER 
Order By OVERRIDE_TYPE, 
    COMPETITOR_NAME, 
    INVOICE_DATE, 
    CUSTOMER_NUMBER 

我不禁在想,如果我的Where語句導致的問題也是如此。起初我只是使用Where INVOICE_DATE between 20100225 and 20130225,但我想也許它需要使用與Select語句中相同的東西? (是的,在這一點上,我還挺有擴展性。)我一直在盡力遵循IBM網站上的文檔,但是我一定是在錯誤地閱讀它,因爲它似乎沒有按預期發揮作用。

無論如何。基本的需求是能夠將信息以月度桶的形式返回。所以,如果你知道另一種方法,那麼可以實現的是可以接受的。我希望能夠使用小數部分來提取年/日期組合並在Group By中使用它來獲得我需要的結果。

PS-我們正在使用DB2的v5.1 for i。

+0

'月(Invoice_Date)'不提取月份?如果不是,那麼你能否確認Field的數據類型是什麼? – xQbert 2013-02-25 14:15:02

+0

選擇列表中的哪個表達式是在抱怨? (逐一刪除它們直到它工作) – 2013-02-25 14:17:32

+0

@xQbert日期包含爲小數。我認爲我們不能在小數點上使用日期算術? – 2013-02-25 14:22:05

回答

0

事實上,答案相當簡單。問題是我沒有在Order By中正確列出分部。這似乎不應該是重要的,但一旦我這樣做,整個事情的工作。

我確實結束了小數的答案。我決定用四捨五入的方法來解決這個問題,這看起來很順利。這裏是我結束了對好奇代碼:

Select Count(COMPETITOR_NAME) as "STORE COUNT", 
    COMPETITOR_NAME, 
    ROUND(INVOICE_DATE/100, 0) As "Month_Date", 
    CUSTOMER_NUMBER, 
    OVERRIDE_TYPE, 
    Sum (QTY_SOLD) as "Quantity Sold", 
    Sum (EXT_ORIGINAL_PRICE) as "Sum Original Price", 
    Sum (EXT_OVERRIDE_PRICE) as "Sum Override Price", 
    Sum (EXT_VARIANCE) As "Sum Variance", 
    Sum (INTERNAL_COST) as "Internal Cost" 
From DA******.DW*******.PRCOVRWK 
Where INVOICE_DATE > 20100201 
Group By COMPETITOR_NAME, 
    ROUND(INVOICE_DATE/100, 0), 
    OVERRIDE_TYPE, 
    CUSTOMER_NUMBER 
Order By COMPETITOR_NAME, 
    ROUND(INVOICE_DATE/100, 0), 
    SUM (EXT_VARIANCE), 
    CUSTOMER_NUMBER 

所以,是的,愚蠢的,因爲它看起來,DB2 V5,1真的很希望我做SelectGroup ByOrder By之間的語句匹配。好吧,幾乎相同,您可以在Select中使用As,但不能在其他地方使用。

希望這可以幫助任何似乎有類似問題的人。

0

我認爲問題是彙總的語法。檢查documentation。 。 。表達式group by rollup僅適用於所有列。所以,試試這個:

Group By ROLLUP (COMPETITOR_NAME, 
    INVOICE_DATE/100, 
    OVERRIDE_TYPE, 
    CUSTOMER_NUMBER) 

或者對不同的組合使用分組集。

此外,我建議你明確使用整數除法。所以,用idiv替換\

invoice_date idiv 100 
+0

我相當肯定這不是彙總,因爲這也是工作之前我加入該部門。另外,我只是移動了Rollup,並沒有解決它,所以...最重要的是,當我使用IDIV時,我被告知'100' toke無效。它期望一個',FROM INTO'。 – 2013-02-25 14:30:30

1

十進制日期做出比他們需要我們的生活更加艱難。我可以建議使用Alan Campin's IDate functions嗎?他們會讓你輕鬆地將這些小數轉換爲SQL日期數據類型。一旦你有了這些,你可以提取出年份和月份,並對這些進行GROUP BY。

你真的在V5R1上嗎?我不認爲ROLLUP早...

+0

哈哈,是的,如果這取決於我...我一直被告知我們有6,1,但是我所有的錯誤都是5,1。是的,Rollup的作品。我也同意十進制日期是我們存在的禍根,但我沒有能力改變我們的日期格式。所有這些決定都不在我手中。謝謝,雖然:-)。 – 2013-02-25 15:18:17

+0

根本不會改變數據庫,你所擁有的是一組SQL用戶定義函數,它們將SQL日期中的十進制'日期'轉換爲真正的SQL日期。 – 2013-02-25 15:37:45

+0

我應該更加明確。我只能讀取這臺服務器。 iDates文檔說我需要將文件保存到iSeries,這不是他們要讓我做的事情。有沒有辦法在我身邊運行這種事情? – 2013-02-25 15:46:57

1

嘗試將小數轉換爲日期。

select digits(date), 
    year(date(
    substr(digits(date),1,4) concat 
    ''-'' concat 
    substr(digits(date),5,2) concat 
    ''-'' concat substr(digits(date),7,2))) as year, 
    month(date(
    substr(digits(date),1,4) concat 
    ''-'' concat 
    substr(digits(date),5,2) concat 
    ''-'' concat substr(digits(date),7,2))) as month 
from .... 

的這裏關鍵是將其轉換爲字符,然後串並插入適當的日期分隔符。

然後爲GROUP BY重新做一遍。這將是最醜陋的SQL語句,但它將成爲所有客戶端。

+0

Upvoting用於持久性。我沒有耐心爲自己確認這是否有效,但我會假設沿着這些方向行事的某種方式會起作用。鑑於OP的情況,他說他正在尋找什麼東西,任何東西.... – 2013-02-26 06:27:56

1

在黑暗中拍攝:您是否嘗試過使用INT來強制數據爲整數?如在INT(INVOICE_DATE/100)

其他「拼寫」可能是INTEGER(INVOICE_DATE/100)CAST(INVOICE_DATE/100 AS INTEGER)