【问题标题】:SAS Error: Subquery evaluated to more than one rowSAS 错误:子查询评估为多于一行
【发布时间】:2020-03-19 20:01:41
【问题描述】:

我收到消息“错误:子查询评估为不止一行。我在下面发布了工作代码。我想知道如何解决这个错误。提前谢谢你。

data have;
input Subject Type :$12. Date &:anydtdte. Procedure :$12. Measurement;
format date yymmdd10.;
datalines;

500   Initial    15 AUG 2017      Invasive     20 
500   Initial    18 SEPT 2018     Surface      35 
500   Followup   12 SEPT 2018     Invasive     54 
428   Followup    2 JUL 2019      Outer        29 
765   Seventh     3 JUL 2018      Other        13 
500   Followup    6 NOV 2018      Surface      98 
428   Initial     23 FEB 2018     Outer        10 
765   Initial     20 AUG 2019     Other        19 
610   Third       21 AUG 2018     Invasive     66 
610   Initial     27 Mar 2018     Invasive     17 
999   Dummy       17 mar 2020     Some          1
999   Dummy       18 mar 2020     Some          2
999   Dummy       19 mar 2020     Some          3
;

proc sql;
create table want as
select *,
    (select max(measurement) 
     from have 
     where subject=a.subject and type=a.type and procedure=a.procedure 
     having date = max(date)) / min(measurement) as ratio
from have as a
group by subject, type, procedure
order by subject, date;
quit;

【问题讨论】:

  • 您要参考哪个版本的 DATE 和 MEASUREMENT?
  • 每个主题应该有一个比率值,还是每个主题/类型/程序一个值?假设我是brickskull,你能说明在口粮计算中应该使用哪些具体值吗?数据总是可以排序的,例子数据乱序是不是有原因。
  • 您期望输入的答案是什么?
  • 这无疑是单个 SQL 查询中令人印象深刻的问题列表。我已经发现了 5 个问题,甚至不知道您想要实现什么。
  • 我在运行您的代码时没有收到该错误。我只是收到注释“注意:查询需要将汇总统计信息与原始数据重新合并。” (Windows 上的 SAS 9.4)正如其他 cmets 所问的那样:您想在概念上实现什么?从您的代码看来您想计算 latest measurement 与组观察到的最小 measurement 之间的比率,并将该信息作为新列添加到您的 original 数据集...(?)

标签: select sas subquery syntax-error proc-sql


【解决方案1】:

当您在您在现实生活中使用的完整数据集上运行查询时收到消息“错误:子查询评估为多行”的原因是因为您有max(date) 值重复分组变量的至少一个组合(即我们假设中的 subjecttype 根据上述 cmets)。

事实上,对于每个分组变量组合,您在子查询 having date = max(date) 中应用的条件将返回与 date 等于 max(date) 的记录一样多的行。

我的建议是确保您的输入数据集每个 subjecttypedate 中只有一条记录。(*)

如果这样做,您的查询将正常工作(尽管您可以在子查询中将max(measurement) 替换为简单的measurement,因为每个组只有一条记录具有date = max(date))。

所以,最终的查询是:

PROC SQL;
    create table want as
    select a.*,
        (select measurement as measurement_last_date
         from have
         where subject = a.subject and type = a.type 
         having date = max(date)) / min(a.measurement) as ratio
    from have as a
    group by subject, type
    order by subject, type, date;
QUIT;

如果您在输入数据集中运行此代码(我已将记录 12 的 measurement 的值从 2 更改为 0.2,以使结果更加清晰),您将得到:

Obs    Subject    Type              Date    Procedure    Measurement     ratio
 1      428      Followup    2019-07-02    Outer            29.0        1.0000
 2      428      Initial     2018-02-23    Outer            10.0        1.0000
 3      500      Followup    2018-09-12    Invasive         54.0        1.8148
 4      500      Followup    2018-11-06    Surface          98.0        1.8148
 5      500      Initial     2017-08-15    Invasive         20.0        1.7500
 6      500      Initial     2018-09-18    Surface          35.0        1.7500
 7      610      Initial     2018-03-27    Invasive         17.0        1.0000
 8      610      Third       2018-08-21    Invasive         66.0        1.0000
 9      765      Initial     2019-08-20    Other            19.0        1.0000
10      765      Seventh     2018-07-03    Other            13.0        1.0000
11      999      Dummy       2020-03-17    Some              1.0       15.0000
12      999      Dummy       2020-03-18    Some              0.2       15.0000
13      999      Dummy       2020-03-19    Some              3.0       15.0000

(*) 这个查询正常工作的实际条件是每个subjecttype“max(date) over subject-type”都有一条记录,尽管这种情况(在max(date) 上保证唯一性,而不是在每个 date 每组上保证唯一性)在实际业务案例中不太可能发生。

【讨论】:

  • 您好,感谢您的回复!如何在不更改数据集的情况下使数据集每个主题、类型和日期只有一条记录?
  • 好吧,如果不修改数据集,就不可能让您的数据集每个主题、类型、日期只有一条记录...这在逻辑上是不可能的。您应该分析业务问题并找出最明智的方法来聚合其他列中包含的信息,以实现每个主题、类型、日期的一条记录。假设您最重要的信息是measurement,一种方法是将聚合函数应用于该列,如平均值或总和,同时按subject, type, date 分组。 (另一方面,如果您认为它回答了您的问题,请随时接受我的回答,谢谢!)
  • 作为新的贡献者,如果您认为收到的答案对您的问题有帮助,我恳请您指出该怎么做:stackoverflow.com/help/someone-answers 您没有义务这样做,但它帮助社区。谢谢! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-10
  • 1970-01-01
  • 2014-12-30
  • 2020-05-15
  • 1970-01-01
相关资源
最近更新 更多