gpt4 book ai didi

sql - SAS/SQL - 使用自定义函数创建 SELECT 语句

转载 作者:行者123 更新时间:2023-12-04 20:56:47 26 4
gpt4 key购买 nike

更新

鉴于这种使用 INTNX 的新方法,我认为我可以使用循环来进一步简化事情。如果我制作一个数组怎么办:

data;
array period [4] $ var1-var4 ('day' 'week' 'month' 'year');
run;

然后尝试为每个元素创建一个循环:

%MACRO sqlloop;
proc sql;
%DO k = 1 %TO dim(period); /* in case i decide to drop something from array later */
%LET bucket = &period(k)
CREATE TABLE output.t_&bucket AS (
SELECT INTX( "&bucket.", date_field, O, 'E') AS test FROM table);
%END
quit;
%MEND
%sqlloop

这不太行,但它捕获了我想要的想法。它可以只对 INTX 中的每个值运行查询。这有意义吗?


我有几个先前的问题正在合并为一个。我从其他人那里得到了一些非常有用的建议,希望这可以将它们联系在一起。

我有以下函数创建一个动态字符串来填充 SAS proc sql; 代码块中的 SELECT 语句:

proc fcmp outlib = output.funcs.test;
function sqlSelectByDateRange(interval $, date_field $) $;
day = date_field||" AS day, ";
week = "WEEK("||date_field||") AS week, ";
month = "MONTH("||date_field||") AS month, ";
year = "YEAR("||date_field||") AS year, ";

IF interval = "week" THEN
do;
day = '';
end;
IF interval = "month" THEN
do;
day = '';
week = '';
end;
IF interval = "year" THEN
do;
day = '';
week = '';
month = '';
end;
where_string = day||week||month||year;
return(where_string);
endsub;
quit;

我已经验证这会创建我想要的字符串类型:

data _null_;
q = sqlSelectByDateRange('month', 'myDateColumn');
put q =;
run;

这会产生:

q=MONTH(myDateColumn) AS month, YEAR(myDateColumn) AS year,

这正是我想要的 SQL 字符串。根据之前的问题,我认为我需要在 MACRO 中调用此函数。然后我想要这样的东西:

%MACRO sqlSelectByDateRange(interval, date_field);
/* Code I can't figure out */
%MEND

PROC SQL;
CREATE TABLE output.t AS (
SELECT
%sqlSelectByDateRange('month', 'myDateColumn')
FROM
output.myTable
);
QUIT;

我无法理解如何让代码调用此宏并将其解释为 SQL SELECT 字符串的一部分。我已经在其他答案中尝试了一些前面的例子,但我就是无法让它发挥作用。我希望这个更具体的问题可以帮助我填补这个缺失的步骤,以便我将来可以学习如何做。

最佳答案

两件事:

首先,您应该能够使用 %SYSFUNC调用您的自定义函数。

%MACRO sqlSelectByDateRange(interval, date_field);
%SYSFUNC( sqlSelectByDateRange(&interval., &date_field.) )
%MEND;

请注意,通过 SYSFUNC 调用函数时不应使用引号。另外,you cannot use SYSFUNC with FCMP functions until SAS 9.2 .如果您使用的是早期版本,这将不起作用。

其次,您的 select 子句中有一个尾随逗号。您可能需要一个虚拟列,如下所示:

PROC SQL;
CREATE TABLE output.t AS (
SELECT
%sqlSelectByDateRange('month', 'myDateColumn')
0 AS dummy
FROM
output.myTable
);
QUIT;

(注意 dummy 之前没有逗号,因为逗号已经嵌入到您的宏中。)


更新

我阅读了您对另一个答案的评论:

I also need to be able to do it for different date ranges and on a very ad-hoc basis, so it's something where I want to say "by month from june to december" or "weekly for two years" etc when someone makes a request.

我想我可以推荐一种更简单的方法来完成您正在做的事情。首先,我将创建一个包含日期和值的非常简单的数据集。日期分布在不同的日、周、月和年中:

DATA Work.Accounts;

Format Opened yymmdd10.
Value dollar14.2
;

INPUT Opened yymmdd10.
Value dollar14.2
;

DATALINES;
2012-12-31 $90,000.00
2013-01-01 $100,000.00
2013-01-02 $200,000.00
2013-01-03 $150,000.00
2013-01-15 $250,000.00
2013-02-10 $120,000.00
2013-02-14 $230,000.00
2013-03-01 $900,000.00
RUN;

您现在可以使用 INTNX 函数创建第三列以将“Opened”列四舍五入到某个时间段,例如 'WEEK''MONTH',或 'YEAR'(参见 complete list):

%LET Period = YEAR;

PROC SQL NOPRINT;

CREATE TABLE Work.PeriodSummary AS
SELECT INTNX( "&Period.", Opened, 0, 'E' ) AS Period_End FORMAT=yymmdd10.
, SUM( Value ) AS TotalValue FORMAT=dollar14.
FROM Work.Accounts
GROUP BY Period_End
;

QUIT;

WEEK 的输出:

Period_End   TotalValue
2013-01-05 $540,000
2013-01-19 $250,000
2013-02-16 $350,000
2013-03-02 $900,000

MONTH 的输出:

Period_End   TotalValue
2012-12-31 $90,000
2013-01-31 $700,000
2013-02-28 $350,000
2013-03-31 $900,000

YEAR 的输出:

Period_End   TotalValue
2012-12-31 $90,000
2013-12-31 $1,950,000

关于sql - SAS/SQL - 使用自定义函数创建 SELECT 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17658864/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com