在UI中,我有一个表,其中显示了按shipday
分组的数据,shipday
是一周中的几天。为了在hasura中做到这一点,我创建了一个PostgreSQL视图-
CREATE
OR REPLACE VIEW "public"."view_shipday" AS
SELECT
shipdata.shipday,
count(*) AS count,
sum(shipdata.delivered) AS delivered,
sum(shipdata.transit) AS transit,
sum(shipdata.refused) AS refused,
sum(shipdata.undeliverable) AS undeliverable,
sum((shipdata.undeliverable + shipdata.refused)) AS total_exceptions
FROM
shipdata
GROUP BY
shipdata.shipday;
现在在UI上,我有两个过滤器carrier
和shipdate
,当用户选择像shipdate
或carrier
或两者的过滤器时,我想通过选择shipday
的过滤器对数据进行分组,但我希望shipday
总是唯一的(这很重要)。
CREATE
OR REPLACE VIEW "public"."view_shipday_and_filter" AS
SELECT
shipdata.shipday,
date(shipdata.shipdate),
shipdata.carrier,
count(*) AS count,
sum(shipdata.delivered) AS delivered,
sum(shipdata.transit) AS transit,
sum(shipdata.refused) AS refused,
sum(shipdata.undeliverable) AS undeliverable,
sum((shipdata.undeliverable + shipdata.refused)) AS total_exceptions
FROM
shipdata
GROUP BY
shipdata.shipday,
date(shipdata.shipdate),
shipdata.carrier;
AFAIK hasura不允许对他们的graphql查询进行分组。我不想在客户端进行分组,因为数据量非常大,会降低应用程序的速度。因此,我想在数据库中创建一个或多个(如果需要)视图,这些视图将对处理上述情况的数据进行分组,以便shipday
始终保持唯一。如果有其他选择,以实现这一点,而不创建视图,我也开放。
2条答案
按热度按时间rxztt3cl1#
查询视图和运行定义视图的查询在性能上没有区别。事实上,PostgreSQL在运行查询时会用视图的定义替换视图。
您可以在问题的末尾使用视图,并向使用视图的查询添加额外的
GROUP BY
和求和,但这会使视图中的GROUP BY
变得毫无意义,实际上会使查询变慢。我的意见是,在这种情况下使用视图没有任何好处,因为过滤条件需要在分组之前应用,所以唯一的选择是直接查询
shipdata
,然后在应用查询中进行分组和求和。您对此只字未提,但如果问题的一部分是此查询的性能太慢,则必须使用视图以外的其他工具。在这种情况下,可以选择使用通过“部分聚集”查询定义的 * 实体化视图 *,并在应用程序查询中执行最终过滤和分组。预聚集的实体化视图将小于基表。缺点是当
shipdata
中的数据发生变化时,物化视图也不会发生变化,因此您必须定期对物化视图进行REFRESH
,并在两者之间使用稍微陈旧的数据。n8ghc7c12#
要获取 * 未筛选 * 发货日报告,您必须使用此查询(请参阅下面的示例数据)
要获得带有 * 筛选器 * 的报告,例如
carrier = 'a'
,必须添加where
predicate ,但仍按shipday
分组无论如何,您可以使用一个函数来优雅地覆盖此特性。
该函数获取一个参数来过滤
carrier
(如果定义),默认值是获取所有载波。样本调用
这当然是最简单的示例,但希望您了解如何为更高级的过滤器添加其他参数或其他函数。
此外,您可能希望在函数中添加
if
then
逻辑,并为不同类型的过滤器定义专用查询。样本数据