每天为每个值选择一行



我在PostgreSQL 9.4中有一个SQL查询,虽然由于我从中提取数据的表而变得更复杂,但它可以归结为以下内容:

SELECT entry_date, user_id, <other_stuff>
FROM <tables, joins, etc>
GROUP BY entry_date, user_id
WHERE <whatever limits I want, such as limiting the date range or users>

结果是,每个用户每天都有一行数据。通常,此查询将在一个月的entry_date周期内运行,所需的结果是每个用户在一个月中的每一天都有一行。

问题是,可能不是每个用户在一个月的每一天都有数据,并且此查询只返回有数据的日子的行。

是否有某种方法可以修改此查询,使其每天为每个用户返回一行,即使某些行中没有数据(除了日期和用户)?

我试着用generate_series()进行联接,但没有成功——它可以使没有遗漏的天数,但不是每个用户。我真正需要的是类似于"对于列表中的每个用户,生成一系列(user,date)记录"的

编辑:为了澄清,我想要的最终结果是,对于数据库中的每个用户(定义为用户表中的记录),我希望每个日期都有一行。因此,如果我在where子句中指定5/1/15-5/31/15的日期范围,我希望每个用户有31行,即使该用户在该范围内没有数据,或者只有几天的数据。

generate_series()是正确的想法。你可能没有把细节弄清楚。可以这样工作:

WITH cte AS (
   SELECT entry_date, user_id, <other_stuff>
   FROM   <tables, joins, etc>
   GROUP  BY entry_date, user_id
   WHERE  <whatever limits I want>
   ) 
SELECT *
FROM  (SELECT DISTINCT user_id FROM cte) u
CROSS  JOIN (
   SELECT entry_date::date 
   FROM   generate_series(current_date - interval '1 month'
                        , current_date - interval '1 day'
                        , interval '1 day') entry_date
   ) d
LEFT   JOIN cte USING (user_id, entry_date);

我选择了一个月结束的运行时间窗口";昨天";。你没有定义你的";月份;确切地

假设CCD_ 4是数据类型CCD_。

更简单地满足您更新的需求

要获得users表中每个用户的结果(而不是当前选择的结果)以及给定时间范围的结果,会变得更简单。你不需要CTE:

SELECT *
FROM   (SELECT user_id FROM users) u
CROSS  JOIN (
   SELECT entry_date::date 
   FROM   generate_series(timestamp '2015-05-01'
                        , timestamp '2015-05-31'
                        , interval '1 day') entry_date
   ) d
LEFT   JOIN (
   SELECT entry_date, user_id, <other_stuff>
   FROM   <tables, joins, etc>
   GROUP  BY entry_date, user_id
   WHERE  <whatever>
   ) t USING (user_id, entry_date);

为什么用这种特殊的方式调用generate_series()

  • 在PostgreSQL中生成两个日期之间的时间序列

最好使用ISO 8601日期格式(YYYY-MM-DD),无论区域设置如何都可以使用。

相关内容

  • 没有找到相关文章

最新更新