Oracle XE,根据一列统计显示不同的行组合
Oracle XE, count and display different combinations of rows based on one column
需要有关复杂查询的帮助。这是我的 table:
的摘录
USERID SERVICE
1 A
1 B
2 A
3 A
3 B
4 A
4 C
5 A
6 A
7 A
7 B
好的,我希望查询 return 并根据 SERVICE 列显示我的 table 中存在的所有可能组合及其各自的计数。例如第一个用户有 A 和 B 服务,这是一个出现一次的组合。下一个用户只有服务 A,这是又一次出现的组合。第三个用户有服务 A 和 B,这已经发生过一次,现在这个组合的计数是 2,等等。所以我基于这个特定输入的输出将是一个 table 像这样:
A AB AC ABC B BC
3 3 1 0 0 0
所以再澄清一点,如果有 3 个服务,那么就有 3 个!可能的组合; 3x2x1=6,分别是A、B、C、AB、AC、BC、ABC。我的 table 应该包含分配了这些服务组合的用户数。
我尝试使用此查询构建矩阵,然后使用 CUBE 函数获取所有计数:
select service_A, service_B, service_C from
(select USERID,
max(case when SERVICE =A then 1 else null end) service_A,
max(case when SERVICE =B then 1 else null end) service_B,
max(case when SERVICE =C then 1 else null end) service_C
from SOME_TABLE)
group by CUBE(service_A, service_B,service_C);
但我没有得到所有组合的计数。我只需要发生的组合,因此计数 0 不是必需的,但可以显示它们。谢谢
不要将其输出为动态列(不使用 PL/SQL 和动态 SQL 很难做到)而是将其输出为行(如果您有前端,那么它通常可以比 oracle 更容易地将行转换为列):
Oracle 设置:
CREATE TABLE some_table ( USERID, SERVICE ) AS
SELECT 1, 'A' FROM DUAL UNION ALL
SELECT 1, 'B' FROM DUAL UNION ALL
SELECT 2, 'A' FROM DUAL UNION ALL
SELECT 3, 'A' FROM DUAL UNION ALL
SELECT 3, 'B' FROM DUAL UNION ALL
SELECT 4, 'A' FROM DUAL UNION ALL
SELECT 4, 'C' FROM DUAL UNION ALL
SELECT 5, 'A' FROM DUAL UNION ALL
SELECT 6, 'A' FROM DUAL UNION ALL
SELECT 7, 'A' FROM DUAL UNION ALL
SELECT 7, 'B' FROM DUAL;
查询:
SELECT service,
COUNT( userid ) AS num_users
FROM (
SELECT userid,
LISTAGG( service ) WITHIN GROUP ( ORDER BY service ) AS service
FROM some_table
GROUP BY userid
)
GROUP BY service;
输出:
SERVICE NUM_USERS
------- ----------
AC 1
A 3
AB 3
PL/SQL 用于动态列:
VARIABLE cur REFCURSOR;
DECLARE
TYPE string_table IS TABLE OF VARCHAR2(4000);
TYPE int_table IS TABLE OF INT;
t_services string_table;
t_counts int_table;
p_sql CLOB;
BEGIN
SELECT service,
COUNT( userid ) AS num_users
BULK COLLECT INTO t_services, t_counts
FROM (
SELECT userid,
CAST( LISTAGG( service ) WITHIN GROUP ( ORDER BY service ) AS VARCHAR2(2) ) AS service
FROM some_table
GROUP BY userid
)
GROUP BY service;
p_sql := EMPTY_CLOB() || 'SELECT ';
p_sql := p_sql || t_counts(1) || ' AS "' || t_services(1) || '"';
FOR i IN 2 .. t_services.COUNT LOOP
p_sql := p_sql || ', ' || t_counts(i) || ' AS "' || t_services(i) || '"';
END LOOP;
p_sql := p_sql || ' FROM DUAL';
OPEN :cur FOR p_sql;
END;
/
PRINT cur;
输出:
AC A AB
--- --- ---
1 3 3
需要有关复杂查询的帮助。这是我的 table:
的摘录USERID SERVICE
1 A
1 B
2 A
3 A
3 B
4 A
4 C
5 A
6 A
7 A
7 B
好的,我希望查询 return 并根据 SERVICE 列显示我的 table 中存在的所有可能组合及其各自的计数。例如第一个用户有 A 和 B 服务,这是一个出现一次的组合。下一个用户只有服务 A,这是又一次出现的组合。第三个用户有服务 A 和 B,这已经发生过一次,现在这个组合的计数是 2,等等。所以我基于这个特定输入的输出将是一个 table 像这样:
A AB AC ABC B BC
3 3 1 0 0 0
所以再澄清一点,如果有 3 个服务,那么就有 3 个!可能的组合; 3x2x1=6,分别是A、B、C、AB、AC、BC、ABC。我的 table 应该包含分配了这些服务组合的用户数。
我尝试使用此查询构建矩阵,然后使用 CUBE 函数获取所有计数:
select service_A, service_B, service_C from
(select USERID,
max(case when SERVICE =A then 1 else null end) service_A,
max(case when SERVICE =B then 1 else null end) service_B,
max(case when SERVICE =C then 1 else null end) service_C
from SOME_TABLE)
group by CUBE(service_A, service_B,service_C);
但我没有得到所有组合的计数。我只需要发生的组合,因此计数 0 不是必需的,但可以显示它们。谢谢
不要将其输出为动态列(不使用 PL/SQL 和动态 SQL 很难做到)而是将其输出为行(如果您有前端,那么它通常可以比 oracle 更容易地将行转换为列):
Oracle 设置:
CREATE TABLE some_table ( USERID, SERVICE ) AS
SELECT 1, 'A' FROM DUAL UNION ALL
SELECT 1, 'B' FROM DUAL UNION ALL
SELECT 2, 'A' FROM DUAL UNION ALL
SELECT 3, 'A' FROM DUAL UNION ALL
SELECT 3, 'B' FROM DUAL UNION ALL
SELECT 4, 'A' FROM DUAL UNION ALL
SELECT 4, 'C' FROM DUAL UNION ALL
SELECT 5, 'A' FROM DUAL UNION ALL
SELECT 6, 'A' FROM DUAL UNION ALL
SELECT 7, 'A' FROM DUAL UNION ALL
SELECT 7, 'B' FROM DUAL;
查询:
SELECT service,
COUNT( userid ) AS num_users
FROM (
SELECT userid,
LISTAGG( service ) WITHIN GROUP ( ORDER BY service ) AS service
FROM some_table
GROUP BY userid
)
GROUP BY service;
输出:
SERVICE NUM_USERS
------- ----------
AC 1
A 3
AB 3
PL/SQL 用于动态列:
VARIABLE cur REFCURSOR;
DECLARE
TYPE string_table IS TABLE OF VARCHAR2(4000);
TYPE int_table IS TABLE OF INT;
t_services string_table;
t_counts int_table;
p_sql CLOB;
BEGIN
SELECT service,
COUNT( userid ) AS num_users
BULK COLLECT INTO t_services, t_counts
FROM (
SELECT userid,
CAST( LISTAGG( service ) WITHIN GROUP ( ORDER BY service ) AS VARCHAR2(2) ) AS service
FROM some_table
GROUP BY userid
)
GROUP BY service;
p_sql := EMPTY_CLOB() || 'SELECT ';
p_sql := p_sql || t_counts(1) || ' AS "' || t_services(1) || '"';
FOR i IN 2 .. t_services.COUNT LOOP
p_sql := p_sql || ', ' || t_counts(i) || ' AS "' || t_services(i) || '"';
END LOOP;
p_sql := p_sql || ' FROM DUAL';
OPEN :cur FOR p_sql;
END;
/
PRINT cur;
输出:
AC A AB
--- --- ---
1 3 3