组内数据样本 - Teradata

时间:2012-06-08 15:59:30

标签: sql teradata sample-data

发现了一个类似的问题,但没有一个可以成功运作的答案。

我需要在一个表中选择每个状态类型50个样本。

TABLE1

MEMBER  STATUS
1234       A
1324       A
3424       R
3432       S
3232       R
2783       A
2413       S
4144       R
2387       S

我试过了:

  

SEL会员,状态   FROM TABLE1限定Row_Number()OVER(PARTITION   BY状态ORDER BY random(1,10000))< = 50

如上一个问题/答案所述,但Teradata不喜欢聚合或有序分析函数中的RANDOM。

2 个答案:

答案 0 :(得分:3)

如果您有一个离散数量的Status值,则以下方法可能工作,因为在Teradata评估WHERE子句之后处理了TOP运算符。 TOP n实际上是QUALIFY ROW_NUMBER() OVER()QUALIFY RANK () OVER()的窗口聚合方法的首选方法,在最差或性能最佳时提供更好的性能:

SELECT TOP 50 
       Member
     , Status
FROM Table1
WHERE Status = 'A'
UNION ALL
SELECT TOP 50 
       Member
     , Status
From Table1
WHERE Status = 'R'
UNION ALL
SELECT TOP 50 
       Member
     , Status
FROM Table1
WHERE Status = 'S';

您可能也成功使用多个查询,SAMPLE子句通过您希望采样的状态代码过滤每个查询。

答案 1 :(得分:2)

正如您在评论中所说,您不需要使用random,您可以这样做:

SEL     Member, status 
FROM    TABLE1 
QUALIFY ROW_NUMBER() OVER (
            PARTITION BY status 
            ORDER BY NULL) <= 50;

编辑:基于与假脱机空间错误相关的注释中的问题,我们可以在表大时尝试的方法是创建一个临时表,其中包含原始表中的一部分记录。

CREATE MULTISET VOLATILE TABLE tmp_tbl AS (
    SEL     Member, status
    FROM    TABLE1
    WHERE   somefield = 'somecriterion'
) WITH DATA 
ON COMMIT PRESERVE ROWS;

然后再试一次:

SEL     Member, status 
FROM    tmp_tbl /* now from temporary table */
QUALIFY ROW_NUMBER() OVER (
            PARTITION BY status 
            ORDER BY NULL) <= 50;