Postgresql查询/分组和求和

Postgresql query / Group by and sum

昨天刚进群,已经收到大家的宝贵意见了。我有另一种情况,我需要一些推动。我昨天收到的建议解决了我的第一个问题,但我有第二种情况我想尝试实施。

我有以下 Postgresql 查询,将 json 列类型的“大小”值从字节转换为 MB:

SELECT c.name AS customer, i.customer_id, i.captured_at, i.name AS image, 
i.raw_upload_complete
, pg_size_pretty((i.manifest ->> 'size')::numeric) AS image_size
FROM   public.images i
JOIN   public.customers c ON c.id = i.customer_id
WHERE  i.raw_upload_complete = 'true' AND captured_at > date_trunc('day', now()) - 
interval '2 months'
ORDER  BY customer ASC

这是一个输出示例:

Customer   Customer ID  captured_at  image        raw_upload_complete   image_size
Customer 1  250         2022-05-09   Ventures Pit       TRUE              4044 MB
Customer 1  250         2022-06-01   Ventures Pit       TRUE              500 MB
Customer 2  85          2022-04-18   Devault Quarry     TRUE              672 MB
Customer 2  85          2022-05-02   Talmage Quarry     TRUE              3876 MB

查询效果很好,但是,我想做的是按客户对结果集进行分组,然后对每个客户的 image_size 求和。所以在上面的示例中,我希望按原样对客户进行分组,反映客户 1 的总图像大小为 4544 MB,客户 2 的总图像大小为 4548 MB。理想情况下,我希望每个客户都汇总在一行中,或者以某种高级汇总方式进行汇总。

我在第一个 post 中提到我在 SQL 还很陌生,所以解决方案可能很明显,但我一直在努力解决这个问题。我试过交叉表功能无济于事,但我不确定是否有更好的选择。似乎一直给我带来问题的是,创建的 image_size 列显示为 TEXT,而不是数字,这一直导致问题。我一直在使用 Google Data Studio 并认为简单地更改数据类型会有所帮助,但即使它可以让我将其更改为数字,它仍然被识别为文本字段。

非常感谢。

我要逆向进行。首先,让我们编写一个查询,按客户

获取图像总大小
select c.id, pg_size_pretty(sum((i.manifest ->> 'size')::numeric)) as total
from images i
join customers c on i.customer_id = c.id
where [snippped]
group by c.id

请注意,您要执行 sum(),然后 然后 应用 pg_size_pretty。那是因为 pg_size_pretty() 的结果里面会有 "MB"、"GB" 的东西,所以它实际上是文本而不是数字了。

现在我们可以将该查询用作 CTE 来获得您想要的结果

with total_size as (
  select c.id, pg_size_pretty(sum((i.manifest ->> 'size')::numeric)) as total
  from images i
  join customers c on i.customer_id = c.id
  where [snippped]
  group by c.id
) as total

SELECT c.name AS customer, i.customer_id, i.captured_at, i.name AS image, 
i.raw_upload_complete
, total_size.total
FROM   public.images i
JOIN   public.customers c ON c.id = i.customer_id
JOIN   total_size on c.id = total_size.id
WHERE  i.raw_upload_complete = 'true' AND captured_at > date_trunc('day', now()) - 
interval '2 months'
ORDER  BY customer ASC

因此,如果您仔细观察,您会发现我们对“总计”CTE 进行了额外的连接,并且 SELECT 子句使用了 CTE 中的“总计”值。

之所以必须分两步执行此操作,是因为您想要的结果混合了详细图像数据(例如“captured_at”)和摘要图像数据(总大小)。那种混合让很多正在学习的人感到困惑SQL。