【问题标题】:Grouping issue with OracleOracle 的分组问题
【发布时间】:2012-02-24 02:40:42
【问题描述】:

我有以下数据:

SUM_OF_ALL_PUSHES  |   USER_LOGIN  |   COMPONENT_NAME  | ROW_LST_UPD_TS
-------------------|---------------|-------------------|-------------------------
61                 |   DOMAIN\abc  |   Component A     | 22/02/12 12:58:26.325 PM
14                 |   DOMAIN\xyz  |   Component B     | 22/02/12 05:20:52.565 PM
17                 |   DOMAIN\xyz  |   Component A     | 22/02/12 05:21:58.045 PM
34                 |   DOMAIN\abc  |   Component A     | 22/02/12 05:44:20.274 PM
38                 |   DOMAIN\abc  |   Component A     | 22/02/12 06:28:41.465 PM

我正在使用以下方法获取数据:

SELECT SUM(Q.SUM_OF_ALL_PUSHES) AS SUM_OF_ALL_PUSHES, Q.USER_LOGIN, Q.COMPONENT_NAME, Q.ROW_LST_UPD_TS FROM( SELECT                
    SUM(REGEXP_SUBSTR(SUBSTR(EVENT_MSG, INSTR(EVENT_MSG, ' ', 1,1), INSTR(EVENT_MSG, ' ', 1,1)) , '[0-9]+')) AS "SUM_OF_ALL_PUSHES", 
    USER_LOGIN,
    COMPONENT_NAME, 
    EVENT_MSG, 
    ROW_LST_UPD_TS
FROM EVENT_MGT.EVENT_LOG
WHERE
ROW_LST_UPD_TS BETWEEN TRUNC(SYSDATE - 1) AND TRUNC(SYSDATE) - 1/86400
AND SUBSTR(EVENT_MSG,1 ,INSTR(EVENT_MSG, 'd', 1,1)) = 'Received'
GROUP BY 
    USER_LOGIN, 
    COMPONENT_NAME, 
    EVENT_MSG, 
    ROW_LST_UPD_TS) Q
GROUP BY COMPONENT_NAME, USER_LOGIN, ROW_LST_UPD_TS 
ORDER BY ROW_LST_UPD_TS ASC

问题是我需要按组件对每个用户的数字求和。所以在上面的结果集中,我需要聚合第 1、4 和 5 列,并将 SUM_OF_ALL_PUSHES 的值相加,因为每条记录都有用户 abc 和组件 A。

所以总而言之,我需要删除其他列中的数据重复,并根据用户和组件对第一列中的值求和。所以结果集应该是这样的:

SUM_OF_ALL_PUSHES  |   USER_LOGIN  |   COMPONENT_NAME  | ROW_LST_UPD_TS
-------------------|---------------|-------------------|-------------------------
133                |   DOMAIN\abc  |   Component A     | 22/02/12 12:58:26.325 PM
14                 |   DOMAIN\xyz  |   Component B     | 22/02/12 05:20:52.565 PM
17                 |   DOMAIN\xyz  |   Component A     | 22/02/12 05:21:58.045 PM 

请帮忙。

【问题讨论】:

    标签: sql oracle grouping aggregate-functions aggregation


    【解决方案1】:

    听起来您不想按时间戳分组,而是对其应用聚合函数(我猜是 MAX)。

    SELECT SUM(Q.SUM_OF_ALL_PUSHES) AS SUM_OF_ALL_PUSHES, Q.USER_LOGIN, Q.COMPONENT_NAME, MAX(Q.ROW_LST_UPD_TS) FROM( SELECT                
        SUM(REGEXP_SUBSTR(SUBSTR(EVENT_MSG, INSTR(EVENT_MSG, ' ', 1,1), INSTR(EVENT_MSG, ' ', 1,1)) , '[0-9]+')) AS "SUM_OF_ALL_PUSHES", 
        USER_LOGIN,
        COMPONENT_NAME, 
        EVENT_MSG, 
        ROW_LST_UPD_TS
    FROM EVENT_MGT.EVENT_LOG
    WHERE
    ROW_LST_UPD_TS BETWEEN TRUNC(SYSDATE - 1) AND TRUNC(SYSDATE) - 1/86400
    AND SUBSTR(EVENT_MSG,1 ,INSTR(EVENT_MSG, 'd', 1,1)) = 'Received'
    GROUP BY 
        USER_LOGIN, 
        COMPONENT_NAME, 
        EVENT_MSG, 
        ROW_LST_UPD_TS) Q
    GROUP BY COMPONENT_NAME, USER_LOGIN 
    ORDER BY MAX(Q.ROW_LST_UPD_TS) ASC
    

    【讨论】:

    • 我从没想过使用 Max,但它完全符合我的要求。非常感谢。但是,我不明白为什么它会起作用。 MAX 函数返回表达式的最大值。那么如何取日期的最大值聚合这样的记录呢?如果你有时间请解释一下。谢谢!
    • 您不想按ROW_LST_UPD_TS 进行分组,因为您不希望该列的每个唯一值都有单独的行。因此,您需要将其从GROUP BY 子句中删除;但在分组查询中,选择列表中的每个表达式必须是分组列或分组函数。因此,您需要对该列应用组函数以使查询正常工作。 MAX 恰好是提供您想要的结果的组函数。
    猜你喜欢
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    相关资源
    最近更新 更多