- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Postgres 9.3。
我有两个表 T1
和 T2
以及它们之间的 n:m
关系 T1_T2_rel
。现在我想创建一个 View ,除了 T1 的列之外,还提供一个列,对于 T1 中的每条记录,该列包含一个数组,其中包含 T2 的所有相关记录的主键 ID。如果T2中没有相关条目,则该列对应字段为空值。
我的架构的抽象版本如下所示:
CREATE TABLE T1 ( t1_id serial primary key, t1_data int );
CREATE TABLE T2 ( t2_id serial primary key );
CREATE TABLE T1_T2_rel (
t1_id int references T1( t1_id )
, t2_id int references T2( t2_id )
);
对应的样本数据可以生成如下:
INSERT INTO T1 (t1_data)
SELECT cast(random()*100 as int) FROM generate_series(0,9) c(i);
INSERT INTO T2 (t2_id) SELECT nextval('T2_t2_id_seq') FROM generate_series(0,99);
INSERT INTO T1_T2_rel
SELECT cast(random()*10 as int) % 10 + 1 as t1_id
, cast(random()*99+1 as int) as t2_id
FROM generate_series(0,99);
到目前为止,我提出了以下查询:
SELECT T1.t1_id, T1.t1_data, agg
FROM T1
LEFT JOIN LATERAL (
SELECT t1_id, array_agg(t2_id) as agg
FROM T1_T2_rel
WHERE t1_id=T1.t1_id
GROUP BY t1_id
) as temp ON temp.t1_id=T1.t1_id;
这行得通。但是,可以简化吗?
相应的 fiddle 可以在这里找到:sql-fiddle .不幸的是,sql-fiddle 还不支持横向连接所需的 Postgres 9.3。
[更新] 正如已经指出的那样,原则上使用子查询的简单 left join
就足够了。但是,如果我比较查询计划,Postgres 在使用 left join
时对聚合表求助于顺序扫描,而在 left join lateral
的情况下使用索引扫描.
最佳答案
正如@Denis 已经评论过的:不需要 LATERAL
.此外,您的子查询选择了错误的列。这有效:
SELECT t1.t1_id, t1.t1_data, t2_ids
FROM t1
LEFT JOIN (
SELECT t1_id, array_agg(t2_id) AS t2_ids
FROM t1_t2_rel
GROUP BY 1
) sub USING (t1_id);
关于随后的顺序扫描,您提到:如果您查询整个表,顺序扫描通常更快。取决于您运行的版本、您的硬件、您的设置和基数统计以及您的数据分布。选择性实验 WHERE
类似 WHERE t1.t1_id < 1000
的条款或 WHERE t1.t1_id = 1000
并结合 planner settings了解选择:
SET enable_seqscan = off;
SET enable_indexscan = off;
重置:
RESET enable_seqscan;
RESET enable_indexscan;
请注意,仅在您的本地 session 中! This related answer on dba.SE有更多说明。
当然,您的设置也可能关闭:
关于sql - Left Join Lateral 和数组聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19490861/
我们可以使用 go 进行模块的通用导入吗?更清楚地说,这里是用例: package main import ( "fmt" "net/http" ) json handler(w ht
这是我在 Chrome 控制台中看到的内容: > new Date(2012, 9, 13).toString() "Sat Oct 13 2012 00:00:00 GMT+0800 (CST)"
我有一个 AI 例程,可以将各种数据存储为 Memory 对象。 Memory 对象根据传递给构造函数的“内存类型”具有不同的参数(回想起来,每种类型的内存确实应该是 Memory 的子类,但是目前这
我正在使用later.js我正在尝试在 Meteor 中安排一个帖子。 我什至还没有到达调度部分,因为我无法理解 later.js recur() 如何通过将时间段链接在一起来工作,并执行一个最终会找
有没有办法在 Java 中定义“指向指针的指针”? 即我正在考虑这样的事情...... class Main { public static void main (String[] args)
我的代码中有一个 IIFE,而其他 IIFE 很少。他们都有名字(所以他们不是匿名的)。我想稍后通过其他功能调用一些 IIFE(我的意思是,是的,它们在开始时就完成了它们的工作,但我想稍后再使用它们)
我正在尝试清理 PostgreSQL 表中的数据,其中一些记录在 email_address 列中有大量脏话(结果,这些记录是由激动的用户输入的由于已修复的错误而感到沮丧): ┌───────
我想使用 Postgres 对地址进行一些基本的地理编码。我有一个包含大约 100 万个原始地址字符串的地址表: => \d addresses Table "public.addresses"
我正在创建一个用于每月定期订单的平台。 我正在使用later.js进行重复。我遇到过以下两种情况,我想知道是否有人对如何更好地处理这些情况有建议(或者later.js是否以某种方式本地处理它们): l
这是 fiddle :http://jsfiddle.net/ccarns/hXPU9/ 尝试让月份选项显示下个月的同一天。当前的实现返回每月的第一天。 later.parse.text("every
我想通过添加“稍后提醒我”操作来扩展我的本地通知功能。换句话说,如果用户点击“稍后提醒我”按钮,我想在设定的时间后重新显示通知。 即使我的应用程序中的所有内容都应该正确连接(检查通知是否启用、设置通知
我正在浏览 Later.js 文档,它记录了如何很好地设置时间表 - 但没有说明如何在完成后执行该功能。 如果我有 function logit(){ console.log('it is done'
我使用 Later.JS 在每个月的第一天进行自动函数调用。为了进行测试,我需要模拟时间来检查 Later.JS 和我的代码是否执行正确的操作。有人可以帮助我如何 mock 过去的时光吗? 谢谢 最佳
我想调用一些已实现的验证 Javascript 方法 validatePageProperties = function() {...} 当我单击“稍后激活”按钮时(见图)。知道如何做到这一点吗? 最
通过首先查看 Vim 中的时间旅行命令,即 ea {N}s 和 lat {N}s,我认为它会非常简单。但是,它并没有像预期的那样为我工作,现在我完全困惑了。事情就是这样。 我启动了我的 Vim,并开始
我不知道我在说什么的真正好名字,但是,大多数编程语言都使用类似这样的赋值语句语法: (变量)(赋值运算符)(表达式) 还有一些有一些特殊的赋值运算符,比如var1 += var2等价于var1 = v
我有以下设置: CREATE TABLE A(id INT); CREATE TABLE B(id INT); CREATE TABLE C(aid INT, bid INT); 我想做以下事情: I
在我的 PostgreSQL 9.6.2 数据库中,我有一个查询,它根据一些股票数据构建一个计算字段表。它为表中的每一行计算 1 到 10 年的移动平均窗口,并将其用于周期性调整。具体来说,CAPE、
我在 postgresql 9.5 中使用“LEFT JOIN LATERAL”函数时遇到了一些困难。 在我的表中,有'ID'、'DATE'、'CODE'三列。一个人(ID)有多个行,如下所示。 ID
我正在使用 Postgres 9.3。 我有两个表 T1 和 T2 以及它们之间的 n:m 关系 T1_T2_rel。现在我想创建一个 View ,除了 T1 的列之外,还提供一个列,对于 T1 中的
我是一名优秀的程序员,十分优秀!