我觉得我需要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 数组?
我在 Mac (10.10.4) 上运行 postgres (postgis) 9.4.2。
我有几张大桌子(几个 TB)。
在其中一个索引构建过程中大约需要一周时间,我看到可用的高清空间下降,正如您所期望的那样,当停电时间比电池单元和系统持续时间更长时索引将完成下楼。我fillfactor=100
在构建期间关闭了缓冲区,因为它是一个静态数据源。重新启动时,驱动器上剩余的可用空间正是索引构建接近结束时的位置。真空分析不会释放空间。
我尝试放下桌子并重新摄取,但并没有减少空间。现在我所在的地方没有足够的空间来构建索引。
索引构建期间生成的文件是否由于停电期间机器停机的方式而无法被系统删除?
当我查看数据库中的表大小 + 索引(这是该驱动器上唯一的数据)时,它们加起来大约6TB。驱动器为8TB,驱动器上剩余的空间不足500GB,因此似乎在某处丢失了大约 1.5TB,这与索引的大小差不多。
有任何想法吗?
我有一张桌子articles
:
Table "articles"
Column | Type | Modifiers | Storage | Stats target | Description
----------------+-----------------------------+----------------------------------------------------+----------+--------------+-------------
id | integer | not null default nextval('articles_id_seq'::regclass) | plain | |
user_id | integer | | plain | |
title | character varying(255) | | extended | |
author | character varying(255) | | extended | |
body | text | default '--- [] +| extended | |
| | '::text | | |
created_at | timestamp without time zone | …
Run Code Online (Sandbox Code Playgroud) postgresql performance datatypes postgresql-9.4 query-performance
我使用以下查询来查找未使用的索引:
SELECT
PSUI.indexrelid::regclass AS IndexName
,PSUI.relid::regclass AS TableName
FROM pg_stat_user_indexes AS PSUI
JOIN pg_index AS PI
ON PSUI.IndexRelid = PI.IndexRelid
WHERE PSUI.idx_scan = 0
AND PI.indisunique IS FALSE;
Run Code Online (Sandbox Code Playgroud)
在运行之前我应该运行任何统计收集语法或其他任何内容吗?上述查询可以用于此目的吗?我的意思是,那么 SQL 输出中显示的所有索引都应该被删除吗?
这是一个已有 8 年历史的 BD,因此结果行可能实际上是遗留下来的,我想应该有足够的统计数据,以便告诉在哪里使用 和 。
我有下表:
create table test (
company_id integer not null,
client_id integer not null,
client_status text,
unique (company_id, client_id)
);
insert into test values
(1, 1, 'y'), -- company1
(2, 2, null), -- company2
(3, 3, 'n'), -- company3
(4, 4, 'y'), -- company4
(4, 5, 'n'),
(5, 6, null), -- company5
(5, 7, 'n')
;
Run Code Online (Sandbox Code Playgroud)
基本上,有 5 家不同的公司,每家公司都有一个或多个客户,每个客户的状态为:“y”或“n”(也可能为空)。
我必须做的是为(company_id, client_id)
至少有一个客户的状态不是“n”(“y”或 null)的所有公司选择所有对。所以对于上面的示例数据,输出应该是:
company_id;client_id
1;1
2;2
4;4
4;5
5;6
5;7
Run Code Online (Sandbox Code Playgroud)
我尝试了一些使用窗口函数的东西,但我无法弄清楚如何将所有客户端的数量与带有STATUS = 'n'
.
select company_id,
count(*) over (partition …
Run Code Online (Sandbox Code Playgroud) 使用 PostgreSQL 9.4,我想要一个只考虑min()
距离 onJOIN
或 的(所有聚合函数)值的结果WHERE
。但似乎这些事情是不允许的。所以,我选择两点之间的距离,我想过滤它只是为了考虑这些min()
值。
为了清楚地继续这个问题,假设这些行:
id; gid; distance; time_interval
142; 028; 62; "21:46:00"
200; 028; 53; "08:20:11"
128; 034; 92; "09:24:43"
179; 034; 70; "08:09:34"
194; 034; 92; "05:31:05"
199; 034; 88; "07:15:48"
200; 034; 61; "14:13:43"
202; 035; 24; "17:32:34"
200; 036; 76; "06:02:11"
154; 037; 97; "12:58:58"
154; 040; 30; "11:34:10"
132; 042; 80; "07:01:12"
142; 042; 67; "19:30:21"
Run Code Online (Sandbox Code Playgroud)
我怎样才能提取id
, gid
,distance
和time_interval
只考虑min(time_interval) …
我面临以下错误:
Run Code Online (Sandbox Code Playgroud)ERROR: functions in index expression must be marked IMMUTABLE
尝试创建这样的索引时:
CREATE INDEX full_phone_number ON orders_clientphone (concat(area_code, phone));
Run Code Online (Sandbox Code Playgroud)
另一方面,当使用替代语法进行连接时:
CREATE INDEX full_phone_number ON orders_clientphone ((area_code || phone));
Run Code Online (Sandbox Code Playgroud)
Postgres 对此非常满意。
两列都定义为character varying(256)
。
我正在尝试构建一个查询以将旧表中的多个列聚合在一起,该表存储在类似的结构中,如下所示:
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?
像这样的查询
SELECT a.id, a.name,
COALESCE( json_agg(b.*), '[]'::json ),
COALESCE( json_agg(c.*), '[]'::json ),
FROM a
LEFT JOIN b ON a.id = b.a_id
LEFT JOIN c ON a.id = c.a_id
GROUP BY a.id, a.name;
Run Code Online (Sandbox Code Playgroud)
执行时,c
和b
将彼此相乘并在 JSON 数组对象中产生重复的条目。
我尝试将查询更改为使用 2 个子查询,但出现各种错误和警告,例如“子查询必须只返回一列”等。
我也尝试使用LEFT OUTER JOIN
,但我想我还没有掌握连接表的工作原理,因为它仅适用于b
并且c
仍然相乘并包含重复项。
编辑:DISTINCT
在COALESCE
函数上使用带有“无法识别 json 类型的相等运算符”的错误。
如何修复此查询并仅聚合唯一行?
我需要指定表b
和c
实际上都是VIEW
s,而且它们都至少有一json_agg
列,所以我不能只使用json_agg(DISTINCT b.*)
. 这太容易了。
这是一个重现问题的小片段:
--DROP TABLE …
Run Code Online (Sandbox Code Playgroud) postgresql ×10
postgresql-9.4 ×10
index ×3
json ×3
datatypes ×2
aggregate ×1
array ×1
disk-space ×1
functions ×1
index-tuning ×1
join ×1
performance ×1
vacuum ×1