是否可以INSERT从SELECT语句DEFAULT中将值放入 PostgreSQL 表并使用空列的值?
就我而言,该SELECT语句是从 JSON 中选择的。
在下面的尝试中,我通过显式检索序列取得了成功,但我希望有一种方法可以使用 DEFAULT 值进行 INSERT。或者选择 DEFAULT 值而不必显式调用默认函数。
-- Example table
create table animals
(
id serial,
nm character varying (30) NOT NULL, --name
typ character varying(10),
tvi integer,
tvf numeric(8,3)
);
insert into animals VALUES (DEFAULT,'mouse','m',4,12.45);
select row_to_json(a) from animals a;
select * from json_populate_record(null::animals,'{"id":null,"nm":"mouse","typ":"m","tvi":4,"tvf":12.450}');
--All good.
-- Attempt #1
INSERT INTO animals
select id ,nm,typ,tvi,tvf from json_populate_record(null::animals,'{"id":null,"nm":"mouse","typ":"m","tvi":4,"tvf":12.450}');
/*
ERROR: null value in column "id" violates not-null …Run Code Online (Sandbox Code Playgroud) 我在 PostgreSQL 中有一个包含一些数据的表:
create table t2 (
key jsonb,
value jsonb
);
INSERT INTO t2(key, value)
VALUES
('1', '"test 1"')
,('2', '"test 2"')
,('3', '"test 3"')
,('[]', '"test 4"')
,('[1]', '"test 5"')
,('[2]', '"test 6"')
,('[3]', '"test 7"')
,('[1, 2]', '"test 8"')
,('[1, 2, 3]', '"test 9"')
,('[1, 3]', '"test 10"')
,('[1,2,4]', '"test 11"')
,('[1, 2,4]', '"test 12"')
,('[1,3,13]', '"test 13"')
,('[1, 2, 15]', '"test 15"');
Run Code Online (Sandbox Code Playgroud)
我尝试像这样对这些行进行排序:
SELECT key FROM t2 order by key;
Run Code Online (Sandbox Code Playgroud)
结果是:
[]
1
2
3
[1] …Run Code Online (Sandbox Code Playgroud) 我觉得我需要json_object_agg()Postgres 9.4的功能,但我现在无法从 9.3 升级。有没有办法在 9.3 中做我想做的事?这是我的场景。我有一个click_activity看起来像的数据表
user | offer | clicks
-----|-------|--------
fred |coupons| 3
fred |cars | 1
john |coupons| 2
Run Code Online (Sandbox Code Playgroud)
但我想把它变成这个:(聚合每个用户的活动)
user | activity
-----|----------
fred | {"coupons": 3, "cars": 1}
john | {"coupons": 2}
Run Code Online (Sandbox Code Playgroud)
我认为json_object_agg()Postgres 9.4的功能可以完美地做到这一点,我只需要调用
select user, json_object_agg(offer, clicks) from click_activity group by 1
Run Code Online (Sandbox Code Playgroud)
有没有办法在 9.3 中做到这一点?谢谢!
这很好地说明了这个问题:
当 b 列是文本类型而不是数组时,以下工作:
select *
from json_to_record('{"a":1,"b":["hello", "There"],"c":"bar"}')
as x(a int, b text, d text);
a | b | d
---+--------------------+---
1 | ["hello", "There"] |
Run Code Online (Sandbox Code Playgroud)
但是,如果我将该b列定义为数组,则会出现此错误:
select *
from json_to_record('{"a":1,"b":["hello", "There"],"c":"bar"}')
as x(a int, b text[], d text)
ERROR: malformed array literal: "["hello", "There"]"
DETAIL: "[" must introduce explicitly-specified array dimensions.
Run Code Online (Sandbox Code Playgroud)
如何说服/强制json_to_record(或json_populate_record)将 JSON 数组转换为目标列类型的 Postgres 数组?
我有一个带有如下表的 PostgreSQL 9.5.3 DB:
container
id: uuid (pk)
... other data
thing
id: uuid (pk)
... other data
container_thing
container_id: uuid (fk)
thing_id: uuid (fk)
primary key (container_id, thing_id)
Run Code Online (Sandbox Code Playgroud)
Acontainer可以指向任意数量的things(没有重复),并且 athing可以被任意数量的containers指向。
可能有大量的容器和东西(取决于我们有多少客户)。每个容器中可能只有 1 到 10 个东西。我们一次最多只能查询大约 20 个容器。一个容器可以是空的,我需要取回一个空数组。
我需要构建代表容器的 json 对象,如下所示:
{
"id": "d7e1bc6b-b659-432d-b346-29f3a530bfa9",
... other data
"thingIds": [
"4e3ad81b-f2b5-4220-8e0e-e9d53c80a214",
"f26f49e5-76b4-4363-9ffe-9654ba0b0f0d"
]
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我通过使用两个查询来做到这一点:
select * from "container" where "id" in (<list of container ids>)
select * from "container_thing" where "container_id" in …Run Code Online (Sandbox Code Playgroud) 我正在尝试将csv包含表数据的文件导入 postgres 。表的列之一具有jsonb类型。
我的csv文件的一行包含类似
1,{"a":"b"}
Run Code Online (Sandbox Code Playgroud)
假设表有一个模式
id | smallint |
data | jsonb |
Run Code Online (Sandbox Code Playgroud)
如果我只是尝试插入数据,一切正常
INSERT INTO table VALUES (1, '{"a":"b"}');
Run Code Online (Sandbox Code Playgroud)
尝试直接从文件导入
COPY table FROM '/path/to/file.csv' DELIMITER ',' csv;
Run Code Online (Sandbox Code Playgroud)
给了我以下错误:
ERROR: invalid input syntax for type json
DETAIL: Token "a" is invalid.
CONTEXT: JSON data, line 1: {a...
COPY availability, line 1, column services: "{a: b}"
Run Code Online (Sandbox Code Playgroud)
我试图用', with ", with\"和\',但没有任何效果。
哪个是正确的语法呢?
我正在尝试构建一个查询以将旧表中的多个列聚合在一起,该表存储在类似的结构中,如下所示:
CREATE TEMPORARY TABLE foo AS
SELECT * FROM ( VALUES
(1,'Router','Networking','Sale',NULL),
(2,NULL,'Router','Networking','Sale'),
(3,NULL,NULL,'Networking','Sale'),
(4,NULL,NULL,NULL,NULL)
) AS t(id,tag_1,tag_2,tag_3,tag_4);
Run Code Online (Sandbox Code Playgroud)
这是我要构建的查询的示例:
SELECT ID, json_build_array(Tag_1, Tag_2, Tag_3, Tag_4) AS tags
FROM table
Run Code Online (Sandbox Code Playgroud)
问题是上面的查询将行中的 NULL 值添加到数组中:
ID Tags
--------------------------------------------------
1 ['Router', 'Networking', 'Sale', null]
2 [null, 'Router', 'Networking', 'Sale']
3 [null, null, 'Networking', 'Sale']
4 [null, null, null, null]
Run Code Online (Sandbox Code Playgroud)
我想避免编写过于复杂的CASE WHEN语句来过滤掉 NULL,而且我对使用 PostgreSQL 的 JSON 数据类型还是个新手。在 Postgres 中构建 JSON 数组时,是否可以避免包含 NULL?
给定band表格,其中一json列包含一个数组:
id | people
---+-------------
1 | ['John', 'Thomas']
2 | ['John', 'James']
3 | ['James', 'George']
Run Code Online (Sandbox Code Playgroud)
如何列出每个名称所属的乐队数量?
期望的输出:
name | count
-------+------------
John | 2
James | 2
Thomas | 1
George | 1
Run Code Online (Sandbox Code Playgroud) 我想验证一json[]列the_array不为空。对于普通数组,我可以检查:
the_array != '{}'
Run Code Online (Sandbox Code Playgroud)
但是,这不适用于 a json[],如下所示:
select '{}'::json[] != '{}'
ERROR: could not identify an equality operator for type json
Run Code Online (Sandbox Code Playgroud)
我可以改用以下检查:
array_length(the_array, 1) != null // yes, array_length on an
empty array returns null
Run Code Online (Sandbox Code Playgroud)
我担心这array_length()会遍历整个数组以计算项目数,然后返回该计数。就我而言,我不需要数组的实际大小,我只需要知道它是否为空。
那么,是否array_length()遍历整个数组?如果是这样,是否有更好的方法来检查 json 数组是否为空?
json 字段的大小限制为 1GB(来源:此 StackOverflow 答案):
json与数据类型相同text,但具有 JSON 验证。数据text类型的最大大小为 1GB。
我进行了一些实验,将json不同大小的数据插入到 Postgres 的表中。这里的行pg_sizeof似乎表明 Postgres 对 json 数据进行了压缩。
我的实验:
create table json_size (n integer, j json);
Run Code Online (Sandbox Code Playgroud)
值为n1、10、100、1000、10 000、100 000、1 000 000。
with q as (select generate_series(1, n)::bigint as x)
insert into json_size (n, j)
select 1, coalesce(json_agg(to_json(q.*)), '[]'::json) from q;
Run Code Online (Sandbox Code Playgroud)
select n, pg_column_size(j) as size from json_size;
Run Code Online (Sandbox Code Playgroud)
结果
n size
1 10
10 92
100 996
1000 3224
10000 …Run Code Online (Sandbox Code Playgroud)