Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL计数表达式_Sql_Count_Sas - Fatal编程技术网

SQL计数表达式

SQL计数表达式,sql,count,sas,Sql,Count,Sas,我正在尝试创建一个表来统计各个办公室每个职位的出现次数 因此,如果我的数据如下: Office Position A Manager A Supervisor A Entry Level A Entry Level B Manager B Entry Level 我希望我的代码返回: Office Managers Supervisors EntryLevel A 1

我正在尝试创建一个表来统计各个办公室每个职位的出现次数

因此,如果我的数据如下:

Office Position
A      Manager
A      Supervisor
A      Entry Level
A      Entry Level
B      Manager
B      Entry Level
我希望我的代码返回:

Office    Managers    Supervisors     EntryLevel
A            1             1              2
B            1             0              1
我的代码在下面。问题在于,此代码统计事件总数,而不是每个办公室的唯一计数。结果如下

A   2   1   3
B   2   1   3

CREATE TABLE OfficeTest AS
SELECT DISTINCT Office,
(Select COUNT(Position) FROM OfficeData  WHERE Make_Name = 'Manager') as Managers, 
(Select COUNT(Position) FROM OfficeData  WHERE Make_Name = 'Supervisor') as Supervisors,
(Select COUNT(Position) FROM OfficeData  WHERE Make_Name = 'Entry Level') as EntryLevel

FROM OfficeData 
GROUP BY Office;

关于如何解决这个问题有什么想法吗?

我能想到的最简单的方法是:

SELECT Office,
       COUNT(CASE WHEN Make_Name = 'Manager' THEN Position END) AS Managers,
       COUNT(CASE WHEN Make_Name = 'Supervisor' THEN Position END) AS Supervisors,
       COUNT(CASE WHEN Make_Name = 'Entry Level' THEN Position END) AS EntryLevel
FROM OfficeData
GROUP BY Office
计数
忽略
缺失的
值;如果
位置
不是
CASE
子句中指定的位置,它将返回一个
缺失的
值,并且不会被计算。这样,每个案例只考虑比较的
位置的值


如评论中所述,另一种选择是旋转表格。SAS等效程序是
转置
程序。我没有SAS系统来创建和测试使用它的查询,但如果您想签出它。

SUM with case语句应该可以解决这个问题。下面是一个参考代码

proc sql;
create table result as 
select age
      , sum(case sex when 'F' then 1 else 0 end) as Female
      , sum(case sex when 'M' then 1 else 0 end) as Male
from sashelp.class
group by age;
quit;
proc print data=result;run;

为了稍微消除Danny的评论,总和代码如下所示:

proc sql;
    CREATE TABLE want AS
    SELECT office,
    SUM( (position='Manager') ) as Managers,
    SUM( (position='Supervisor') ) as Supervisors,
    SUM( (position='Entry Level') ) as EntryLevel
FROM OfficeData
GROUP BY office
;quit;

(position='Manager')
位解析为0或1,具体取决于当前记录是否为真。我觉得SUM版本更简洁易读,但两者都适合你的情况。此外,它还可以轻松扩展到多个标准,如
(position='Manager')*(sex='F')
以仅统计女性经理。

您使用的是什么SQL数据库产品?(如SQL Server、Oracle、MySQL等)。对于任何支持它的产品来说,这实际上是
PIVOT
的典型用法。我正在SAS中使用Proc-SQL函数。下面的计数案例正是我想要的。如果您使用SAS,为什么不使用SAS摘要过程,如
PROC tablate
?这可能只是个人偏好,但我通常进行求和而不是计数,并让案例返回1或0,这取决于Make_Name是否与该列的值匹配。我认为逻辑更为不言而喻。既然你提到了它,那么写两种方式并查看执行计划会很有趣。这很完美。谢谢我正在使用SAS,因此Else Null部分不起作用。我认为这不会影响我。我编辑了答案。不知道SAS没有
NULL
缺少值。但是,从技术上讲,不需要
ELSE NULL/MISSING
部分,因为如果不满足
CASE
条件,默认情况下会返回
MISSING
。我个人更喜欢
count
;也许是因为我的数学背景。我倾向于对
else
进行明确说明,只是为了清楚起见,所以它甚至不保存任何字符。我考虑过让case表达式的计算结果类似于
'CountMe'
,而不是一个数字。最后,我认为这对任何有能力的人来说都是直截了当的。