使用 SAS SQL 计算单个类别中的唯一项目

问题描述 投票:0回答:1

我正在使用 SAS 解决数据分析问题,其中我有一个由属于不同类别的各种项目组成的数据集。每个项目可以属于多个类别,但我有兴趣计算与单个类别专门关联的项目数量。该数据集有两个主要列:category_code 和 item_id,位于名为 item_categories 的表中。

SAS SQL 用于连接到 Hadoop。

目标:

我的目标是根据category_code的第一个字符找出有多少商品严格属于一个类别(例如,代码为A123和A456的商品计入类别A)。属于多个类别的项目不应计入最终计数(例如属于类别 A123 和 B456)。我计算的是项目而不是它所属的类别。如果某件商品属于 A123 和 A456 类别,则计为 1。如果属于 C789 和 D567,则不算数,因为类别不同。

挑战:

提取category_code的第一个字符来识别该项目的类别。 每个项目都计数一次,即使它在同一类别下列出多次。 从最终计数中排除在多个类别下列出的项目。

我正在考虑一个可能需要 SAS SQL 中的多个步骤的解决方案,但我不确定如何构建查询:

首先,过滤掉只属于一个类别的项目。 然后,计算每个类别的这些项目。 我对 SQL 相当陌生,希望能得到有关如何解决此问题的指导,无论是通过单个复杂的查询还是一系列步骤。

sql sas aggregate-functions data-analysis
1个回答
0
投票

您将需要聚合一个聚合子查询。

这里有一些 SAS 代码,演示了思维的进展。 HADOOP 库引擎可能无法自动“在后台”将 SAS SQL 语句转换为 HADOOP 端 SQL 语句,在这种情况下,您需要向 HADOOP 专家询问这个问题。

示例:

* Create sample data containing some devoted items ;
* A devoted item is associated with a single category group ;
* A category group is the first letter of the categoryid value ;

* libname source hadoop ... ;

libname source "%sysfunc(pathname(WORK))";

data source.have (keep=itemid categoryid);
  call streaminit(20240218);
  do itemid = 1 to 2**13 ;
    do count = 1 to rand('integer',2,8);
      length categoryid $4;
      categoryid = cats(byte(rand('integer',26) + 64), rand('integer', 100,999));
      output;
    end ;
  end ;
run;

proc sql ;
  create table want1(label="Items in one category group") as
  select itemid
  , categoryid
  , substr(categoryid,1,1) as cgroup length =1
  , count(distinct categoryid) as item_cgroup_instance_count
  from source.have
  group by itemid
  having count(distinct substr(categoryid,1,1)) = 1
  order by cgroup, categoryid
  ;

  create table want2(label="Items in one category group") as
  select distinct itemid
  , substr(categoryid,1,1) as cgroup length=1
  from source.have
  group by itemid
  having count(distinct substr(categoryid,1,1)) = 1
  order by cgroup, itemid
  ;

  create table want3(label="Counts of items soley in one category group") as
  select 
    cgroup
  , count(distinct itemid) as devoted_item_count
  from  
    (   select
          itemid
        , substr(categoryid,1,1) as cgroup length=1
        from source.have
        group by itemid
        having count(distinct substr(categoryid,1,1)) = 1
    )
  group by
    cgroup 
  ;
quit;

© www.soinside.com 2019 - 2024. All rights reserved.