使用带有generate_series的OVER函数

时间:2018-02-07 22:18:33

标签: sql postgresql

我的数据库中有以下架构:

CREATE TABLE survey_results (
    id integer NOT NULL,
    scores jsonb DEFAULT '{}'::jsonb,
    created_at timestamp without time zone,
    updated_at timestamp without time zone  
);

INSERT INTO survey_results (id, scores, created_at, updated_at)
    VALUES (1, '{"medic": { "social": { "total": "high" } } }', '2018-01-10', '2018-01-11');

INSERT INTO survey_results (id, scores, created_at, updated_at)
    VALUES (2, '{"medic": { "social": { "total": "high" } } }', '2018-01-12', '2018-01-12');

以及以下查询:

SELECT date::date, coalesce(positive, 0.00) as positive
FROM generate_series('2018-01-10'::date, '2018-01-12', '1d') s(date)
LEFT JOIN (
    -- your query
    SELECT
      distinct(date(survey_results.created_at)),
      ROUND(
        COUNT(*) FILTER (WHERE (
          scores#>>'{medic,social,total}' in('high'))) OVER(order by date(survey_results.created_at)
        ) * 1.0 /
        (
          GREATEST(
            COUNT(*) FILTER (WHERE (scores#>>'{medic,social,total}' in('high','medium','low')
        )
      ) OVER(order by date(survey_results.created_at)), 1.0))* 100, 2
    )
     AS positive
      FROM survey_results
      WHERE  
        survey_results.created_at::date >= '2018-01-10'
        AND survey_results.created_at::date <= '2018-01-12'
      GROUP BY date, scores
    -- your query
    ) q USING(date)
ORDER BY date ASC;

返回以下结果:

date        positive
2018-01-10  100
2018-01-11  0
2018-01-12  100

但问题是,当某天没有结果时,它应该获得与前一天相同的数据,所以它应该是这样的:

date        positive
2018-01-10  100
2018-01-11  100
2018-01-12  100

我在考虑使用OVER功能,但我无法使其正常工作。有没有办法做到这一点?

http://sqlfiddle.com/#!17/0cd2c/1

2 个答案:

答案 0 :(得分:1)

使用累积count(*)作为窗口函数来指定分区(具有前导非空值和连续空值的组)。接下来,在这些分区中添加一个带有窗口函数first_value()的外部选择:

SELECT *, first_value(positive) OVER (PARTITION BY part ORDER BY date)
FROM (
    SELECT date::date, positive, count(positive) OVER (ORDER BY date) as part
    FROM generate_series('2018-01-09'::date, '2018-01-12', '1d') s(date)
    LEFT JOIN (
        SELECT
          distinct(date(survey_results.created_at)),
          ROUND(
            COUNT(*) FILTER (WHERE (
              scores#>>'{medic,social,total}' in('high'))) OVER(order by date(survey_results.created_at)
            ) * 1.0 /
            (
              GREATEST(
                COUNT(*) FILTER (WHERE (scores#>>'{medic,social,total}' in('high','medium','low')
            )
          ) OVER(order by date(survey_results.created_at)), 1.0))* 100, 2
        )
         AS positive
          FROM survey_results
          WHERE  
            survey_results.created_at::date >= '2018-01-09'
            AND survey_results.created_at::date <= '2018-01-12'
          GROUP BY date, scores
        ) q USING(date)
    ) q
ORDER BY date ASC;

SqlFiddle.

答案 1 :(得分:0)

您可以使用累积功能,例如max()

select, date::date, coalesce(positive, 0.00),
        max(positive) over (order by date::date)

如果您的数据正在增加,这是有效的。