在我的PostgreSQL数据库中,我有survey_results
表:
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-11', '2018-01-10');
INSERT INTO survey_results (id, scores, created_at, updated_at)
VALUES (2, '{"medic": { "social": { "total": "high" } } }', '2018-01-12', '2018-01-12');
以及以下查询:
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
ORDER BY date ASC;
返回:
date positive
2018-01-11 100
2018-01-12 100
问题是查询省略2018-01-10因为没有记录,这是因为group by。有没有办法更新此查询以返回没有记录的日期:
date positive
2018-01-10 0
2018-01-11 100
2018-01-12 100
这是sqlfiddle:
答案 0 :(得分:1)
使用功能This answer
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 | 0.00
2018-01-11 | 100.00
2018-01-12 | 100.00
(3 rows)
答案 1 :(得分:0)
日期不是&#34;缺少&#34;。可以这样想:您的查询要求服务器返回所有数据,其中created_at值为&gt; =&#39; 2018-01-10&#39;和created_at值是&lt; =&#39; 2018-01-12&#39;。查询正确执行。
如果要将数据集与任意日期集进行对比,则必须生成该集。一些数据仓库从业者使用日期维度,其中包含所有相关日期,以及财政年度,IsHoliday等便利属性。
或者,您可以自己生成这样的序列,并使用它们(作为视图,派生表等),并将日期序列LEFT JOIN到您的实际查询。然后,您可以将日期谓词应用于序列,并且外部查询中缺少数据的任何日期都将填充为NULL。您也可以选择将这些列转换为具体的值,例如&#39;&#39;&#39;或0(零)。
以下是生成任意日期序列的示例查询。您可以想象如何修改它以适合您的环境。这适用于MSSQL 2017,但任何平台的想法都是一样的。
DECLARE @dtStartDate datetime
DECLARE @dtEndDate datetime
SET @dtStartDate = '2018-01-10'
SET @dtEndDate = '2018-01-12'
SELECT
T.DateVal,
CASE DATEPART(weekday, T.DateVal)
WHEN 1 THEN 'Sunday'
WHEN 2 THEN 'Monday'
WHEN 3 THEN 'Tuesday'
WHEN 4 THEN 'Wednesday'
WHEN 5 THEN 'Thursday'
WHEN 6 THEN 'Friday'
WHEN 7 THEN 'Saturday'
END AS WeekDay,
DATEPART(day, T.DateVal) AS [Date],
DATEPART(month, T.DateVal) AS [Month],
DATEPART(year, T.DateVal) AS [Year]
FROM
(
SELECT
DATEADD(day, SEQ.SeqValue, @dtStartDate) DateVal
FROM
(
SELECT
(HUNDREDS.SeqValue + TENS.SeqValue + ONES.SeqValue) SeqValue
FROM
(
SELECT 0 SeqValue
UNION ALL
SELECT 1 SeqValue
UNION ALL
SELECT 2 SeqValue
UNION ALL
SELECT 3 SeqValue
UNION ALL
SELECT 4 SeqValue
UNION ALL
SELECT 5 SeqValue
UNION ALL
SELECT 6 SeqValue
UNION ALL
SELECT 7 SeqValue
UNION ALL
SELECT 8 SeqValue
UNION ALL
SELECT 9 SeqValue
) ONES
CROSS JOIN
(
SELECT 0 SeqValue
UNION ALL
SELECT 10 SeqValue
UNION ALL
SELECT 20 SeqValue
UNION ALL
SELECT 30 SeqValue
UNION ALL
SELECT 40 SeqValue
UNION ALL
SELECT 50 SeqValue
UNION ALL
SELECT 60 SeqValue
UNION ALL
SELECT 70 SeqValue
UNION ALL
SELECT 80 SeqValue
UNION ALL
SELECT 90 SeqValue
) TENS
CROSS JOIN
(
SELECT 0 SeqValue
UNION ALL
SELECT 100 SeqValue
UNION ALL
SELECT 200 SeqValue
UNION ALL
SELECT 300 SeqValue
UNION ALL
SELECT 400 SeqValue
UNION ALL
SELECT 500 SeqValue
UNION ALL
SELECT 600 SeqValue
UNION ALL
SELECT 700 SeqValue
UNION ALL
SELECT 800 SeqValue
UNION ALL
SELECT 900 SeqValue
) HUNDREDS
) SEQ
) T
WHERE
T.DateVal <= @dtEndDate
ORDER BY
T.DateVal ASC