使用PostgreSQL / JSON执行部门

发布于 2025-02-03 04:44:26 字数 844 浏览 2 评论 0原文

我已经在Postgres数据库中的表上写了一个简单的查询,该查询包含类型JSON的列“清单”。每个单元格包含一个很长的值,我正在提取“大小”的数值。

我需要创建一个新的列(也许称其为“ MB中的大小”),并针对大小执行除法。具体来说,我需要将大小的价值划分为1024,两次。我已经尝试了每个示例我无济于事。

这是我当前的查询,结果是结果:

select customers.name, images.customer_id, images.captured_at, images.name,
 manifest -> 'size' as image_size
from public.images
inner join public.customers on customers.id = images.customer_id
where (captured_at > current_date - interval '12 months')
order BY captured_at desc
Name       customer_id   captured_at   name         image_size
Acme Inc   12345         2022-05-31    Central HMA  628032520  

目标是将image_size除以1024,然后将结果存储在一个称为“ size in Mb in Mb”的新列中。因此,在这种情况下,数学的结果将为598。

I have written a simple query against a table in a Postgres database that contains a column "manifest" of type json. Each cell contains a very long value and I am extracting the numerical value for "size".

I need to create a new column (perhaps call it "size in MB"), and perform division against size. Specifically, I need to take the value of size and divide it by 1024, two times. I have tried every example I can find to no avail.

Here is my current query, and a small snippet of the result:

select customers.name, images.customer_id, images.captured_at, images.name,
 manifest -> 'size' as image_size
from public.images
inner join public.customers on customers.id = images.customer_id
where (captured_at > current_date - interval '12 months')
order BY captured_at desc
Name       customer_id   captured_at   name         image_size
Acme Inc   12345         2022-05-31    Central HMA  628032520  

The goal is to take image_size, divide by 1024 two times, and store the result in a new column called "size in MB". So in this case, the result of the math would be 598.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

阳光下的泡沫是彩色的 2025-02-10 04:44:26

要提取标量值(不是另一个json),请使用 - >> operator (不是- >)。
返回类型文本。因此,您还需要 cast 在数字上进行数学之前:

(manifest ->> 'size')::bigint  -- or numeric? see below!

<

  • a href =“ https://stackoverflow.com/questions/13676816/13676816/postgres-data-type-cast/1367676871 #13676871 “> Postgres数据类型cast

可以 do 整数部门 truncates ,computing 598 像您预测的那样:

SELECT 628032520 / 1024 / 1024  -- 598  -- truncated!

铸造到浮点数或> 数字避免整数部门,并显示您的样本值更接近 599

SELECT 628032520.0 / 2^20  -- 598.9384841918945313  -- precise

数字常数 123解析type type Integer,而123.0(包含一个点)解析为数字
1024 * 1024 = 1048576 = 2^20

也许是圆吗?还是保留两个分数?

SELECT round(628032520.0 / 2^20)     -- 599    -- rounded
     , round(628032520.0 / 2^20, 2)  -- 599.94

考虑内置函数 pg_size_pretty() 是出于此目的而制造的:

SELECT pg_size_pretty(628032520.0)  -- 599 MB  -- formatted text
     , pg_size_pretty(232520.0)     -- 227 kB

所以:

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

应该给您:

customer   customer_id   captured_at   image        image_size
Acme Inc   12345         2022-05-31    Central HMA  599 MB  

我还解决了您的查询其他一些问题。

假设capture_at是类型timestamptz(就像应该是),current_date将引入对会话时区域设置的依赖关系,这是一个偷偷摸摸的,不必要的角案错误来源。请参阅:

)姓名。

To extract a scalar value (not another json) use the ->> operator (not ->).
That returns type text. So you also need to cast before doing math on the number:

(manifest ->> 'size')::bigint  -- or numeric? see below!

See:

You could do integer division, which truncates, computing 598 like you projected:

SELECT 628032520 / 1024 / 1024  -- 598  -- truncated!

Casting to a floating point number or numeric avoids integer division and shows your sample value to be much closer to 599:

SELECT 628032520.0 / 2^20  -- 598.9384841918945313  -- precise

The numeric constant 123 resolves to type integer, while 123.0 (containing a point .) resolves to numeric.
And 1024 * 1024 = 1048576 = 2^20.

Maybe round? Or keep two fractional digits?

SELECT round(628032520.0 / 2^20)     -- 599    -- rounded
     , round(628032520.0 / 2^20, 2)  -- 599.94

But consider the built-in function pg_size_pretty() instead which is made for this very purpose:

SELECT pg_size_pretty(628032520.0)  -- 599 MB  -- formatted text
     , pg_size_pretty(232520.0)     -- 227 kB

So:

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

Should give you:

customer   customer_id   captured_at   image        image_size
Acme Inc   12345         2022-05-31    Central HMA  599 MB  

I also fixed a couple other issues with your query.

Assuming captured_at is type timestamptz (like it probably should be), current_date would introduce a dependency on time zone setting of the session, which is a sneaky, unnecessary source of corner-case errors. See:

And "name" is not a good name.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文