【问题标题】:Json aggregation of data with missing values具有缺失值的数据的 Json 聚合
【发布时间】:2017-03-28 22:18:38
【问题描述】:

我有一个简单的补充表

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

【问题讨论】:

    标签: sql json postgresql psql jsonb


    【解决方案1】:

    示例数据:

    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)
    

    结果可以很容易地聚合到jsonbsee the full example here.

    【讨论】:

    • 天哪。这是惊人的。非常感谢。这正是我一直在寻找的。我以前从未见过交叉连接。
    猜你喜欢
    • 1970-01-01
    • 2011-08-17
    • 1970-01-01
    • 2021-12-12
    • 2019-09-15
    • 2021-02-06
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    相关资源
    最近更新 更多