PostgreSQL 9.3:交叉表查询中的无效计数
PostgreSQL 9.3: Invalid count within crosstab query
我有以下数据要显示到数据透视表 table 中:
下面是table Employee
包含员工详细信息:
Employee_Number Employee_Role Group_Name
--------------------------------------------------------------------
EMP101 C# Developer Group_1
EMP102 ASP Developer Group_1
EMP103 SQL Developer Group_2
EMP104 PLSQL Developer Group_2
EMP101 Java Developer
EMP102 Web Developer
EMP101 DBA
EMP105 DBA
EMP106 SQL Developer Group_3
EMP107 Oracle Developer Group_3
EMP101 Oracle Developer Group_3
EMP108 JSP Group_4
EMP108 JS Group_5
EMP101 C# Developer Group_1
EMP101 C# Developer Group_1
EMP101 C# Developer Group_1
EMP101 C# Developer Group_1
我想将输出显示到枢轴 table 中,如下所示:
Employee_Number TotalRoles TotalGroups Available Others Group_1 Group_2 Group_3 Group_4 Group_5
------------------------------------------------------------------------------------------------------------------------------------------
EMP101 8 5 2 6 5 0 1 0 0
EMP102 2 5 1 1 1 0 0 0 0
EMP103 1 5 1 0 0 1 0 0 0
EMP104 1 5 1 0 0 1 0 0 0
.......
.......
我正在使用这个脚本:
SELECT * FROM crosstab(
$$SELECT grp.*, e.group_name
, CASE WHEN e.employee_number IS NULL THEN 0 ELSE 1 END AS val
FROM (
SELECT employee_number
, count(employee_role)::int AS total_roles
, (SELECT count(DISTINCT group_name)::int
FROM employee
WHERE group_name <> '') AS total_groups
, count(group_name <> '' OR NULL)::INT AS available
, count(group_name = '' OR NULL)::int AS others
FROM employee
GROUP BY employee_number
) grp
LEFT JOIN employee e ON e.employee_number = grp.employee_number
AND e.group_name <> ''
ORDER BY grp.employee_number, e.group_name$$
,$$VALUES ('Group_1'),('Group_2'),('Group_3'),('Group_4'),('Group_5')$$
) AS ct (employee_number text
, total_roles int
, total_groups int
, available int
, others int
, Group_1 int
, Group_2 int
, Group_3 int
, Group_4 int
, Group_5 int);
但是在 EMP101
的输出中出现错误 Available
它必须为 2 因为他是
在 group_1
和 group_3
中可用。但是为此得到一个错误。
我看到两个问题:
1) count(group_name <> '' OR NULL)
将计算每个非空白的 group_name 的出现次数,即当有重复时,您将重复计算值。
2) 您没有对组计数进行分组 - 交叉表函数不会为您聚合,因此当一名员工多次属于一个组时,您会得到不正确的组计数。下面的查询有不同的计算可用方式,并对计数进行分组。你会得到缺失值的空值,但你之前得到它们:-)
SELECT * FROM crosstab(
$$SELECT grp.*, e.group_name
, val
FROM (
SELECT employee_number
, count(employee_role)::int AS total_roles
, (SELECT count(DISTINCT group_name)::int
FROM employee
WHERE group_name <> '') AS total_groups
, (count(distinct group_name) - count(distinct group_name = '' OR NULL))::int AS available
, count(group_name = '' OR NULL)::int AS others
FROM employee
GROUP BY employee_number
) grp
LEFT JOIN
(select employee_number,group_name,count(*) as val from employee group by employee_number,group_name) e
ON e.employee_number = grp.employee_number
ORDER BY grp.employee_number, e.group_name$$
,$$VALUES ('Group_1'),('Group_2'),('Group_3'),('Group_4'),('Group_5')$$
) AS ct (employee_number text
, total_roles int
, total_groups int
, available int
, others int
, Group_1 int
, Group_2 int
, Group_3 int
, Group_4 int
, Group_5 int);
我有以下数据要显示到数据透视表 table 中:
下面是table Employee
包含员工详细信息:
Employee_Number Employee_Role Group_Name
--------------------------------------------------------------------
EMP101 C# Developer Group_1
EMP102 ASP Developer Group_1
EMP103 SQL Developer Group_2
EMP104 PLSQL Developer Group_2
EMP101 Java Developer
EMP102 Web Developer
EMP101 DBA
EMP105 DBA
EMP106 SQL Developer Group_3
EMP107 Oracle Developer Group_3
EMP101 Oracle Developer Group_3
EMP108 JSP Group_4
EMP108 JS Group_5
EMP101 C# Developer Group_1
EMP101 C# Developer Group_1
EMP101 C# Developer Group_1
EMP101 C# Developer Group_1
我想将输出显示到枢轴 table 中,如下所示:
Employee_Number TotalRoles TotalGroups Available Others Group_1 Group_2 Group_3 Group_4 Group_5
------------------------------------------------------------------------------------------------------------------------------------------
EMP101 8 5 2 6 5 0 1 0 0
EMP102 2 5 1 1 1 0 0 0 0
EMP103 1 5 1 0 0 1 0 0 0
EMP104 1 5 1 0 0 1 0 0 0
.......
.......
我正在使用这个脚本:
SELECT * FROM crosstab(
$$SELECT grp.*, e.group_name
, CASE WHEN e.employee_number IS NULL THEN 0 ELSE 1 END AS val
FROM (
SELECT employee_number
, count(employee_role)::int AS total_roles
, (SELECT count(DISTINCT group_name)::int
FROM employee
WHERE group_name <> '') AS total_groups
, count(group_name <> '' OR NULL)::INT AS available
, count(group_name = '' OR NULL)::int AS others
FROM employee
GROUP BY employee_number
) grp
LEFT JOIN employee e ON e.employee_number = grp.employee_number
AND e.group_name <> ''
ORDER BY grp.employee_number, e.group_name$$
,$$VALUES ('Group_1'),('Group_2'),('Group_3'),('Group_4'),('Group_5')$$
) AS ct (employee_number text
, total_roles int
, total_groups int
, available int
, others int
, Group_1 int
, Group_2 int
, Group_3 int
, Group_4 int
, Group_5 int);
但是在 EMP101
的输出中出现错误 Available
它必须为 2 因为他是
在 group_1
和 group_3
中可用。但是为此得到一个错误。
我看到两个问题:
1) count(group_name <> '' OR NULL)
将计算每个非空白的 group_name 的出现次数,即当有重复时,您将重复计算值。
2) 您没有对组计数进行分组 - 交叉表函数不会为您聚合,因此当一名员工多次属于一个组时,您会得到不正确的组计数。下面的查询有不同的计算可用方式,并对计数进行分组。你会得到缺失值的空值,但你之前得到它们:-)
SELECT * FROM crosstab(
$$SELECT grp.*, e.group_name
, val
FROM (
SELECT employee_number
, count(employee_role)::int AS total_roles
, (SELECT count(DISTINCT group_name)::int
FROM employee
WHERE group_name <> '') AS total_groups
, (count(distinct group_name) - count(distinct group_name = '' OR NULL))::int AS available
, count(group_name = '' OR NULL)::int AS others
FROM employee
GROUP BY employee_number
) grp
LEFT JOIN
(select employee_number,group_name,count(*) as val from employee group by employee_number,group_name) e
ON e.employee_number = grp.employee_number
ORDER BY grp.employee_number, e.group_name$$
,$$VALUES ('Group_1'),('Group_2'),('Group_3'),('Group_4'),('Group_5')$$
) AS ct (employee_number text
, total_roles int
, total_groups int
, available int
, others int
, Group_1 int
, Group_2 int
, Group_3 int
, Group_4 int
, Group_5 int);