我有一种情况,我想在两个视图之间返回连接.那是很多专栏.在sql server中很容易.但是在PostgreSQL中我加入时.我收到错误"需要列定义列表".
有什么方法可以绕过这个,我不想提供返回列的定义.
CREATE OR REPLACE FUNCTION functionA(username character varying DEFAULT ''::character varying, databaseobject character varying DEFAULT ''::character varying)
RETURNS SETOF ???? AS
$BODY$
Declare
SqlString varchar(4000) = '';
BEGIN
IF(UserName = '*') THEN
Begin
SqlString := 'select * from view1 left join ' + databaseobject + ' as view2 on view1.id = view2.id';
End;
ELSE
Begin
SqlString := 'select * from view3 left join ' + databaseobject + ' as view2 on view3.id = view2.id';
End;
END IF;
execute …
Run Code Online (Sandbox Code Playgroud) CREATE OR REPLACE FUNCTION getParentLtree(parent_id bigint, tbl_name varchar)
RETURNS ltree AS
$BODY$
DECLARE
parent_ltree ltree;
BEGIN
-- This works fine:
-- select into parent_ltree l_tree from tbl1 where id = parent_id;
EXECUTE format('select into parent_ltree l_tree from %I
where id = %I', tbl_name,parent_id);
RETURN parent_ltree;
END;
$BODY$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
上述功能有2个问题:
parent_id
是integer
,但它会被替换引号?int
变量的正确格式说明符是什么?select into
不起作用EXECUTE
?如何使上面的注释查询使用表名传递?SELECT TOP ...
在Postgres 中描述查询的大多数资源都说你应该使用LIMIT
,ORDER BY
如果需要通过某种顺序选择顶部元素,可能使用子句.
你会怎么做,如果你需要选择一个递归查询,那里是没有排序的前N个元素和有可能的查询可以在不递归返回N多行少(这样TOP
的部分是必要的,以确保结果set 至少是 N行,而LIMIT
可以允许更少的行)?
我的具体用例是动态SQL模式的修改,用于选择表的随机子样本.
这是我修改的sql源的链接.最简单的方法是查看那里定义的最终函数_random_select
.它紧跟上述链接,但在输入表和输出结果集中已经被修改为多态,并且正确地说明了只返回输入表中已经存在的列的需要(还有另一个动态SQL)黑客row_number
从最终结果集中排除中期结果).
这是一个眼睛,但它是我最接近可重复的例子.如果您使用_random_select
并尝试从大于4500行的表中获取大约4500行的内容,则会开始以较高的概率看到较小的结果集,并且只会随着您增加所需样本的大小而变得更糟(因为重复的出现随着你想要的样本变大,情况会变得更糟)
请注意,在我的修改中,我没有使用_gaps
此链接中的技巧,如果某个索引列中存在间隙,则意味着过度采样以抵消采样效率低下.那部分与这个问题无关,在我的情况下,我row_number
用来确保有一个整数列,没有可能的间隙.
CTE的是递归的,以确保如果CTE的第一,非递归部分不给你足够的行(因为被去除重复的UNION
),那么它会回去经过一轮又一轮的CTE的递归调用,并继续坚持更多的结果,直到你有足够的.
在链接的示例中,LIMIT
使用,但我发现这不起作用.该方法返回的结果较少,因为最多LIMIT
只能保证N行.
你如何获得至少 N行保证?选择TOP
N行似乎是执行此操作的自然方式(因此递归CTE必须保持一直持续直到它获得足够的行来满足TOP
条件),但这在Postgres中不可用.
sql postgresql recursive-query common-table-expression sql-limit
在我的Rails 4应用程序中,我对Postgres 9.4数据库进行了此查询:
@chosen_opportunity = Opportunity.find_by_sql(
" UPDATE \"opportunities\" s
SET opportunity_available = false
FROM (
SELECT \"opportunities\".*
FROM \"opportunities\"
WHERE ( deal_id = #{@deal.id}
AND opportunity_available = true
AND pg_try_advisory_xact_lock(id) )
LIMIT 1
FOR UPDATE
) sub
WHERE s.id = sub.id
RETURNING sub.prize_id, sub.id"
)
Run Code Online (Sandbox Code Playgroud)
非常受到dba.SE相关答案的启发.
我只是希望我的查询找到并更新第一个(随机,有LIMIT
)行,available = true
并将其更新到available = false
,我需要在执行此操作时锁定行,但不要让新请求等待释放上一个锁,因为有许多将使用此查询的并发调用.
但我也看到了NOWAIT
选项FOR UPDATE
.我不确定我理解使用pg_try_advisory_xact_lock()
和NOWAIT
选项之间的区别,他们似乎在我看来实现了同样的目标:
要防止操作等待其他事务提交,请使用该
NOWAIT
选项.
我正在使用PHP进行PostgreSQL.
是否可以在列FROM 表 WHERE 条件中选择特定数量的随机值
代替
选择列 FROM 表 WHERE 条件
然后将它们转换为数组并使用array_rand()
?
(我不想使用这种方式,因为我将拥有数百万行并首先选择所有值,然后array_rand()
可能需要花费很多时间.)
假设我有一个这样的表格:
name | items
-----------+------------
Ben | {dd,ab,aa}
-----------+------------
David | {dd,aa}
-----------+------------
Bryan | {aa,ab,cd}
-----------+------------
Glen | {cd}
-----------+------------
Edward | {aa,cd}
-----------+------------
Aaron | {dd,aa}
-----------+------------
..... (many many more)
Run Code Online (Sandbox Code Playgroud)
我需要在一个列(或基本上是10个随机行)中选择匹配条件(在这种情况下是@> ARRAY[aa]
)的10个随机值,而不进行顺序表扫描或耗时的事情.
order by random()
因为它必须处理每一行所以需要花费很多时间,所以我会选择更好的解决方案.
是否可以仅使用纯Ecto查询从数据库中获取10个随机记录,而不是在应用程序端?例如,我不想从数据库中获取所有记录,然后在Elixir中获取它们的随机值(如下所示):
Subscribers
|> Repo.all
|> Enum.take_random(10)
Run Code Online (Sandbox Code Playgroud) postgresql ×6
dynamic-sql ×2
plpgsql ×2
sql ×2
concurrency ×1
ecto ×1
elixir ×1
random ×1
sql-limit ×1