Postgres:使用GROUP BY的子查询

时间:2018-09-12 14:24:17

标签: sql postgresql

我正在尝试使用上面的 NOT FUNCTIONAL CODE (无功能代码)优化查询(而不是重复很多时间)(因为子查询仅返回1列):

SELECT
    e.pageview_identifier,
    e.created_at,
    e.pageview_current_url,
    e.pageview_mobile,
    (
        SELECT event_type, COUNT(event_identifier)
        FROM events v
        WHERE
            v.company_identifier = e.company_identifier AND
            v.user_identifier = e.user_identifier AND
            v.pageview_identifier = e.pageview_identifier
        GROUP BY v.event_type
    )
FROM events e
WHERE
    company_identifier = 'xyz' AND
    user_identifier = '01CDQZVSJFBDA8W444JS2CS3BA' AND
    event_type = 'page:view';

基本上,我想将列检索为

pageview_identifier, created_at, ..., event_type_a_count, event_type_b_count, ...

有效的功能代码是:

SELECT
    e.pageview_identifier,
    e.created_at,
    e.pageview_current_url,
    e.pageview_mobile,
    (
        SELECT COUNT(event_identifier)
        FROM events v
        WHERE
            v.company_identifier = e.company_identifier AND
            v.user_identifier = e.user_identifier AND
            v.pageview_identifier = e.pageview_identifier AND
            v.event_type = 'mouse:move'
    ) as mouse_move_count
FROM events e
WHERE
    company_identifier = 'xyz' AND
    user_identifier = '01CDQZVSJFBDA8W444JS2CS3BA' AND
    event_type = 'page:view';

但是在这种情况下,我需要为每种event_type重复此子查询很多时间。

编辑1-更多信息:

在我的WHERE子句中,我仅将其限制为event_type = 'page:view'。我为event_type提供了一些可能的值,对于每个page:view,我需要根据条件event_type来计算与其相关的事件(具有不同的e.pageview_identifier = v.pageview_identifier)。

1 个答案:

答案 0 :(得分:0)

只需使用窗口函数:

    SELECT e.pageview_identifier,
           e.created_at,
           e.pageview_current_url,
           e.pageview_mobile,
           COUNT(*) OVER (PARTITION BY e.company_identifier, e.user_identifier, e.pageview_identifier) as cnt
    FROM events e
    WHERE e.company_identifier = 'xyz' AND
          e.user_identifier = '01CDQZVSJFBDA8W444JS2CS3BA' AND
          e.event_type = 'page:view';

注意:这仅计算'page:view'个事件。如果您希望对每个事件进行计数,那么一种方法是:

SELECT e.*
FROM (SELECT e.pageview_identifier,
             e.created_at,
             e.pageview_current_url,
             e.pageview_mobile,
             COUNT(*) FILTER (WHERE .event_type = 'mouse:move') OVER (PARTITION BY e.company_identifier, e.user_identifier, e.pageview_identifier) as cnt_mouse_move,
             COUNT(*) FILTER (WHERE .event_type = ''page:view'') OVER (PARTITION BY e.company_identifier, e.user_identifier, e.pageview_identifier) as cnt_page_view,
             . . .
      FROM events e
      WHERE e.company_identifier = 'xyz' AND
          e.user_identifier = '01CDQZVSJFBDA8W444JS2CS3BA' 
     ) e
WHERE e.event_type = 'page:view';