【问题标题】:How to perform stratification based on a column in Snowflake如何根据雪花中的列执行分层
【发布时间】:2019-10-18 16:19:36
【问题描述】:

我正在使用 Snowflake 编写我的 sql 查询。我们有一个巨大的表,其中包含数十亿条包含客户信息的记录。目标是获取随机样本并使用 R 查看分布。不幸的是,我们不能使用从 RStudio 到数据库的 JDBC/ODBC 连接。这是一个限制。所以我只能从雪花中提取提取物并导入 R。

困难在于我们有一个名为 CUSTOMER SEGMENT 的列,它有近 24 个唯一值。目标是从每个细分市场中获得一个代表显着比例的样本。我尝试了以下查询;

SELECT DISTINCT *
FROM test sample(10)

获取随机样本,其中每行有 10% 的概率被选中。但我没有从客户群的每个值中获取样本。我可以知道任何可以帮助根据客户细分进行分层的 sql 命令。提前致谢。

【问题讨论】:

    标签: sql r snowflake-cloud-data-platform


    【解决方案1】:

    对更多大小相同的分区进行抽样的另一种方法是使用循环抽样

    select t.*
    from (select t.*, 
                 row_number() over (partition by segment order by random()) as seqnum,
                 count(*) over () as cnt
          from test t
         ) t
    where seqnum <= 20;
    

    “20”表示每个段最多 20 行。

    这可以针对基于百分比的样本进行修改。是否有必要尚不清楚。

    【讨论】:

    • 感谢您的建议。我可以知道我们如何修改以获得每个细分的基于百分比的样本。抱歉,如果之前没有澄清。
    • 例如,如果段 A 有 30% 的数据,段 B 有 15%,那么我希望在随机样本中也有相同的表示。你能告诉我如何获得吗?
    • @Jayant 。 . .在这种情况下,随机样本应该做得足够好。您需要精确的分层吗?如果是这样,您的问题在这一点上并不清楚。
    • 很高兴知道可以对客户群进行分层。有没有办法在雪花中实现它?请指教
    【解决方案2】:

    以下是 Snowflake(或 SQL)中的分层示例,基于以下内容:

    https://en.wikipedia.org/wiki/Stratified_sampling

    这可以作为固定数字或百分比返回。

    这已被编译为单个查询,在我们的实现中,我们实际上预先创建了排序段列表 (W0) 作为临时表,而不是让相同的查询运行多次。

    SELECT 
        W1.Id, 
        W1.EmploymentStatus,    
        W1.Gender
        FROM 
            ( SELECT 
                ID, 
                Row_Number() OVER ( PARTITION BY COALESCE(Gender, '') || COALESCE(EmploymentStatus,'') ORDER BY random() ) as iInternalRank, 
                COALESCE(Gender, '') || COALESCE(EmploymentStatus,'') as sInternalGroupVal 
                FROM STAFF ) W0,
            STAFF W1    -- Linked back the original table (Inbound query)
        WHERE (
                SELECT 
                        MAX(case when W2.sInternalGroupVal = W3.sInternalGroupVal then W3.iGroupSegmentVolume else 0 end ) -- This is where the magic happens...
                        FROM ( 
                                SELECT 
                                    ID, 
                                    Row_Number() OVER ( PARTITION BY COALESCE(Gender, '') || COALESCE(EmploymentStatus,'') ORDER BY random() ) as iInternalRank, 
                                    COALESCE(Gender, '') || COALESCE(EmploymentStatus,'') as sInternalGroupVal 
                                    FROM STAFF ) W2, 
                            (SELECT 
                                sInternalGroupVal, 
                                COUNT(Id)*(40/iTotalPopulation::DOUBLE PRECISION) as iGroupSegmentVolume -- as a fixed volumne (40 Records)
                                --COUNT(Id)*((iTotalPopulation*(23/100.00))/iTotalPopulation::DOUBLE PRECISION) as iGroupSegmentVolume -- as a percentage (23% of overall population)
                                FROM (SELECT 
                                        ID, 
                                        Row_Number() OVER ( PARTITION BY COALESCE(Gender, '') || COALESCE(EmploymentStatus,'') ORDER BY random() ) as iInternalRank, 
                                        COALESCE(Gender, '') || COALESCE(EmploymentStatus,'') as sInternalGroupVal 
                                        FROM STAFF ), 
                                     (SELECT 
                                        COUNT(Id) as iTotalPopulation 
                                        FROM ( SELECT 
                                                ID, 
                                                Row_Number() OVER ( PARTITION BY COALESCE(Gender, '') || COALESCE(EmploymentStatus,'') ORDER BY random() ) as iInternalRank, 
                                                COALESCE(Gender, '') || COALESCE(EmploymentStatus,'') as sInternalGroupVal 
                                                FROM STAFF )
                                             ) W4
                                GROUP BY sInternalGroupVal, iTotalPopulation) W3
                        WHERE ((W2.sInternalGroupVal = W0.sInternalGroupVal)) AND ((W2.sInternalGroupVal = W3.sInternalGroupVal))
                ) >= iInternalRank 
                AND ((W1.Id = W0.Id));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-17
      • 1970-01-01
      相关资源
      最近更新 更多