【问题标题】:SAS to SQL ConversionSAS 到 SQL 转换
【发布时间】:2016-05-31 11:59:55
【问题描述】:

作为第一次查看 SAS 代码的 SQL 开发人员,我很难理解提供给我的脚本的一部分。

请任何人解释以下内容的作用,或者如果可能的话,SQL 中的等价物?

* sum up the total 6 months value for customers with positive value and quantity of items;

proc summary data=value_last6_positive nway missing;
    var saleprice quantity;
    class Cardid  ;
        output out = value_last6_s (drop=_type_ _freq_)
            sum(saleprice)=saleprice
            sum(quantity)=quantity;
    run;

* rank them;

proc sort data=value_last6_s;
    by saleprice;
    run;

data count;
    set value_last6_s;
    count=1;
    run;

proc sort data=count;
    by count;
    run;

data count2;
    set count;
    by count;
    if first.count then rank=1;
    else rank+1;

    if rank=<544139 then decile=10;
    else if rank=<544139*2 then decile=9;
    else if rank=<544139*3 then decile=8;
    else if rank=<544139*4 then decile=7;
    else if rank=<544139*5 then decile=6;
    else if rank=<544139*6 then decile=5;
    else if rank=<544139*7 then decile=4;
    else if rank=<544139*8 then decile=3;
    else if rank=<544139*9 then decile=2;
    else decile=1;

run;

proc freq data=count2;
    table decile;
    run;

proc means data=count2;
var saleprice;
    class decile;
    run;

我已经构建了一个等效于value_last6_s 的临时表,它的结构为(CardID, SalePrice, Quantity),使用按CardID 分组的销售数据聚合。不太确定如何进行。提前致谢。

编辑:

我的第一个proc summary块的转换:

-- value_last6_s
SELECT  CardID,
        SUM(SalePrice) SalePrice,
        SUM(Quantity) Quantity
INTO    #value_last6_s
FROM    #value_last6_positive
GROUP BY CardID
ORDER BY SUM(SalePrice);

【问题讨论】:

  • 我不能确定,但​​我认为它总结了具有正值和物品数量的客户的 6 个月总价值......
  • @RQDQ 谢谢,非常有帮助。
  • 对不起 - 我无法抗拒。 :-) 到目前为止,您开发了哪些 SQL?
  • 我已经转换到 sn-p 的开头,包括 proc summary 块。我会把它包括在问题中。
  • 我不确定 SAS 代码是否正确或是否符合其应有的目的......关于功能要求的任何想法?

标签: sql sql-server sas


【解决方案1】:

第一步只是创建一个汇总表。虚拟变量 COUNT 作为常量添加,您可能不需要。需要排序以按 sum 或 SALEPRICE 的顺序获取值,以便在下一步创建 RANK 变量。

create table COUNT as
  select Cardid
      , sum(saleprice) as saleprice
      , sum(quantity) as quantity
  from value_last6_positive 
  group by Cardid
;

下一个数据步骤是生成一个 RANK 变量。你不能在 PROC SQL 中这样做,因为它不包括窗口函数。您应该能够使用 ROW_NUMBER() 函数来做到这一点。您可以用 CASE 语句替换 IF/THEN/ELSE 链。

create table COUNT2 as 
 select a.* 
      , row_number() over (order by saleprice) as RANK
      , case 
        when (rank<=544139) then 10
        when (rand<=544139*2) then 9
        ...
        else 1 end as DECILE
  from COUNT a
;

最后一步是使用新的 DECILE 变量创建报告。

所以频率报告。

select decile,count(*) as COUNT,COUNT/(count(*) over()) as PERCENT
  from count2
  group by 1
  order by 1
;

以及手段的总结。

select decile
     , count(saleprice) as N
     , mean(saleprice) as Mean
     , min(saleprice) as Min
     , max(saleprice) as Max
from count2
group by 1
order by 1
;

【讨论】:

  • 谢谢,但是您建议的改进不是与我的转换相同,而是添加了1 常量列吗?我正在转储到一个临时表中,这样我就可以逐步分解脚本的每个部分。这一点我真的没有问题,这是我不理解的恒定和十分位解释的后来排名。
  • 你打算使用什么风格的 SQL?它是否有一个 RANK() 或 ROW_NUMBER() 函数可以用来替换数据步骤用来计算排名的 sum 语句?
  • T-SQL,所以是的 - RANK() OVER...
  • 太好了,所以使用 RANK() 并按 saleprice 排序。使用 CASE 语句替换一系列 IF/THEN 语句。
  • SQL Server 中的 @Tom select into 确实创建了一个表(实际上,它在 SAS 中也可以)。
猜你喜欢
  • 2021-12-07
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-14
相关资源
最近更新 更多