首页 > 解决方案 > 夏皮罗-威尔克测试

问题描述

在 PL/SQL 中,我想计算我选择的数据的Shapiro-Wilk值。

显然,函数 DBMS_STAT_FUNCS.normal_dist_fit 能够做到这一点,但它需要一个表名作为参数,而不是选择的结果。

我正在使用的值是数字,在许多内部连接之后选择。这是我的典型测试值示例(每个值只有一个数字,为​​了便于阅读,我在这里只对它们进行了重新组合):

-1,1168954372406006 -1,0339429378509521 -1,0194162130355835 -,9636680483818054 -,9536418914794922 -,9111286401748657 -,851311981678009 -,8325300216674805 -,8051750063896179 -,738100528717041 -,7174761295318604 -,6651638746261597 -,663613498210907 -,6444216966629028 -,6267942190170288 -,6180349588394165 -,6027824282646179 -,5999149084091187 -,5908389687538147 -,590206503868103 -,5845686793327332 -,5831132531166077 -,5629676580429077 -,5572993159294128 -,5481508374214172 -,5445670485496521 -,5093156099319458 -,49224603176116943 -,47992199659347534 -,4758097231388092 -,4546264410018921 -,38799363374710083 -,3803306519985199 -,3734436631202698 -,36905646324157715 -,27978914976119995 -,2048187553882599 -,16521787643432617

标签: sqloracleplsql

解决方案


您可以根据您的查询创建一个视图。(“视图”仅表示命名查询,其代码被保存以备将来使用;视图不包含任何数据。因此,即使您不想在生产服务器上创建表,也可以创建视图。)然后您可以在调用拟合优度过程中使用此视图。

首先让我们澄清一下,这DBMS_STAT_FUNCS.normal_dist_fit不是一个函数,正如包名称中的 FUNCS 所建议的那样(正如你在帖子中所说的那样),而是一个过程。事实上,那个包里的所有子程序都是程序!

包的文档是错误的。

https://docs.oracle.com/database/121/ARPLS/d_stat_f.htm#ARPLS68476

它说的meanstddevIN参数。他们不是; 它们是OUT参数。目前尚不清楚为什么在此过程中需要它们(有单独的函数来计算它们),但同样,这不是我的选择,它是 Oracle 的。

normal_dist_fit这是在物理表上使用过程的简短示例(来自不同的模式:标准HR模式)。请注意,我必须具有允许我从架构select any table中的表中进行选择的特权或其他一些特权。HR(我没有以 身份登录HR,而是以另一个用户身份登录MATHGUY。)

declare
  mn number;
  sd number;
  sw number;
begin
  dbms_stat_funcs.normal_dist_fit('HR', 'EMPLOYEES', 'SALARY',
                                  'SHAPIRO_WILKS', mn, sd, sw);
end;
/

W value : .8739562109117848523112862359519603805821

PL/SQL procedure successfully completed.

(请注意,Shapiro-Wilk 测试的参数是'SHAAPIRO_WILKS',末尾有一个S;也许甲骨文对此有充分的理由,尽管我对此表示怀疑。)

现在,假设在我的模式中我有这个查询,它产生一列数字:

select salary * (1 + nvl(commission_pct, 0)) as total_compensation 
from   hr.employees
;

这会计算总薪酬,包括佣金(对于那些有佣金的员工;NVL需要致电,因为对于没有佣金的员工,百分比显示为 NULL 而不是零)。

我将根据这个查询创建一个视图……但我需要拥有所需的权限,而且只是有点复杂。

到目前为止,我假设我可以从HR模式中的表中进行选择;的确,我有SELECT ANY TABLE特权。但是,就我而言,我通过角色获得了这种特权。可以选择,但不能基于它创建视图SELECT。要创建一个视图,我必须直接授予我SELECT ANY TABLE(或者一个更弱的授权:从那个表中专门选择,或者可能进一步限制为我需要的两列)直接授予我,而不是通过角色。这是您需要与您的 DBA 讨论的问题;这是您已经拥有的特权(否则您现有的SELECT将不起作用),但如果您通过角色拥有它,现在您需要将其直接授予您。而且,当然,您必须拥有CREATE VIEW特权。

好的,假设您拥有正确的权限。然后你可以这样做:

创建视图

create or replace view my_emp(total_comp) 
as 
    select salary*(1 + nvl(commission_pct, 0)) from hr.employees;

调用过程

declare
  mn number;
  sd number;
  sw number;
begin
  dbms_stat_funcs.normal_dist_fit('MATHGUY', 'MY_EMP', 'TOTAL_COMP', 
                                  'SHAPIRO_WILKS', mn, sd, sw);
end;
/

W value : .8852586932906502861798487994791857389177

推荐阅读