标签: cast

在 PostgreSQL 中查询 JSONB

我有一个表,persons它包含两列,一个id和一个基于 JSONB 的data列(这个表只是为了演示目的而制作的,以使用 PostgreSQL 的 JSON 支持)。

现在,假设它包含两条记录:

1, { name: 'John', age: 30 }
2, { name: 'Jane', age: 20 }
Run Code Online (Sandbox Code Playgroud)

现在,假设我想得到每个 25 岁以上的人的名字。我尝试过的是:

select data->'name' as name from persons where data->'age' > 25
Run Code Online (Sandbox Code Playgroud)

不幸的是,这会导致错误。我可以通过使用->>代替来解决它->,但是比较不再按预期工作,因为不是比较数字,而是比较它们作为字符串的表示:

select data->'name' as name from persons where data->>'age' > '25'
Run Code Online (Sandbox Code Playgroud)

然后我发现我实际上可以通过使用->和强制转换来解决这个问题int

select data->'name' as name from persons where cast(data->'age' as int) > 25
Run Code Online (Sandbox Code Playgroud)

这有效,但我必须知道实际类型并不是那么好(ageJSON 文档中的类型是number无论如何,那么为什么 PostgreSQL …

postgresql cast json operator postgresql-9.5

23
推荐指数
1
解决办法
3万
查看次数

从 count() 确定百分比没有转换问题

我正在尝试运行以下查询以提供patients表中具有refinst列值的行的百分比。我一直得到0的结果。

select (count (refinst) / (select count(*) from patients) * 100) as "Formula" 
from patients;
Run Code Online (Sandbox Code Playgroud)

该表有 15556 行,并select count(refinst) from patients告诉我其中 1446行在列中有值refinst。我想从查询中得到的响应是 30.62 ( 1446/15556*100=30.62XXXXX,四舍五入到两位小数)。

我很确定它与计数结果的数据类型(我假设是整数)有关。如果我将一个整数除以一个整数并且结果小于 0,它会被截断为 0 是否正确?如果是这种情况,有人可以告诉我如何将计数结果转换为带有 2 个小数位的数字,以便结果也四舍五入到 2 个小数位吗?

我确信有比多个 count 语句更好的方法来编写此代码。我正在寻找一种更高效的方式来编写这个查询。

postgresql datatypes count cast

22
推荐指数
2
解决办法
4万
查看次数

如何将ctid分解为页码和行号?

表中的每一行都有一个系统列 ctid,其类型tid表示该行的物理位置:

create table t(id serial);
insert into t default values;
insert into t default values;
Run Code Online (Sandbox Code Playgroud)
select ctid
     , id
from t;
Run Code Online (Sandbox Code Playgroud)
ctid | ID
:---- | -:
(0,1) | 1
(0,2) | 2

dbfiddle在这里

ctid最合适的类型(例如integerbigintnumeric(1000,0))中获取页码的最佳方法是什么?

我能想到的唯一的办法是非常难看。

postgresql data-pages datatypes cast postgresql-9.4

19
推荐指数
1
解决办法
1万
查看次数

在 SQL Server 中本地解码 Base64 字符串

varchar在 SQL Server 的表中有一个列,其中包含一个 base64 编码的文本字符串,我想将其解码为纯文本等效项

SQL Server 是否具有处理此类事情的任何本机功能?

一个示例 base64 字符串:

cm9sZToxIHByb2R1Y2VyOjEyIHRpbWVzdGFtcDoxNDY4NjQwMjIyNTcxMDAwIGxhdGxuZ3tsYXRpdHVkZV9lNzo0MTY5ODkzOTQgbG9uZ2l0dWRlX2U3Oi03Mzg5NjYyMTB9IHJhZGl1czoxOTc2NA==
Run Code Online (Sandbox Code Playgroud)

解码为:

role:1 producer:12 timestamp:1468640222571000 latlng{latitude_e7:416989394 longitude_e7:-738966210} radius:19764
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql sql-server-2008-r2 cast string-manipulation

19
推荐指数
1
解决办法
6万
查看次数

PostgreSQL 替代 SQL Server 的 `try_cast` 函数

Microsoft SQL Server 有一个我认为非常明智的函数,如果转换不成功,try_cast()它返回一个null,而不是引发错误。

这使得可以使用CASE表达式或 acoalesce来回退。例如:

SELECT coalesce(try_cast(data as int),0);
Run Code Online (Sandbox Code Playgroud)

问题是,PostgreSQL 有没有类似的东西?

提出这个问题是为了填补我知识中的一些空白,但也有一个一般原则,即有些人更喜欢对某些用户错误做出不那么剧烈的反应。null在 SQL 中返回 a比错误更容易。例如SELECT * FROM data WHERE try_cast(value) IS NOT NULL;。根据我的经验,如果有 B 计划,有时可以更好地处理用户错误。

postgresql datatypes error-handling cast

13
推荐指数
2
解决办法
1万
查看次数

为什么我需要将 NULL 转换为列类型?

我有一个助手,它正在生成一些代码来为我进行批量更新,并生成如下所示的 SQL:

( active 和 core 字段都是 type boolean

UPDATE fields as t set "active" = new_values."active","core" = new_values."core"
FROM (values 
(true,NULL,3419),
(false,NULL,3420)
) as new_values("active","core","id") WHERE new_values.id = t.id;
Run Code Online (Sandbox Code Playgroud)

但是它失败了:

ERROR: column "core" is of type boolean but expression is of type text

我可以通过添加::boolean空值来让它工作,但这看起来很奇怪,为什么 NULL 被认为是类型TEXT

此外,转换有点棘手,因为它需要对代码进行大量修改才能知道它应该将 NULL 转换为什么类型(列和值的列表目前是从一个简单的 JSON 对象数组自动生成的) .

为什么这是必要的,是否有更优雅的解决方案,不需要生成代码知道 NULL 的类型?

如果相关,我将在Node.JS上使用sequelize来执行此操作,但在 Postgres 命令行客户端中也得到相同的结果。

postgresql null cast

12
推荐指数
1
解决办法
6574
查看次数

带有类型修饰符的数据类型的惊人结果

在讨论这个问题的递归 CTE 解决方案时:

@ypercube偶然发现了一个令人惊讶的异常,这导致我们调查类型修饰符的处理。我们发现了令人惊讶的行为。

1. 类型转换在某些上下文中保留了类型修饰符

即使被指示不要这样做。最基本的例子:

SELECT 'vc8'::varchar(8)::varchar
Run Code Online (Sandbox Code Playgroud)

人们可能会期望varchar(没有修饰符),至少我会。但结果是varchar(8)(带修饰符)。下面的小提琴中有许多相关的案例。

2. 数组连接在某些情况下失去了类型修饰符

不需要,所以这在相反的一面出错:

SELECT ARRAY['vc8']::varchar(8)[]
     , ARRAY['vc8']::varchar(8)[] || 'vc8'::varchar(8)
Run Code Online (Sandbox Code Playgroud)

第一个表达式varchar(8)[]按预期产生。
但是第二个,在连接另一个之后varchar(8)被淡化到只是varchar[](没有修饰符)。来自array_append(),下面小提琴中的示例的类似行为。

在大多数情况下,所有这些都无关紧要。Postgres 不会丢失数据,并且当分配给列时,该值无论如何都会被强制转换为正确的类型。然而,相反方向的错误最终会导致一个令人惊讶的异常:

3. 递归 CTE 要求数据类型完全匹配

鉴于此简化表:

CREATE TABLE a (
  vc8  varchar(8)  -- with modifier
, vc   varchar     -- without  
);
INSERT INTO a VALUES  ('a',  'a'), ('bb', 'bb');
Run Code Online (Sandbox Code Playgroud)

虽然此 rCTE 对varchar列有效vc,但对 …

postgresql datatypes cte debugging cast

11
推荐指数
1
解决办法
1825
查看次数

如何在 Postgresql 中转换为 int 数组?

我想从 ARGV[] 转换到 PostgreSQL 中的 int 数组,我在代码中用TODO标记了伪代码。x86_64-unknown-linux-gnu 上 PostgreSQL 9.4.3 中的代码,由 gcc (Debian 4.9.2-10) 4.9.2 编译,64 位:

CREATE TABLE measurements (
        measurement_id SERIAL PRIMARY KEY NOT NULL,
        measurement_size_in_bytes INTEGER NOT NULL
);

CREATE TABLE events (
        event_id SERIAL PRIMARY KEY NOT NULL, 
        measurement_id INTEGER NOT NULL, 
        event_index_start INTEGER NOT NULL,
        event_index_end INTEGER NOT NULL
);

CREATE OR REPLACE FUNCTION insaft_function() 
    RETURNS TRIGGER AS 
$func$
BEGIN 
  -- TODO Loop until TG_ARGV[0] empty
INSERT INTO events (measurement_id, event_index_start, event_index_end) 
SELECT …
Run Code Online (Sandbox Code Playgroud)

postgresql insert plpgsql cast array

9
推荐指数
1
解决办法
6万
查看次数

PostgreSQL 中的一字节“char”类型究竟是如何工作的?

我经常看到人们谈论"char"。我从来没有用过它。它在文档中定义为,

“char”类型(注意引号)与 char(1) 的不同之处在于它只使用一个字节的存储空间。它在系统目录中作为一种简单的枚举类型在内部使用。

并进一步,

"char"  1 byte  single-byte internal type
Run Code Online (Sandbox Code Playgroud)

那么,如果它是一个字节,那么域是什么,您将如何使用它?它是签名的还是未签名的?在@Erwin Brandstetter 的这篇文章中,他对此进行了阐述,但我仍然感到困惑。他正在使用ascii()and chr(),并提供了这个

SELECT i
     , chr(i)::"char"        AS i_encoded
     , ascii(chr(i)::"char") AS i_decoded
FROM   generate_series(1,256) i;
Run Code Online (Sandbox Code Playgroud)

这在 10 点到 11 点之间做一些非常奇怪的事情。

  i  | i_encoded | i_decoded 
-----+-----------+-----------
...
   8 | \x08      |         8
   9 |           |         9
  10 |          +|        10
     |           |           -- WTF is going on here.
  11 | \x0B      |        11
  12 | \x0C      |        12 …
Run Code Online (Sandbox Code Playgroud)

postgresql datatypes storage cast

9
推荐指数
1
解决办法
1998
查看次数

为什么从双精度到数字的转换会四舍五入到 15 位有效数字?

double precision从( float8) 到numeric四舍五入到 15 个有效小数位的转换,从而丢失信息。显然,更高的精度是可能的。转换为bigint(对于其范围内的值)可以保留更高的精度:

SELECT f8          AS float8
     , f8::bigint  AS to_bigint
     , f8::numeric AS to_numeric
FROM  (
   VALUES
     ('8217316934885843456'::float8)
   , ('8217316934885843457')
   , ('8217316934885844479')
   , ('8217316934885844480')   
   , ('8217316934885845503')
   , ('8217316934885845584')   
   ) t(f8);

        float8         |      to_bigint      |     to_numeric      
-----------------------+---------------------+---------------------
 8.217316934885843e+18 | 8217316934885842944 | 8217316934885840000
 8.217316934885844e+18 | 8217316934885843968 | 8217316934885840000
 8.217316934885844e+18 | 8217316934885843968 | 8217316934885840000
 8.217316934885845e+18 | 8217316934885844992 | 8217316934885840000
 8.217316934885845e+18 | 8217316934885844992 | 8217316934885840000
 8.217316934885846e+18 | 8217316934885846016 | 8217316934885850000
(6 rows)
Run Code Online (Sandbox Code Playgroud)

db<>在这里摆弄 …

postgresql floating-point cast

9
推荐指数
1
解决办法
3780
查看次数