2013-09-05 34 views
1

我有一個產品清單和與單個表中銷售數量相對應的計數。數據佈局爲這樣:TERADATA從滾動SUM限制創建組標識

Product Name QTY_SOLD 
Mouse   23 
Keyboard   25 
Monitor   56 
TV    10 
Laptop   45 
... 

我想創造一個組被創建一個組ID,如果銷售數量的滾動總和大於50.我們可以通過產品名稱訂購更大,以得到一個類似的輸出以下。

Product Name QTY_SOLD GROUP_NBR 
Keyboard   25   1 
Laptop   45   1 
Monitor   56   2 
Mouse    23   3 
TV    10   3 

我創建了一個case語句來創建輸出我的需要,但如果我想組ID截止50改說100,如果我得到更多的產品和數量我必須不斷變化的情況說明。有沒有簡單的方法來使用遞歸或其他方法來適應此? 這部作品的Teradata 13.10

UPDATE main FROM prod_list AS main, 
( 
SEL PROD_NAME 
, QTY_SOLD 
, SUM(QTY_SOLD) OVER (ORDER BY PROD_NAME ROWS UNBOUNDED PRECEDING) RUNNING FROM prod_list 
) inr 
SET GROUP_NBR = CASE 
WHEN RUNNING < 50 THEN 1 
WHEN RUNNING > 50 AND RUNNING < 100 THEN 2 
WHEN RUNNING > 100 AND RUNNING < 150 THEN 3 
WHEN RUNNING > 150 AND RUNNING < 200 THEN 4 
WHEN RUNNING > 200 AND RUNNING < 250 THEN 5 
ELSE 6 
END 
WHERE main.PROD_NAME = inr.PROD_NAME ; 

回答

0

當我第一次看到你的問題,我認爲這是一種裝箱問題的。但是,您的查詢看起來你只是希望把你的數據變成ň桶:-)

Teradata的支持QUANTILE功能,但它的過時,因爲它創建了大小相等的桶,它不適合你的需求。您需要WIDTH_BUCKET這產生(顧名思義)相等的寬度的桶:

SELECT 
    PROD_id 
, COUNT(DISTINCT PROD_ID) AS QTY 
, SUM(QTY) OVER (ORDER BY QTY ROWS UNBOUNDED PRECEDING) RUNNING 
, WIDTH_BUCKET(RUNNING, 1, 120*2000000, 120) AS GRP_NBR 
FROM TMP_WORK_DB.PROD_LIST 
GROUP BY 1 

可以很容易地改變一個桶(2000000)或輪葉(120)的數量的大小。

+0

我從來沒有見過這個功能,但它完美的工作。謝謝。 –

0

創建參考表和加入......那麼改變只需要在表格中進行(甚至可以創建一個過程來幫助以後自動變化表)

的僞創建:

Create table group_nbr (low_limit,upper_limit,group_nbr) 

插入你的價值觀的情況下向表和使用條件比大於和小於內連接到它。

select *, group_nbr.group_nbr 
from table inner join group_nbr on RUNNING > lower_limit and RUNNING < upper_limit 

代碼,因爲它坐在那裏,但希望你的想法不夠好改變你的代碼,它不太工作。我發現將這些值留在參考表中就像比改變代碼更容易。您甚至可以通過在group_nbr表中添加一個'group_id'來允許多個group_nbr設置,並且讓group_id 1是一組運行限制和group_id爲2,3,4,5等不同組的運行限制,並使用where子句選擇你想要使用的group_id。

+0

好主意。讓我試試看看。謝謝 –

+0

讓我知道它是怎麼回事...這裏的邏輯應該適合你,這更多的是調整代碼並使用它的問題。我真的建議把'group_id'列放在那裏,因爲它可以讓你跟蹤每個組的各種值...將使未來的報告和歷史記錄驗證變得更容易一些。 – Twelfth

+0

我創建了一個遞歸查詢來填充group_nbr表,以便可以根據需要調整時間間隔和限制。然後,我使用grp_nbr表和我的正在運行的查詢,並使用一個簡單的設置組號。有時候,qroup號碼依次連續,但它仍然創建了我正在尋找的不同組。它像一個魅力。謝謝。 –

0

希望下面的邏輯有所幫助,如果約50

UPDATE main FROM prod_list AS main, 
( 
SEL PROD_NAME 
, QTY_SOLD 
, SUM(QTY_SOLD) OVER (ORDER BY PROD_NAME ROWS UNBOUNDED PRECEDING) RUNNING FROM prod_list 
) inr 
SET GROUP_NBR = RUNNING /50 
WHERE main.PROD_NAME = inr.PROD_NAME ; 
+0

這實際上並不奏效,因爲它仍然創造了不平衡的羣體數量。使用上面的數據創建了2個組。我嘗試了10個組的解決方案,但它仍然沒有真正平均分配產品。但它給了我一個嘗試的想法。 –

+0

我構建了這個代碼,運行了100多個產品,它幾乎給了我想要的東西,但它沒有像我期望的那樣均勻分佈。
UPDATE main FROM prod_list AS main,(SEL PROD_NAME,QTY_SOLD,SUM(QTY_SOLD)OVER(從NUMOF行開始排序的無序前置順序)從prod_list運行)inr SET GROUP_NBR = RUNNING MOD <存儲桶數量> WHERE main.PROD_NAME = inr.PROD_NAME ;' –

0

這是增量在我十二的建議創建的代碼。

-- create the first entry for the recursive query 
INSERT TMP_WORK_DB.GRP_NBRS VALUES (0,1,0,2000000); 


INSERT TMP_WORK_DB.GRP_NBRS (GRP_NBR,LOWER_LIMIT, UPPER_LIMIT) 
WITH RECURSIVE GRP_RECRSV (GRP_NBR, LOWER_LIMIT, UPPER_LIMIT) 
AS (
SELECT 
    1 AS GRP_NBR 
, LOWER_LIMIT 
, UPPER_LIMIT 
FROM TMP_WORK_DB.GRP_NBRS 
UNION ALL 
SELECT 
    GRP_NBR + 1 
, LOWER_LIMIT + 2000000 -- set the interval to 2 million 
, UPPER_LIMIT + 2000000 -- can be adjusted as needed 
FROM GRP_RECRSV 
WHERE GRP_NBR < 120 -- needed a limit so that it would not be endless 
) 
SELECT * FROM GRP_RECRSV 
; 


-- delete the first entry because it was duplicated 
DELETE FROM TMP_WORK_DB.GRP_NBRS WHERE GRP_NBR = 0; 

-- set grp nbr using the limits table 
INSERT TMP_WORK_DB.PROD_LIST_GRP 
WITH NUMOFPRODS (PROD_NAME,QTY,RUNNING) AS 
(
    SELECT 
     PROD_NAME 
    , COUNT(DISTINCT PROD_ID) AS QTY 
    , SUM(QTY) OVER (ORDER BY QTY ROWS UNBOUNDED PRECEDING) RUNNING 
    FROM TMP_WORK_DB.PROD_LIST 
    GROUP BY 1 
) 
SELECT 
    PROD_NAME 
, QTY 
, RUNNING 
, GRP_NBR 
FROM NUMOFPRODS a 
JOIN TMP_WORK_DB.GRP_NBRS b ON RUNNING BETWEEN LOWER_LIMIT AND UPPER_LIMIT 
;