如何在按总和分区的情况下编写没有窗口函数的 proc sql?
How to write proc sql without windowfunction over partition by sum?
我刚开始学习 SAS 并意识到 proc sql 不使用 window 函数。因为我对 sql 更放心,所以我想知道如何在 proc?window 中模拟求和函数?
想要的结果
select a.active, a.store_id, a.nbr, sum(nbr) over (partition by a.store_id)
from(select active, store_id, count(customer_id) as nbr from customer group by active, store_id) as a
;
active
store_id
nbr
sum
0
1
8
326
1
1
318
326
0
2
7
273
1
2
266
273
例如原始数据
select active, store_id, customer_id
from customer
limit 10;
active
store_id
customer_id
1
1
1
1
1
2
1
2
3
1
2
4
1
1
5
1
1
6
0
1
7
1
2
8
1
1
9
1
2
10
当前结果和查询
select a.active, a.store_id, a.nbr, sum(nbr)
from(select active, store_id, count(customer_id) as nbr from customer group by active, store_id) as a
group by a.active, a.store_id, a.nbr;
active
store_id
nbr
sum
0
1
8
8
1
1
318
318
0
2
7
7
1
2
266
266
您可以通过合并两个 sub-queries 在 proc sql
中做同样的事情:一个用于 active, store_id
的客户数量,另一个用于每个 store_id
的客户总数].
proc sql noprint;
create table want as
select t1.active
, t1.store_id
, t1.nbr
, t2.sum
from (select active
, store_id
, count(customer_id) as nbr
from have
group by store_id, active
) as t1
LEFT JOIN
(select store_id
, count(customer_id) as sum
from have
group by store_id
) as t2
ON t1.store_id = t2.store_id
;
quit;
如果您想以更 SASsy 的方式执行此操作,您可以 运行 proc means
并将包含您需要的所有内容的单个数据集的结果合并在一起。 proc means
将默认计算所有可能的变量组合。
proc means data=have noprint;
class store_id active;
ways 1 2;
output out=want_total
n(customer_id) = total
;
run;
data want;
merge want_total(where=(_TYPE_ = 3) rename=(total = nbr) )
want_total(where=(_TYPE_ = 2) rename=(total = sum) keep=_TYPE_ store_id total)
;
by store_id;
drop _:;
run;
或者,在 SQL 中:
proc sql;
create table want as
select t1.store_id
, t1.active
, t1.total as nbr
, t2.total as sum
from want_total as t1
LEFT JOIN
want_total as t2
ON t1.store_id = t2.store_id
where t1._TYPE_ = 3
AND t2._TYPE_ = 2
;
quit;
_TYPE_
变量标识分析级别。例如,_TYPE_ = 1
仅适用于 active
,_TYPE_ = 2
仅适用于 store_id
,_TYPE_ = 3
适用于所有组合。您可以在 proc means
:
的输出数据集中查看此内容
store_id active _TYPE_ _FREQ_ total
. 0 1 3 3
. 1 1 7 7
1 . 2 6 6
2 . 2 4 4
1 0 3 1 1
1 1 3 5 5
2 0 3 2 2
2 1 3 2 2
如果您想要更快的 high-performance 结果,请查看它的大兄弟 proc hpsummary
。
这就是 SAS 的酷炫之处:您可以通过 Pandas/proc python 在 PROC、SQL、DATA 步和 Python 之间跳转。您可以利用这些方法和思维过程中的每一种的独特优势来解决任意数量的数据工程和统计问题。
与某些 SQL 实现不同,当您包含既不是分组依据也不是汇总统计的变量时,SAS 很乐意 re-merge 将汇总统计返回到详细信息行。
让我们将您打印的数据转换为实际的数据集。让我们更改一个值,这样我们至少有两个 ACTIVE 值可以作为分组依据。
data have;
input active store_id customer_id;
cards;
1 1 1
1 1 2
1 2 3
1 2 4
1 1 5
1 1 6
0 1 7
1 2 8
1 1 9
1 2 10
;
现在我们可以按 ACTIVE 和 STORE_ID 统计记录,然后通过附加商店总数来生成报告。
proc sql;
select active,store_id,nbr,sum(nbr) as store_nbr
from (select active,store_id,count(*) as nbr
from have
group by active,store_id
)
group by store_id
;
结果打印输出:
active store_id nbr store_nbr
---------------------------------------
0 1 1 6
1 1 5 6
1 2 4 4
我刚开始学习 SAS 并意识到 proc sql 不使用 window 函数。因为我对 sql 更放心,所以我想知道如何在 proc?window 中模拟求和函数?
想要的结果
select a.active, a.store_id, a.nbr, sum(nbr) over (partition by a.store_id)
from(select active, store_id, count(customer_id) as nbr from customer group by active, store_id) as a
;
active | store_id | nbr | sum |
---|---|---|---|
0 | 1 | 8 | 326 |
1 | 1 | 318 | 326 |
0 | 2 | 7 | 273 |
1 | 2 | 266 | 273 |
例如原始数据
select active, store_id, customer_id
from customer
limit 10;
active | store_id | customer_id |
---|---|---|
1 | 1 | 1 |
1 | 1 | 2 |
1 | 2 | 3 |
1 | 2 | 4 |
1 | 1 | 5 |
1 | 1 | 6 |
0 | 1 | 7 |
1 | 2 | 8 |
1 | 1 | 9 |
1 | 2 | 10 |
当前结果和查询
select a.active, a.store_id, a.nbr, sum(nbr)
from(select active, store_id, count(customer_id) as nbr from customer group by active, store_id) as a
group by a.active, a.store_id, a.nbr;
active | store_id | nbr | sum |
---|---|---|---|
0 | 1 | 8 | 8 |
1 | 1 | 318 | 318 |
0 | 2 | 7 | 7 |
1 | 2 | 266 | 266 |
您可以通过合并两个 sub-queries 在 proc sql
中做同样的事情:一个用于 active, store_id
的客户数量,另一个用于每个 store_id
的客户总数].
proc sql noprint;
create table want as
select t1.active
, t1.store_id
, t1.nbr
, t2.sum
from (select active
, store_id
, count(customer_id) as nbr
from have
group by store_id, active
) as t1
LEFT JOIN
(select store_id
, count(customer_id) as sum
from have
group by store_id
) as t2
ON t1.store_id = t2.store_id
;
quit;
如果您想以更 SASsy 的方式执行此操作,您可以 运行 proc means
并将包含您需要的所有内容的单个数据集的结果合并在一起。 proc means
将默认计算所有可能的变量组合。
proc means data=have noprint;
class store_id active;
ways 1 2;
output out=want_total
n(customer_id) = total
;
run;
data want;
merge want_total(where=(_TYPE_ = 3) rename=(total = nbr) )
want_total(where=(_TYPE_ = 2) rename=(total = sum) keep=_TYPE_ store_id total)
;
by store_id;
drop _:;
run;
或者,在 SQL 中:
proc sql;
create table want as
select t1.store_id
, t1.active
, t1.total as nbr
, t2.total as sum
from want_total as t1
LEFT JOIN
want_total as t2
ON t1.store_id = t2.store_id
where t1._TYPE_ = 3
AND t2._TYPE_ = 2
;
quit;
_TYPE_
变量标识分析级别。例如,_TYPE_ = 1
仅适用于 active
,_TYPE_ = 2
仅适用于 store_id
,_TYPE_ = 3
适用于所有组合。您可以在 proc means
:
store_id active _TYPE_ _FREQ_ total
. 0 1 3 3
. 1 1 7 7
1 . 2 6 6
2 . 2 4 4
1 0 3 1 1
1 1 3 5 5
2 0 3 2 2
2 1 3 2 2
如果您想要更快的 high-performance 结果,请查看它的大兄弟 proc hpsummary
。
这就是 SAS 的酷炫之处:您可以通过 Pandas/proc python 在 PROC、SQL、DATA 步和 Python 之间跳转。您可以利用这些方法和思维过程中的每一种的独特优势来解决任意数量的数据工程和统计问题。
与某些 SQL 实现不同,当您包含既不是分组依据也不是汇总统计的变量时,SAS 很乐意 re-merge 将汇总统计返回到详细信息行。
让我们将您打印的数据转换为实际的数据集。让我们更改一个值,这样我们至少有两个 ACTIVE 值可以作为分组依据。
data have;
input active store_id customer_id;
cards;
1 1 1
1 1 2
1 2 3
1 2 4
1 1 5
1 1 6
0 1 7
1 2 8
1 1 9
1 2 10
;
现在我们可以按 ACTIVE 和 STORE_ID 统计记录,然后通过附加商店总数来生成报告。
proc sql;
select active,store_id,nbr,sum(nbr) as store_nbr
from (select active,store_id,count(*) as nbr
from have
group by active,store_id
)
group by store_id
;
结果打印输出:
active store_id nbr store_nbr
---------------------------------------
0 1 1 6
1 1 5 6
1 2 4 4