由于Postgres能够进行LATERAL
连接,我一直在阅读它,因为我目前为我的团队执行复杂的数据转储,其中包含大量低效的子查询,这使得整个查询需要四分钟或更长时间.
我知道LATERAL
联接可能能够帮助我,但即使在阅读了像Heap Analytics 这样的文章之后,我仍然没有完全遵循.
LATERAL
加入的用例是什么?LATERAL
连接和子查询之间有什么区别?
我有这样的查询,很好地生成两个给定日期之间的一系列日期:
select date '2004-03-07' + j - i as AllDate
from generate_series(0, extract(doy from date '2004-03-07')::int - 1) as i,
generate_series(0, extract(doy from date '2004-08-16')::int - 1) as j
Run Code Online (Sandbox Code Playgroud)
它在2004-03-07
和之间生成162个日期2004-08-16
,这就是我想要的.这段代码的问题是,它不会得到正确的答案时,这两个日期都不同年份,例如,当我尝试2007-02-01
和2008-04-01
.
有更好的解决方案吗?
我试图从表中获取25个15,000个ID的随机样本.而不是每次都手动按下运行,我正在尝试循环.我完全理解的不是Postgres的最佳用法,但它是我的工具.这是我到目前为止:
for i in 1..25 LOOP
insert into playtime.meta_random_sample
select i, ID
from tbl
order by random() limit 15000
end loop
Run Code Online (Sandbox Code Playgroud) 假设我有一个这样的表:
subject | flag
----------------+------
this is a test | 2
Run Code Online (Sandbox Code Playgroud)
subject
属于类型text
,flag
属于类型int
.我想在Postgres中将此表转换为类似的内容:
token | flag
----------------+------
this | 2
is | 2
a | 2
test | 2
Run Code Online (Sandbox Code Playgroud)
是否有捷径可寻?
我有一个表模式,其中包含一个int数组列,以及一个自定义聚合函数,它对数组内容求和.换句话说,给出以下内容:
CREATE TABLE foo (stuff INT[]);
INSERT INTO foo VALUES ({ 1, 2, 3 });
INSERT INTO foo VALUES ({ 4, 5, 6 });
Run Code Online (Sandbox Code Playgroud)
我需要一个可以返回的"sum"函数{ 5, 7, 9 }
.正确运行的PL/pgSQL版本如下:
CREATE OR REPLACE FUNCTION array_add(array1 int[], array2 int[]) RETURNS int[] AS $$
DECLARE
result int[] := ARRAY[]::integer[];
l int;
BEGIN
---
--- First check if either input is NULL, and return the other if it is
---
IF array1 IS NULL OR array1 = '{}' THEN
RETURN array2;
ELSEIF …
Run Code Online (Sandbox Code Playgroud) 我的最后一个问题将数组传递给存储到postgres有点不清楚.现在,澄清我的目标:
我想创建一个Postgres存储过程,它将接受两个输入参数.一个将是一些数量的列表,例如(100, 40.5, 76)
,另一个将是一些发票的 列表('01-2222-05','01-3333-04','01-4444-08')
.之后我想使用这两个数字和字符列表并对它们做一些事情.例如,我想从这一组数字中取出每个金额,并将其分配给相应的发票.
在Oracle中类似的东西看起来像这样:
SOME_PACKAGE.SOME_PROCEDURE (
789,
SYSDATE,
SIMPLEARRAYTYPE ('01-2222-05','01-3333-04','01-4444-08'),
NUMBER_TABLE (100,40.5,76),
'EUR',
1,
P_CODE,
P_MESSAGE);
Run Code Online (Sandbox Code Playgroud)
当然,这两种类型SIMPLEARRAYTYPE
,并NUMBER_TABLE
出现在靠前的DB定义.
我使用postgreSQL 9.1.在我的数据库中有一个看起来像的表
id | ... | values
-----------------------
1 | ... | {1,2,3}
2 | ... | {}
Run Code Online (Sandbox Code Playgroud)
其中id是一个整数,values是一个整数数组.数组可以为空.
我需要删除此列表.如果我查询
select id, ..., unnest(values)
from table
Run Code Online (Sandbox Code Playgroud)
我得到三行id = 1(正如预期的那样)并没有id = 2的行.有没有办法得到像这样的结果
id | ... | unnest
-------------------
1 | ... | 1
1 | ... | 2
1 | ... | 3
2 | ... | null
Run Code Online (Sandbox Code Playgroud)
即一个查询,其中还包含具有空数组的行?
给定一个如此定义的表:
CREATE TABLE test_values(name TEXT, values INTEGER[]);
Run Code Online (Sandbox Code Playgroud)
......以及以下值:
| name | values |
+-------+---------+
| hello | {1,2,3} |
| world | {4,5,6} |
Run Code Online (Sandbox Code Playgroud)
我正在尝试查找将返回的查询:
| name | value |
+-------+-------+
| hello | 1 |
| hello | 2 |
| hello | 3 |
| world | 4 |
| world | 5 |
| world | 6 |
Run Code Online (Sandbox Code Playgroud)
我已经回顾了有关访问数组的上游文档,并试图考虑使用该unnest()
函数的解决方案是什么样的,但是它已经空洞了.
即使在阵列被扩展且没有主键的情况下存在大量列的情况下,理想的解决方案也将易于使用.处理具有多个数组的案例并不重要.
我有一个数组作为一列的表,我想将数组元素加在一起:
> create table regres(a int[] not null);
> insert into regres values ('{1,2,3}'), ('{9, 12, 13}');
> select * from regres;
a
-----------
{1,2,3}
{9,12,13}
Run Code Online (Sandbox Code Playgroud)
我希望结果如下:
{10, 14, 16}
Run Code Online (Sandbox Code Playgroud)
那就是:{1 + 9, 2 + 12, 3 + 13}
.
这样的功能在某处已经存在吗?插入扩展看起来是一个很好的候选者,但这样的功能尚不存在.
预计数组的长度在24到31个元素之间,所有元素都是NOT NULL
,并且数组本身也将是NOT NULL
.所有元素都是基本的int
.每个聚合将有两行以上.在查询中,所有数组都将具有相同数量的元素.不同的查询将具有不同数量的元素.
我的实现目标是:x86_64-unknown-linux-gnu上的PostgreSQL 9.1.13,由gcc编译(Ubuntu/Linaro 4.6.3-1ubuntu5)4.6.3,64位
我一直在尝试从时间戳字段中的第一个日期到最后一个日期生成一系列日期(YYYY-MM-DD HH).我有generate_series()
我需要的东西,但是在尝试从表中获取开始和结束日期时遇到了问题.我有以下几点给出一个粗略的想法:
with date1 as
(
SELECT start_timestamp as first_date
FROM header_table
ORDER BY start_timestamp DESC
LIMIT 1
),
date2 as
(
SELECT start_timestamp as first_date
FROM header_table
ORDER BY start_timestamp ASC
LIMIT 1
)
select generate_series(date1.first_date, date2.first_date
, '1 hour'::interval)::timestamp as date_hour
from
( select * from date1
union
select * from date2) as foo
Run Code Online (Sandbox Code Playgroud)
Postgres 9.3
postgresql ×10
arrays ×4
sql ×4
plpgsql ×3
arraylist ×1
c ×1
date ×1
for-loop ×1
lateral ×1
lateral-join ×1
random ×1
split ×1
subquery ×1
time-series ×1