Json聚合具有缺失值的数据

时间:2017-03-28 22:18:39

标签: sql json postgresql psql jsonb

我有一个简单的补充表

create table consumption (
    account bigint not null,
    date date not null,
    supplement text not null check (supplement in ('multiVitamin', 'calMag', 'omega3', 'potassium', 'salt', 'antiOxidant', 'enzymes')),
    quantity integer not null default 0
);

我想要获取人们每天消耗的东西。这将是我想要的输出的例子

[
    {
        "date" : "2016-01-01",
        "multiVitamin" : 7,
        "calMag" : 0,
        "omega3" : 3,
        "potassium" : 3,
        "salt" : 2,
        "antiOxidant" : 0,
        "enzymes" : 1
    },
    {
        "date" : "2016-01-02",
        "multiVitamin" : 2,
        "calMag" : 1,
        "omega3" : 1,
        "potassium" : 2,
        "salt" : 2,
        "antiOxidant" : 0,
        "enzymes" : 1
    }
]

我很困惑如何将这些值放入json对象并合并,以便如果当天没有输入任何补充,我将返回0。因此,每天应该返回所有补品。这是我到目前为止所做的,但距离完成还很远 - 它至少取代了所选的日期。

WITH duration_amount AS (
SELECT date_trunc('day', date)::date AS date_group,     json_build_object('quantity', SUM(consumption.quantity) )::jsonb->'quantity' as supplement
FROM consumption
WHERE account = 1667
GROUP BY date_group
)
SELECT DISTINCT date_group, supplement
FROM (
SELECT generate_series(date_trunc('day', '2016-10-20'::date), '2016-10-28'::date, '1 day') AS date_group
) x
LEFT JOIN duration_amount
USING (date_group)
ORDER BY date_group DESC

1 个答案:

答案 0 :(得分:0)

示例数据:

insert into consumption values
(1667, '2016-10-21', 'multiVitamin', 1),
(1667, '2016-10-21', 'calMag', 2),
(1667, '2016-10-22', 'multiVitamin', 3),
(1667, '2016-10-22', 'calMag', 4),
(1667, '2016-10-22', 'omega3', 5);

您应准备一个包含所有可能值的行的模板表。在示例中,它将包含14行(交叉连接2天,7个补充)。接下来,使用coalesce()左键连接到您的表,以获取缺失值:

select 
    date_group::date as date, 
    supplement_group as supplement, 
    coalesce(quantity, 0) quantity
from generate_series('2016-10-21'::date, '2016-10-22', '1 day') as date_group
cross join (
    values 
        ('multiVitamin'), ('calMag'), ('omega3'), 
        ('potassium'), ('salt'), ('antiOxidant'), ('enzymes') 
    ) as supplements(supplement_group)
left join consumption 
    on date_group = date 
    and supplement = supplement_group 
    and account = 1667;

    date    |  supplement  | quantity 
------------+--------------+----------
 2016-10-21 | multiVitamin |        1
 2016-10-21 | calMag       |        2
 2016-10-21 | omega3       |        0
 2016-10-21 | potassium    |        0
 2016-10-21 | salt         |        0
 2016-10-21 | antiOxidant  |        0
 2016-10-21 | enzymes      |        0
 2016-10-22 | multiVitamin |        3
 2016-10-22 | calMag       |        4
 2016-10-22 | omega3       |        5
 2016-10-22 | potassium    |        0
 2016-10-22 | salt         |        0
 2016-10-22 | antiOxidant  |        0
 2016-10-22 | enzymes      |        0
(14 rows)

结果可以轻松汇总到jsonbPHP Sessions across sub domains