2013-09-05 16 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 
;