我想在PostgreSQL中随机选择一行,我试过这个:
select * from table where random() < 0.01;
Run Code Online (Sandbox Code Playgroud)
但其他一些人推荐这个:
select * from table order by random() limit 1000;
Run Code Online (Sandbox Code Playgroud)
我有一个非常大的表,有5亿行,我希望它快.
哪种方法更好?有什么区别?选择随机行的最佳方法是什么?
我经常需要在重建之前删除PostgreSQL数据库中的所有数据.我将如何直接在SQL中执行此操作?
目前我已经设法提出一个SQL语句,它返回我需要执行的所有命令:
SELECT 'TRUNCATE TABLE ' || tablename || ';' FROM pg_tables WHERE tableowner='MYUSER';
Run Code Online (Sandbox Code Playgroud)
但是,一旦拥有它们,我就无法以编程方式执行它们.
问题很简单.如何将列添加x
到表中y
,但仅当x
列不存在时?我在这里找到了解决方法,如何检查列是否存在.
SELECT column_name
FROM information_schema.columns
WHERE table_name='x' and column_name='y';
Run Code Online (Sandbox Code Playgroud) 我想在PostgreSQL中对表进行大量更新,但我不需要在整个操作中维护事务完整性,因为我知道我正在更改的列不会被写入或读取更新.我想知道psql控制台中是否有一种简单的方法可以更快地完成这些类型的操作.
例如,假设我有一个名为"orders"的表,有3500万行,我想这样做:
UPDATE orders SET status = null;
Run Code Online (Sandbox Code Playgroud)
为避免被转移到offtopic讨论,让我们假设3500万列的所有状态值当前都设置为相同(非空)值,从而使索引无用.
此语句的问题是需要很长时间才能生效(仅因为锁定),并且所有更改的行都将被锁定,直到整个更新完成.此更新可能需要5个小时,而类似
UPDATE orders SET status = null WHERE (order_id > 0 and order_id < 1000000);
Run Code Online (Sandbox Code Playgroud)
可能需要1分钟.超过3500万行,执行上述操作并将其分成35块只需要35分钟,节省了4小时25分钟.
我可以用脚本进一步分解它(在这里使用伪代码):
for (i = 0 to 3500) {
db_operation ("UPDATE orders SET status = null
WHERE (order_id >" + (i*1000)"
+ " AND order_id <" + ((i+1)*1000) " + ")");
}
Run Code Online (Sandbox Code Playgroud)
此操作可能仅在几分钟内完成,而不是35分钟.
所以这归结为我真正的要求.我不想写一个怪异的脚本来分解操作,每次我想做这样一个大的一次性更新.有没有办法在SQL中完成我想要的东西?
我写了一个函数,输出一个SELECT
以文本形式组成的PostgreSQL 查询.现在我不想再输出文本,但实际上SELECT
对数据库运行生成的语句并返回结果 - 就像查询本身一样.
CREATE OR REPLACE FUNCTION data_of(integer)
RETURNS text AS
$BODY$
DECLARE
sensors varchar(100); -- holds list of column names
type varchar(100); -- holds name of table
result text; -- holds SQL query
-- declare more variables
BEGIN
-- do some crazy stuff
result := 'SELECT\r\nDatahora,' || sensors ||
'\r\n\r\nFROM\r\n' || type ||
'\r\n\r\nWHERE\r\id=' || $1 ||'\r\n\r\nORDER BY Datahora;';
RETURN result;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION data_of(integer) OWNER TO postgres;
Run Code Online (Sandbox Code Playgroud)
sensors …
我不确定如何实现以下内容:
CREATE OR REPLACE FUNCTION fnJobQueueBEFORE() RETURNS trigger AS $$
DECLARE
shadowname varchar := TG_TABLE_NAME || 'shadow';
BEGIN
INSERT INTO shadowname VALUES(OLD.*);
RETURN OLD;
END;
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
即将值插入到具有动态生成名称的表中.
执行上面的代码会产生:
ERROR: relation "shadowname" does not exist
LINE 1: INSERT INTO shadowname VALUES(OLD.*)
Run Code Online (Sandbox Code Playgroud)
它似乎表明变量不会作为表名扩展/允许.我在Postgres手册中没有发现这个.
我已经尝试过EXECUTE
这样的事情:
EXECUTE 'INSERT INTO ' || quote_ident(shadowname) || ' VALUES ' || OLD.*;
Run Code Online (Sandbox Code Playgroud)
但没有运气:
ERROR: syntax error at or near ","
LINE 1: INSERT INTO personenshadow VALUES (1,sven,,,)
Run Code Online (Sandbox Code Playgroud)
该RECORD
类型似乎失去了:OLD.*
似乎被转换为字符串,并得到的重新解析,导致各种各样的类型的问题(例如NULL
值). …
DECLARE @DatabaseName NVARCHAR(max); SET @DatabaseName = 'MainDb'
USE @DatabaseName
Run Code Online (Sandbox Code Playgroud)
不行.怎么做?
我正在使用PostgreSQL并且是一个SQL初学者.我正在尝试从查询中创建一个表,如果我运行:
CREATE TABLE table_name AS
(....query...)
Run Code Online (Sandbox Code Playgroud)
它工作得很好.但是如果我添加'if not exists'并运行:
CREATE TABLE IF NOT EXISTS table_name AS
(....query...)
Run Code Online (Sandbox Code Playgroud)
使用完全相同的查询,我得到:
Run Code Online (Sandbox Code Playgroud)ERROR: syntax error at or near "as"
有没有办法做到这一点?
我想遍历所有表来计算每个表中的行数.以下查询给我一个错误:
DO $$
DECLARE
tables CURSOR FOR
SELECT tablename FROM pg_tables
WHERE tablename NOT LIKE 'pg_%'
ORDER BY tablename;
tablename varchar(100);
nbRow int;
BEGIN
FOR tablename IN tables LOOP
EXECUTE 'SELECT count(*) FROM ' || tablename INTO nbRow;
-- Do something with nbRow
END LOOP;
END$$;
Run Code Online (Sandbox Code Playgroud)
错误:
Run Code Online (Sandbox Code Playgroud)ERROR: syntax error at or near ")" LINE 1: SELECT count(*) FROM (sql_features) ^ QUERY: SELECT count(*) FROM (sql_features) CONTEXT: PL/pgSQL function inline_code_block line 8 at EXECUTE statement
sql_features
是我的数据库中的表名.我已经尝试使用quote_ident()
但无济于事.
使用PostgreSQL,第一条记录的表中的列值存储在记录变量中.例如:让变量为:recordvar
recordvar.columnname
Run Code Online (Sandbox Code Playgroud)
给出指定列名的值.我将columname
在变量中定义:
var := columnname
Run Code Online (Sandbox Code Playgroud)
在地方columnname
,如果我与变量如更换recordvar.var
,这是行不通的.
请让我知道如何处理这种情况.以下是示例代码:
CREATE OR REPLACE FUNCTION getrowdata(id numeric, table_name character varying)
RETURNS SETOF void AS
$BODY$
DECLARE
srowdata record;
reqfield character varying;
value numeric;
BEGIN
RAISE NOTICE 'id: %',id;
reqfield:= 'columnname';
EXECUTE 'select * from datas.'||table_name||' WHERE id = '||id into srowdata;
RAISE NOTICE 'srowdata: %',srowdata;
RAISE NOTICE 'srowdatadata.columnname: %',srowdata.columnname;
value:= srowdata.reqfield;
RAISE NOTICE 'value: %',value;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
Run Code Online (Sandbox Code Playgroud) postgresql ×9
plpgsql ×6
dynamic-sql ×4
sql ×3
create-table ×1
database ×1
dblink ×1
hstore ×1
loops ×1
performance ×1
random ×1
sql-server ×1
sql-update ×1
t-sql ×1
tablename ×1
transactions ×1
triggers ×1
truncate ×1
types ×1
variables ×1