基于两个表

时间:2015-05-12 18:36:13

标签: sql oracle

我有两个表,一个包含来自某些应用程序的访问历史记录,另一个包含执行这些访问的用户。

ACCESS_HISTORY
WORKSPACE - APP_ID - APP_NAME   -  USERNAME

WS_1        1        APP_NAME      USER_1
WS_1        1        APP_NAME      USER_2
WS_2        1        APP_NAME      USER_3
WS_3        2        APP_NAME      USER_1

USERS
WORKSPACE - USERNAME - IS_ADMIN - IS_DEVELOPER
WS_1        USER_1      YES          NO
WS_1        USER_2      NO           YES
WS_2        USER_3      NO           NO
WS_3        USER_1      NO           YES

我想执行SELECT查询以获取每个应用程序的详细访问信息(acc_general是来自非管理员或开发人员的用户的访问权限,acc_adm是从管理员用户访问,acc_dev是dev用户的访问权限,acc_total是general,adm和dev访问权限的总和):

WORKSPACE  APP_NAME  APP_ID  ACC_GENERAL  ACC_ADM  ACC_DEV  ACC_TOTAL
WS_1       APP_NAME  1       0            1        1        2
WS_2       APP_NAME  1       1            0        0        1
WS_3       APP_NAME  2       0            0        1        1

请注意:

  • access_history中,当工作区和app_id相同时,访问权引用相同的应用程序。两个应用程序可能具有相同的ID但位于不同的工作区。
  • 每个USERNAME指的是同一个用户,但用户可能是WS_1的管理员或开发者,而只是另一个工作区的简单用户。
  • 真正的数据库包含许多行(ACCESS_HISTORY上的 700k +,USERS上的 5k )和许多其他列,但是&#39 ;现在不重要了。
  • 我正在使用Oracle数据库。
  • 如果有人想将我的问题标题编辑为更合适的问题(我想不出更好的问题)。

2 个答案:

答案 0 :(得分:1)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE ACCESS_HISTORY AS 
          SELECT 'WS_1' AS WORKSPACE, 1 AS APP_ID, 'APP_NAME' AS APP_NAME, 'USER_1' AS USERNAME FROM DUAL
UNION ALL SELECT 'WS_1' AS WORKSPACE, 1 AS APP_ID, 'APP_NAME' AS APP_NAME, 'USER_2' AS USERNAME FROM DUAL
UNION ALL SELECT 'WS_2' AS WORKSPACE, 1 AS APP_ID, 'APP_NAME' AS APP_NAME, 'USER_3' AS USERNAME FROM DUAL
UNION ALL SELECT 'WS_3' AS WORKSPACE, 2 AS APP_ID, 'APP_NAME' AS APP_NAME, 'USER_1' AS USERNAME FROM DUAL;

CREATE TABLE USERS AS 
          SELECT 'WS_1' AS WORKSPACE, 'USER_1' AS USERNAME, 'YES' AS IS_ADMIN, 'NO' AS IS_DEVELOPER FROM DUAL
UNION ALL SELECT 'WS_1' AS WORKSPACE, 'USER_2' AS USERNAME, 'NO' AS IS_ADMIN, 'YES' AS IS_DEVELOPER FROM DUAL
UNION ALL SELECT 'WS_2' AS WORKSPACE, 'USER_3' AS USERNAME, 'NO' AS IS_ADMIN, 'NO' AS IS_DEVELOPER FROM DUAL
UNION ALL SELECT 'WS_3' AS WORKSPACE, 'USER_1' AS USERNAME, 'NO' AS IS_ADMIN, 'YES' AS IS_DEVELOPER FROM DUAL;

查询1

SELECT a.WORKSPACE,
       a.APP_NAME,
       a.APP_ID,
       COUNT( CASE WHEN u.IS_ADMIN <> 'YES' AND u.IS_DEVELOPER <> 'YES' THEN 1 END ) AS ACC_GENERAL,
       COUNT( CASE u.IS_ADMIN WHEN 'YES' THEN 1 END ) AS ACC_ADM,
       COUNT( CASE u.IS_DEVELOPER WHEN 'YES' THEN 1 END ) AS ACC_DEV,
       COUNT( 1 ) AS ACC_TOTAL
FROM   ACCESS_HISTORY a
       INNER JOIN
       USERS u
       ON (   a.WORKSPACE = u.WORKSPACE
          AND a.USERNAME  = u.USERNAME )
GROUP BY
       a.WORKSPACE,
       a.APP_NAME,
       a.APP_ID

<强> Results

| WORKSPACE | APP_NAME | APP_ID | ACC_GENERAL | ACC_ADM | ACC_DEV | ACC_TOTAL |
|-----------|----------|--------|-------------|---------|---------|-----------|
|      WS_1 | APP_NAME |      1 |           0 |       1 |       1 |         2 |
|      WS_2 | APP_NAME |      1 |           1 |       0 |       0 |         1 |
|      WS_3 | APP_NAME |      2 |           0 |       0 |       1 |         1 |

答案 1 :(得分:0)

尝试这样的事情:

SELECT h.workspace, h.appid, h.appname, u.username, 
SUM(CASE WHEN u.is_admin=0 AND u.is_dev=0 THEN 1 ELSE 0 END) AS acc_general,
SUM(CASE WHEN u.is_admin>0 THEN 1 ELSE 0 END ) AS acc_admin, 
SUM(CASE WHEN u.is_dev>0 THEN 1 ELSE 0 END ) acc_dev, COUNT(*) AS acc_total
FROM acc_history h LEFT JOIN users u 
ON h.worksapce=u.workspace AND h.username=u.workspace
GROUP BY h.workspace, h.appid, h.appname, u.username