由于Postgres能够进行LATERAL连接,我一直在阅读它,因为我目前为我的团队执行复杂的数据转储,其中包含大量低效的子查询,这使得整个查询需要四分钟或更长时间.
我知道LATERAL联接可能能够帮助我,但即使在阅读了像Heap Analytics 这样的文章之后,我仍然没有完全遵循.
LATERAL加入的用例是什么?LATERAL连接和子查询之间有什么区别?
我有3张桌子:
users(id, account_balance)
grocery(user_id, date, amount_paid)
fishmarket(user_id, date, amount_paid)
Run Code Online (Sandbox Code Playgroud)
对于具有不同日期和金额的相同user_id,两个fishmarket和grocery表可能有多次出现,或者对于任何给定用户都没有任何内容.当我尝试以下查询时:
SELECT
t1."id" AS "User ID",
t1.account_balance AS "Account Balance",
count(t2.user_id) AS "# of grocery visits",
count(t3.user_id) AS "# of fishmarket visits"
FROM users t1
LEFT OUTER JOIN grocery t2 ON (t2.user_id=t1."id")
LEFT OUTER JOIN fishmarket t3 ON (t3.user_id=t1."id")
GROUP BY t1.account_balance,t1.id
ORDER BY t1.id
Run Code Online (Sandbox Code Playgroud)
它会产生不正确的结果:"1", "12", "12".
但是,当我尝试LEFT JOIN只有一个表时,它会产生正确的结果,无论是访问grocery还是fishmarket访问"1", "3", "4".
我在这做错了什么?
我正在使用PostgreSQL 9.1.
我有下表MyTable:
id ? value_two ? value_three ? value_four
???????????????????????????????????????????
1 ? a ? A ? AA
2 ? a ? A2 ? AA2
3 ? b ? A3 ? AA3
4 ? a ? A4 ? AA4
5 ? b ? A5 ? AA5
Run Code Online (Sandbox Code Playgroud)
我想查询{ value_three, value_four }按组分组的对象数组value_two.value_two应该在结果中独立存在.结果应如下所示:
value_two ? value_four
???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
a ? [{"value_three":"A","value_four":"AA"}, {"value_three":"A2","value_four":"AA2"}, {"value_three":"A4","value_four":"AA4"}]
b ? [{"value_three":"A3","value_four":"AA3"}, {"value_three":"A5","value_four":"AA5"}]
Run Code Online (Sandbox Code Playgroud)
它是否使用json_agg()或无关紧要array_agg().
然而,我能做的最好的事情是:
with MyCTE as ( select …Run Code Online (Sandbox Code Playgroud) 我正在尝试用我的查询来完成某些事情,但它并没有真正起作用.我的应用程序曾经有一个mongo db,所以应用程序用于在一个字段中获取数组,现在我们不得不更改为Postgres,我不想更改我的应用程序代码以保持v1工作.
为了在Postgres中的1个字段中获取数组,我使用了array_agg()函数.到目前为止这个工作正常.但是,我正处于另一个不同表的字段中需要另一个数组的位置.
例如:
我有我的员工.员工有多个地址,有多个工作日.
SELECT name, age, array_agg(ad.street) FROM employees e
JOIN address ad ON e.id = ad.employeeid
GROUP BY name, age
Run Code Online (Sandbox Code Playgroud)
现在这对我来说很好,这将导致例如:
| name | age| array_agg(ad.street)
| peter | 25 | {1st street, 2nd street}|
Run Code Online (Sandbox Code Playgroud)
现在我想在工作日加入另一张桌子,所以我这样做:
SELECT name, age, array_agg(ad.street), arrag_agg(wd.day) FROM employees e
JOIN address ad ON e.id = ad.employeeid
JOIN workingdays wd ON e.id = wd.employeeid
GROUP BY name, age
Run Code Online (Sandbox Code Playgroud)
这导致:
| peter | 25 | {1st street, 1st street, 1st street, 1st …Run Code Online (Sandbox Code Playgroud)