注意:查询需要将汇总统计信息与 SAS 中的原始数据消息重新合并

0 sql sas proc-sql

当我运行下面的 proc sql sas 代码时,我的程序继续运行并且不会停止。该注释说查询需要将汇总统计信息与 SAS 中的原始数据消息重新合并\n有人知道为什么它继续这样做吗?

\n

这是我的代码:

\n
proc sql;\ncreate table PUBLIC.ILK_ODENEN_SAYI as\nSELECT* FROM\n    (select datepart(i1.UpdatedDate) as date FORMAT DATE9.,\n    COUNT(*) AS ILK_ODENEN_SAYI,\n    sum(InvoiceAmount) as ILK_ODENEN_MIKTAR\n    from fatura.ASKIDAFATURA_INVOICES as i1\n    where i1.Status=2 and i1.CorparateIdentity in (1,2) and\n    (select count(*) \n    from fatura.ASKIDAFATURA_INVOICES  as i2\n    where i2.Status=2 and i2.CorparateIdentity in (1,2) AND \n    i1.CitizenIdentity=i2.CitizenIdentity and i2.UpdatedDate < i1.UpdatedDate\n    )=0\n    /*GROUP BY i1.UpdatedDate*/\n    )\xc2\xa0tt;\nquit;\n
Run Code Online (Sandbox Code Playgroud)\n

感谢您的意见!

\n

Stu*_*ski 5

您的查询是i1.UpdatedDate根据您创建的计算日期列进行分组的il1.UpdatedDate。要删除此消息,请改为分组依据calculated date。你的查询是要求datepart(il1.UpdatedDate),而不是il1.UpdatedDate

换句话说,如果UpdatedDate时间戳未对齐(例如01JAN2020:00:0002JAN2020:00:00等),则您的行可能不会折叠为单个日期。

有关此消息的详细信息,请参阅SAS 使用说明 4308

细节

这实际上是 SAS 的一个非常巧妙的功能,可以节省大量编码时间。让我们用一个非常简单的例子来探讨为什么会出现此消息。假设我们要计算 sashelp.cars 中每个品牌的平均马力:

proc sql;
    create table avg_make_horsepower as
        select make, mean(horsepower) as avg_horsepower
        from sashelp.cars
        group by make
    ;
quit;
Run Code Online (Sandbox Code Playgroud)

我们得到这张表:

Make        avg_horsepower
Acura       239.28571429
Audi        250.78947368
BMW         241.45
Buick       214.44444444
Cadillac    298.125
...
Run Code Online (Sandbox Code Playgroud)

现在假设我们想要将每个型号的马力与其制造商的平均马力进行比较。这意味着我们需要引入两列,modelhorsepower。但是,我们不想按makemodel、 和horsepower进行分组。在其他类型的 SQL 中,您可以使用子查询和连接来计算:

proc sql;
    create table avg_horsepower_make_vs_model as
        select t1.make
             , t1.model
             , t1.horsepower
             , t2.avg_make_horsepower
        from sashelp.cars as t1
        LEFT JOIN
             (select make, mean(horsepower) as avg_make_horsepower
              from sashelp.cars
              group by make
             ) as t2
        ON t1.make = t2.make
    ;
quit;
Run Code Online (Sandbox Code Playgroud)

这给了我们这个:

Make    Model            Horsepower    avg_make_horsepower
Acura   MDX              265           239.28571429
Acura   RSX Type S 2dr   200           239.28571429
Acura   TSX 4dr          200           239.28571429
Acura   TL 4dr           270           239.28571429
Acura   3.5 RL 4dr       225           239.28571429
...
Run Code Online (Sandbox Code Playgroud)

但在 SAS 中,您不必这样做。您所需要做的就是指定最终表中所需的列并指定要分组的依据。我们可以通过此查询得到完全相同的结果:

proc sql;
    create table avg_horsepower_make_vs_model as
        select make
             , model
             , horsepower
             , mean(horsepower) as avg_make_horsepower
        from sashelp.cars 
        group by make
    ;
quit;
Run Code Online (Sandbox Code Playgroud)

您将在日志中看到此消息:

NOTE: The query requires remerging summary statistics back with the original data.
Run Code Online (Sandbox Code Playgroud)

SAS 会在后台自动为您执行此连接。它通过 计算马力平均值make,然后用、、 和将其连接make回表中。换句话说,它做了两个步骤:makemodelhorsepower

  1. 计算horsepower平均值make
  2. 查询make, model,horsepower并将其与 (1) 连接make

如果您要创建计算列,则同样的功能也适用。例如:

proc sql;
    create table foo as
        select datepart(timestamp) as date
             , count(*) as total
        from have
        group by timestamp
    ;
quit;
Run Code Online (Sandbox Code Playgroud)

时间戳不是查询结果的列。SAS 将 (1)count(*)通过进行计算timestamp,然后 (2) 将其与 合并回来datepart(timestamp)。要解决此问题,请改为分组calculated date

proc sql;
    create table foo as
        select datepart(timestamp) as date
             , count(*) as total
        from have
        group by calculated date
    ;
quit;
Run Code Online (Sandbox Code Playgroud)

calculated datedate是一个快捷方式,让 SAS 知道您想要按查询中的计算列进行分组。您不需要datepart(timestamp)group by.