postgresql 如果组中缺少值,则跳过结果行

kh212irz  于 2023-06-29  发布在  PostgreSQL
关注(0)|答案(2)|浏览(132)

我有一个这样的Postgres表:
| 租户ID|订单_今天| orders_today |
| - -----|- -----| ------------ |
| 租客2| 2| 2 |
| 租客1|一个| 1 |
| 租客1| 5个| 5 |
| 租客2| 2| 2 |
| 租客1| 5个| 5 |
请注意,tenant 2的orders_today尚未在时间12:00生成。
我使用这样的查询来汇总今天的订单:

SELECT datetime, SUM(orders_today)
FROM orders
GROUP BY datetime

但这给了我这个结果:
| 总和| sum |
| - -----| ------------ |
| 三个| 3 |
| 七个| 7 |
| 5个| 5 |
如何使其忽略时间12的组,其中缺少租户2的计数?如果可能的话,我可以让它使用租户2从时间11开始的前一个值吗?

pwuypxnk

pwuypxnk1#

如果我理解正确的话,如果缺少租户,您希望排除一组datetime,如果是这样,您可以使用having子句,条件是每个datetime的租户数量必须等于租户总数:

select datetime, sum(orders_today)
from mytable
group by datetime
having count(distinct tenant_id) = (select count(distinct tenant_id) from mytable)
azpvetkf

azpvetkf2#

我可以让它使用租户2从时间11开始的前一个值吗?
假设:

  • (datetime, tenant_id)PRIMARY KEY。因此:UNIQUE和第b列NOT NULL
  • 您需要给定时间范围内的结果。
  • 您需要一组给定租户的结果(示例中的“tenant1”和“tenant2”)。
  • 时间范围内每满一小时需要一行。
  • 用前一小时相同租户的值替换缺失的行。
  • 如果我们不能通过这种方式获得每个租户的订单,则忽略该行。

从tenant & timestamp生成所有感兴趣的组合,LEFT JOIN到您的表,LEFT JOIN到可能的替代品,然后继续:

SELECT datetime, sum(orders) AS sum_orders_today
FROM  (
   SELECT d.datetime, COALESCE(o.orders_today, o1.orders_today) AS orders
   FROM   generate_series(timestamp '2023-06-25 10:00'
                        , timestamp '2023-06-25 13:00'
                        , interval '1 hour') AS d(datetime)    -- given time range
   CROSS  JOIN (VALUES ('tenant1'), ('tenant2')) t(tenant_id)  -- given tenants
   LEFT   JOIN orders o USING (tenant_id, datetime)            -- regular data
   LEFT   JOIN orders o1 ON o1.tenant_id = t.tenant_id         -- substitutes
                        AND o1.datetime  = d.datetime - interval '1 hour'
   ) sub
GROUP  BY 1
HAVING count(orders) = 2  -- omit hours without full data set
ORDER  BY 1;

fiddle
相似:

  • 如何按a,b分组并返回N行b的集合
  • array_agg group by和null

如果我的假设不成立,你得说得更具体些。

相关问题