【问题标题】:Query for count of distinct values in a rolling date range and country查询滚动日期范围和国家/地区中不同值的计数
【发布时间】:2021-11-10 00:48:42
【问题描述】:

晚上好,亲爱的 Stack Overflow 社区。 这是我在这里的第一个问题。

我有以下问题:我需要一个查询来计算每个国家/地区滚动日期范围(3 天)内的不同值。

我做了一些研究,发现这里有以下讨论 [1]:Query for count of distinct values in a rolling date range

对于我面临的问题,我不仅需要按日期分组,还需要按国家/地区分组。请考虑以下输入表:

Date Country Email
1/1/12 DE de1@example.com
1/1/12 FRA fra1@example.com
1/1/12 SPA spa1@example.com
1/2/12 DE de1@example.com
1/2/12 DE de2@example.com
1/3/12 SPA spa1@example.com
1/3/12 SPA spa2@example.com
1/3/12 FRA fra2@example.com
1/4/12 SPA spa1@example.com
1/4/12 FRA fra2@example.com
1/4/12 FRA fra3@example.com
1/4/12 SPA spa3@example.com

计算不同电子邮件的预期结果如下:

Date Country Email
1/1/12 DE 1
1/1/12 FRA 1
1/1/12 SPA 1
1/2/12 DE 2
1/2/12 FRA 1
1/2/12 SPA 1
1/3/12 SPA 2
1/3/12 DE 2
1/3/12 FRA 2
1/4/12 SPA 3
1/4/12 FRA 2
1/4/12 DE 2

我试图修改上述讨论中建议的解决方案,并通过在选定列和分组中添加国家/地区来修改以下内容。

SELECT date
     ,(SELECT count(DISTINCT email)
       FROM   tbl
       WHERE  date BETWEEN g.date - 2 AND g.date
      ) AS dist_emails
FROM  (SELECT generate_series(timestamp '2012-01-01'
                            , timestamp '2012-01-06'
                            , interval  '1 day')::date) AS g(date)

很遗憾,更新后的查询不起作用,因为无法识别国家并出错。

SELECT date, country,
         ,(SELECT count(DISTINCT email)
           FROM   tbl
           WHERE  date BETWEEN g.date - 2 AND g.date
          ) AS dist_emails
    FROM  (SELECT generate_series(timestamp '2012-01-01'
                                , timestamp '2012-01-06'
                                , interval  '1 day')::date) AS g(date)
GROUP BY 1,2

非常感谢您的建议并分享您在解决此问题方面的专业知识。

【问题讨论】:

  • @GordonLinoff 感谢并抱歉给您带来不便
  • 请发布您使用 SQL 收到的确切错误消息
  • SQL 编译错误:位置 17 处的错误 line1 无效标识符“国家”。问题发生在雪花中。不幸的是,我无法编辑问题并添加相关标签。管理员可以请您帮忙吗?非常感谢。

标签: sql postgresql date grouping distinct-values


【解决方案1】:

country 不存在的原因是我们只能从查询的FROM 部分中的表中获取SELECT 列。嵌套子查询选择from tbl,但这不适用于主外部查询,它只从生成的表g 中进行选择。 g 只有一个 date 列,所以这是外部查询可以直接选择的唯一列。

查询的另一个问题是COUNT 没有考虑国家/地区。

为此,我将使用基本连接来查询每个日期范围的每一行,然后为每个日期 + 国家/地区执行 count distinct。您可以使用INNER 连接删除没有条目的日期,或者使用LEFT OUTER 返回{date}, nil,nil 的行(如果该日期范围内没有条目)。比如:

SELECT g.date
     , tbl.country
     , COUNT(DISTINCT(tbl.email))
    FROM  (SELECT generate_series(timestamp '2012-01-01'
                                , timestamp '2012-01-06'
                                , interval  '1 day')::date) AS g(date)
    INNER JOIN tbl ON (tbl.date BETWEEN g.date - 2 AND g.date)

GROUP BY 1,2

【讨论】:

    猜你喜欢
    • 2012-05-19
    • 2020-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-06
    • 1970-01-01
    • 2016-07-31
    • 2020-12-23
    相关资源
    最近更新 更多