如何强制 postgres 到 return 0 即使没有匹配查询的行,使用合并、分组依据和连接
How to force postgres to return 0 even if there are no rows matching query, using coalesce, group by and join
我一直在绝望地尝试将以下 SQL 语句添加到 return 查询结果中,如果没有与查询匹配的行,则默认为 0。
这是预期的结果:
vol | year
-------+------
0 | 2018
相反,我得到:
vol | year
-----+------
(0 rows)
这里是 sql 语句:
select coalesce(vol,0) as vol, year
from (select sum(vol) as vol, year
from schema.fact_data
join schema.period_data
on schema.fact_data.period_tag = schema.period_data.tag
join schema.product_data
on schema.fact_data.product_tag =
schema.product_data.tag
join schema.market_data
on schema.fact_data.market_tag = schema.market_data.tag
where "retailer"='MadeUpRetailer'
and "product_tag"='FakeProductTag'
and "year"='2018' group by year
) as DerivedTable;
我知道查询有效,因为它 return 有数据时就有数据。只是没有按预期默认为 0...
如果能帮助找出为什么会这样,我们将不胜感激!
使用您的子查询 DerivedTable
,您可以这样写:
SELECT coalesce(DerivedTable.vol, 0) AS vol,
y.year
FROM (VALUES ('2018'::text)) AS y(year)
LEFT JOIN (SELECT ...) AS DerivedTable
ON DerivedTable.year = y.year;
根据您发布的代码,不清楚 table 中有 year
列。
您可以使用 UNION 仅获取 1 行,以防 2018 年 table 中没有行,如下所示:
select sum(vol) as vol, year
from schema.fact_data innrt join schema.period_data
on schema.fact_data.period_tag = schema.period_data.tag
inner join schema.product_data
on schema.fact_data.product_tag = schema.product_data.tag
inner join schema.market_data
on schema.fact_data.market_tag = schema.market_data.tag
where
"retailer"='MadeUpRetailer' and
"product_tag"='FakeProductTag' and
"year"='2018'
group by "year"
union
select 0 as vol, '2018' as year
where not exists (
select 1 from tablename where "year" = '2018'
)
如果有 2018 年的行,那么第二次查询将不会获取任何内容,
删除 GROUP BY
(和外部查询):
select 2018 as year, coalesce(sum(vol), 0) as vol
from schema.fact_data f join
schema.period_data p
on f.period_tag = p.tag join
schema.product_data pr
on f.product_tag = pr.tag join
schema.market_data m
on fd.market_tag = m.tag
where "retailer" = 'MadeUpRetailer' and
"product_tag" = 'FakeProductTag' and
"year" = '2018';
没有 GROUP BY
的聚合查询总是 returns 恰好一行,所以这应该做你想要的。
编辑:
查询看起来像这样:
select v.yyyy as year, coalesce(sum(vol), 0) as vol
from (values (2018), (2019)) v(yyyy) left join
schema.fact_data f
on f.year = v.yyyy left join -- this is just an example. I have no idea where year is coming from
schema.period_data p
on f.period_tag = p.tag left join
schema.product_data pr
on f.product_tag = pr.tag left join
schema.market_data m
on fd.market_tag = m.tag
group by v.yyyy
但是,您必须将 where
条件移动到适当的 on
子句中。我不知道这些列来自哪里。
我一直在绝望地尝试将以下 SQL 语句添加到 return 查询结果中,如果没有与查询匹配的行,则默认为 0。
这是预期的结果:
vol | year
-------+------
0 | 2018
相反,我得到:
vol | year
-----+------
(0 rows)
这里是 sql 语句:
select coalesce(vol,0) as vol, year
from (select sum(vol) as vol, year
from schema.fact_data
join schema.period_data
on schema.fact_data.period_tag = schema.period_data.tag
join schema.product_data
on schema.fact_data.product_tag =
schema.product_data.tag
join schema.market_data
on schema.fact_data.market_tag = schema.market_data.tag
where "retailer"='MadeUpRetailer'
and "product_tag"='FakeProductTag'
and "year"='2018' group by year
) as DerivedTable;
我知道查询有效,因为它 return 有数据时就有数据。只是没有按预期默认为 0...
如果能帮助找出为什么会这样,我们将不胜感激!
使用您的子查询 DerivedTable
,您可以这样写:
SELECT coalesce(DerivedTable.vol, 0) AS vol,
y.year
FROM (VALUES ('2018'::text)) AS y(year)
LEFT JOIN (SELECT ...) AS DerivedTable
ON DerivedTable.year = y.year;
根据您发布的代码,不清楚 table 中有 year
列。
您可以使用 UNION 仅获取 1 行,以防 2018 年 table 中没有行,如下所示:
select sum(vol) as vol, year
from schema.fact_data innrt join schema.period_data
on schema.fact_data.period_tag = schema.period_data.tag
inner join schema.product_data
on schema.fact_data.product_tag = schema.product_data.tag
inner join schema.market_data
on schema.fact_data.market_tag = schema.market_data.tag
where
"retailer"='MadeUpRetailer' and
"product_tag"='FakeProductTag' and
"year"='2018'
group by "year"
union
select 0 as vol, '2018' as year
where not exists (
select 1 from tablename where "year" = '2018'
)
如果有 2018 年的行,那么第二次查询将不会获取任何内容,
删除 GROUP BY
(和外部查询):
select 2018 as year, coalesce(sum(vol), 0) as vol
from schema.fact_data f join
schema.period_data p
on f.period_tag = p.tag join
schema.product_data pr
on f.product_tag = pr.tag join
schema.market_data m
on fd.market_tag = m.tag
where "retailer" = 'MadeUpRetailer' and
"product_tag" = 'FakeProductTag' and
"year" = '2018';
没有 GROUP BY
的聚合查询总是 returns 恰好一行,所以这应该做你想要的。
编辑:
查询看起来像这样:
select v.yyyy as year, coalesce(sum(vol), 0) as vol
from (values (2018), (2019)) v(yyyy) left join
schema.fact_data f
on f.year = v.yyyy left join -- this is just an example. I have no idea where year is coming from
schema.period_data p
on f.period_tag = p.tag left join
schema.product_data pr
on f.product_tag = pr.tag left join
schema.market_data m
on fd.market_tag = m.tag
group by v.yyyy
但是,您必须将 where
条件移动到适当的 on
子句中。我不知道这些列来自哪里。