我有一个包含以下结构和数据的表格。我想根据 WHERE 子句过滤器获取 USER_ID 的不同计数。我可以通过下面的示例查询来实现这一点。
WITH CTE(REPORT,INSTANCE,ROLE,LOGIN_TIME,ISACTIVE,WEB_ACCESS,USER_ID) AS (
SELECT * FROM VALUES
('R1','ABC','ADMIN','2024-04-05 16:00:00','1','YES','U1'),
('R1','ABC','DEV','2024-04-04 16:00:00','1','NO','U2'),
('R1','ABC','ADMIN','2024-04-03 16:00:00','1','NO','U3'),
('R1','ABC','ADMIN','2024-04-07 16:00:00','1','YES','U1'),
('R1','ABC','ADMIN','2024-04-09 16:00:00','1','YES','U1'),
('R1','ABC','DEV','2024-04-06 16:00:00','1','NO','U2')
)
--SELECT * FROM CTE
--SELECT COUNT( DISTINCT USER_ID) FROM CTE WHERE WEB_ACCESS='NO'; -- Gives 2
--SELECT COUNT( DISTINCT USER_ID) FROM CTE WHERE ROLE='ADMIN';-- gives 2
--SELECT COUNT( DISTINCT USER_ID) FROM CTE WHERE ROLE='ADMIN' and WEB_ACCESS='YES';-- gives 1
但真正的要求是在此表之上为最终用户创建一个视图,并动态生成计数,就像最终用户使用自己的过滤条件查询视图时一样,并且不同的 user_id 计数应填充在不同的列中。
但是,根据 SQL 标准,这无法通过普通视图来实现。只是想从专家那里知道是否有任何可能的方法来呈现 USER_ID 上的总不同计数,同时最终用户可以选择使用 WHERE 子句过滤器在 VIEW 上触发简单的选择。
我不想使用任何UDTF。只需要信息,如果这可以通过任何窗口函数或枢轴或任何其他方式来实现,以将不同计数呈现为最终用户查询视图的视图中的附加字段?
考虑使用以下 DDL 在具有上述共享数据的临时表上创建的视图
CREATE VIEW REPORT_VIEW AS
SELECT
REPORT,INSTANCE,ROLE,LOGIN_TIME,ISACTIVE,WEB_ACCESS,USER_ID,'Use some logic to get distinct count on USER_ID dynamically' as DISTINCT_USER_ID_COUNT
FROM MY_TABLE
当我如下查询视图 REPORT_VIEW 时,我希望应该为过滤条件填充 DISTINCT_USER_ID_COUNT
SELECT * FROM REPORT_VIEW WHERE WEB_ACCESS='NO';--This should give DISTINCT_USER_ID_COUNT as 2
SELECT * FROM REPORT_VIEW WHERE WEB_ACCESS='YES' AND ROLE='ADMIN';--This should give DISTINCT_USER_ID_COUNT as 1
根据我的理解,这是不可能的。
当您将 COUNT(DISTINCT USER_ID) 定义为视图中的列时,如下所示:
CREATE or replace VIEW REPORT_VIEW AS
SELECT
REPORT,INSTANCE,ROLE,LOGIN_TIME,ISACTIVE,WEB_ACCESS,USER_ID,
count(distinct user_id) over () as DISTINCT_USER_ID_COUNT
FROM test;
视图中使用的任何函数都是针对已定义的过滤器的表定义的。
在这种情况下,当用户运行时:
select * from REPORT_VIEW where
WEB_ACCESS='YES' AND ROLE='ADMIN';
我们不能下推过滤器,否则会影响原始视图的结果,并会被视为错误结果问题。滤波器必须在窗函数之后应用:
我想用户在从视图中选择时必须手动添加此列:
CREATE or replace VIEW REPORT_VIEW AS
SELECT
REPORT,INSTANCE,ROLE,LOGIN_TIME,ISACTIVE,WEB_ACCESS,USER_ID
FROM test;
select
*,
count(distinct user_id) over () as DISTINCT_USER_ID_COUNT
from REPORT_VIEW
where
WEB_ACCESS='YES'
AND ROLE='ADMIN'
;