我在 Postgres 9.5中t有一个带有数组列的表z。我想选择id其中z要么是NULLOR {NULL}。
id | z
---+--------
1 | {NULL}
2 | null
Run Code Online (Sandbox Code Playgroud)
我试图改变{NULL}到NULL以array_remove():
SELECT id,
array_remove(z,NULL) as removed
from t;
Run Code Online (Sandbox Code Playgroud)
返回:
id | z | removed
---+--------+-------
1 | {NULL} | {}
2 | null | null
Run Code Online (Sandbox Code Playgroud)
但是,如果我查询这个:
select id, z from t where removed is null;
Run Code Online (Sandbox Code Playgroud)
我仍然得到 id 1。理想情况下,我想避免取消嵌套和分组备份。
days函数中的参数getAvgByDay()不起作用,我猜是因为它在引号内:
CREATE OR REPLACE FUNCTION getAvgByDay(days int)
RETURNS TABLE ( average text,
date timestamp with time zone
) AS
$func$
BEGIN
RETURN QUERY
SELECT to_char( AVG(measure), '99999D22') AS average, ( now() - interval '$1 day') AS date
FROM (
SELECT mes.date, mes.measure
FROM measures mes
WHERE mes.date < ( now() - interval '$1 day')
) AS mydata;
END
$func$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud) 我有一个看起来像这样的数组[[(Double,Double)]]。它是一个多维元组数组。
这是我永远不会查询的数据,因为它不需要查询。只有在客户端是这样才有意义。我正在考虑将整个内容存储为字符串,然后将其解析回多数组。
这是一个很好的方法吗?考虑到我最多可以有 20 个数组,其中最多有 4 个内部数组,每个数组都有一个 2 Double 的元组,那么解析会非常昂贵吗?
我如何检查哪种方法更好,以及将其存储为 PostgreSQL 中的多维数组是否是更好的方法?
我将如何存储它?
postgresql parsing database-design tuples multidimensional-array
我想创建一个函数,尝试将一组值转换为用户指定的类型(默认为文本)。一个非常简单的函数如下所示:
CREATE OR REPLACE FUNCTION cast_to(variable jsonb, key text, target_type anyelement DEFAULT 'TEXT'::regtype) RETURNS anyelement as $$
begin
RETURN CAST(variable->>key AS target_type);
end
$$
language plpgsql;
Run Code Online (Sandbox Code Playgroud)
我已经尝试过以下方法:
SELECT CAST('foo' AS 'text');: 给出语法错误SELECT CAST('foo' AS 'text'::regtype);: 与 1 相同的错误SELECT CAST('foo' AS pg_typeof(null::text));说type pg_typeof does not exist 最后一次尝试是我可以传入一个具有目标类型的变量而不是文本表示形式。使用该函数将如下所示SELECT cast_to('text', NULL::text);。
如何实现这个或类似的功能?
编辑:正如评论中所建议的,我尝试使用动态 SQL。我运气不太好。我创建了一个非常基本的案例,不使用任何变量:
CREATE OR REPLACE FUNCTION audit.cast_to() RETURNS text as $$
DECLARE
_sql TEXT := 'SELECT CAST($1 AS $2)';
out TEXT;
begin …Run Code Online (Sandbox Code Playgroud) 问题实际上是关于 sql 查询的优化。假设我们有这样定义的表。
CREATE TYPE record_type AS ENUM (
'TRANSFER',
'TRADE',
'VOUCHER'
);
CREATE TYPE record_status AS ENUM (
'NEW',
'VALIDATED',
'EXPIRED'
);
CREATE TABLE good_records (
id uuid PRIMARY KEY,
user_id uuid NOT NULL,
type record_type NOT NULL,
status record_status NOT NULL,
amount numeric(36,18) NOT NULL DEFAULT 0,
expired_at timestamp WITH TIME ZONE NOT NULL,
notification_sent boolean DEFAULT false,
);
Run Code Online (Sandbox Code Playgroud)
我想每 10 分钟运行一次过期检查,即我会运行SELECT * FROM good_records
where record_status = 'NEW' and notification_sent = false(和SELECT * FROM …
我有一个users包含字段id和 的表email。id是主键并且email也被索引。
database> \d users
+-----------------------------+-----------------------------+-----------------------------------------------------+
| Column | Type | Modifiers |
|-----------------------------+-----------------------------+-----------------------------------------------------|
| id | integer | not null default nextval('users_id_seq'::regclass) |
| email | character varying | |
+-----------------------------+-----------------------------+-----------------------------------------------------+
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
"index_users_on_email" UNIQUE, btree (email)
Run Code Online (Sandbox Code Playgroud)
如果我在子查询中使用子句查询表,distinct on (email)我会得到显着的性能损失。
database> \d users
+-----------------------------+-----------------------------+-----------------------------------------------------+
| Column | Type | Modifiers |
|-----------------------------+-----------------------------+-----------------------------------------------------|
| id | integer | not null default nextval('users_id_seq'::regclass) |
| …Run Code Online (Sandbox Code Playgroud) postgresql performance greatest-n-per-group distinct-on postgresql-performance
我有一个插入、更新或删除表行的存储过程。当所有参数都用作输入时,它工作正常。但是,我需要返回最后插入行的 ID。为此,我尝试使用INOUT参数并在语句RETURNING之后INSERT返回 ID。
但是,我不知道如何将返回的 ID 绑定到参数INOUT。以下是存储过程的代码:
CREATE OR REPLACE PROCEDURE public.spproductinsertupdatedelete(
_ser integer,
_subcategid integer,
_inrprice numeric,
_usdprice numeric,
_colour integer,
_size integer,
_qty integer,
_prodid integer DEFAULT NULL::integer,
inout _pid integer default null
)
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
if _ser=1 then --- Insert
INSERT INTO product (prod_subcateg_id,prod_inr_price,prod_usd_price,prod_colour,prod_size,prod_qty)
VALUES (_subcategID, _inrprice, _usdprice, _colour, _size, _qty)
RETURNING prod_id;
ELSEIF _ser=2 THEN
UPDATE PRODUCT SET
prod_subcateg_id = _subcategid,
prod_inr_price = _inrprice,
prod_usd_price = …Run Code Online (Sandbox Code Playgroud) 我尝试向数据库添加索引,但不断收到错误:
PG::SyntaxError: ERROR: DEFAULT is not allowed in this context
阅读了几个小时的文档后,我似乎无法解决该问题。
我正在运行这个:
"CREATE UNIQUE INDEX index_uniq_service_models_default ON service_models(zone_id) WHERE default"
Run Code Online (Sandbox Code Playgroud)
我的桌子看起来像这样:
create_table :service_models do |t|
t.string :name, null: false
t.jsonb :configuration, null: false, default: "{}"
t.boolean :default, null: false
t.json :metadata, null: false, default: "{}"
t.references :zone, foreign_key: true, null: false, index: { name: idx_name(:service_models, :zones) }
t.timestamps
end
Run Code Online (Sandbox Code Playgroud)
我想要做的是让 ServiceModel 对于一个区域只有 1 个默认值。
一个区域可以有多个 ServiceModel,但只能有 1 个默认 ServiceModel。
我尝试执行事务操作并故意抛出异常,以验证回滚是否已完成,但回滚并未执行。
PostgreSQL 数据库版本为 12.1-1,基于 Docker。
这是包含注释的服务@Transactional:
@Service
public class MyTestService {
@Autowired
private DocumentDataDao documentDataDao;
@Transactional
public void test() {
DocumentData data = new DocumentData();
data.setData(UUID.randomUUID().toString());
documentDataDao.create(data);
throw new IllegalArgumentException("Test rollback");
}
}
Run Code Online (Sandbox Code Playgroud)
该create函数使用 aNamedParameterJdbcTemplate插入数据:
String statement = String.format("INSERT INTO %s (%s) VALUES (%s) RETURNING %s", tableName,
String.join(",", insertingColumns), String.join(",", values),
String.join(",", returningColumns));
return getNamedJdbcTemplate().queryForObject(statement, parameters, getRowMapper());
Run Code Online (Sandbox Code Playgroud)
该test函数是从另一个服务调用的:
@Service
public class ApplicationStartupListener {
private Logger log = LoggerFactory.getLogger(ApplicationStartupListener.class);
@Autowired
private MyTestService testService; …Run Code Online (Sandbox Code Playgroud) Postgres 方法array_position(array, element)与 SQL 中的其他事物一样,是基于 1 的。例如:
SELECT array_position(array[4,5,6], 5) -- returns 2
Run Code Online (Sandbox Code Playgroud)
但是,我正在执行以下查询来从 pg_catalog 检索非唯一索引及其列:
SELECT array_position(array[4,5,6], 5) -- returns 2
Run Code Online (Sandbox Code Playgroud)
第四个选择indkey在数组中搜索列的ordinal_position,因此对于每一列,它都会获取其在索引中的位置。
有趣的是,第一列的位置为 0,所以我必须添加+ 1它以使其基于 1。
随后的CASE表达式使用完全相同的值作为检索 的第 n 个元素的索引indoption,奇怪的是,即使[]运算符也是基于 1 的,也能正常工作:
SELECT (array[4,5,6])[2] -- returns 5
Run Code Online (Sandbox Code Playgroud)
这怎么样?
我目前使用的是 PG 9.6。
postgresql ×10
sql ×5
plpgsql ×3
indexing ×2
arrays ×1
ddl ×1
distinct-on ×1
dynamic-sql ×1
function ×1
identifier ×1
java ×1
null ×1
parsing ×1
performance ×1
polymorphism ×1
spring-boot ×1
transactions ×1
tuples ×1