我在批量插入中使用下面的函数,通常批量插入有大约 60 行,每行都有下面的函数。但有时我会收到 PG::TRDeadlockDetected: ERROR: deadlock detected(请参阅下面的完整错误)。
我怎样才能避免这种情况?如果发生这种情况,我可以添加一个将返回 0 的 EXCEPTION,我宁愿不这样做,但批量插入对我来说非常方便。
CREATE OR REPLACE FUNCTION "univ"."gc_title_desc"(IN _title text, IN _desc text, OUT result_id int4) RETURNS "int4"
AS $BODY$BEGIN
LOOP
BEGIN
WITH sel AS (
SELECT id
FROM univ.results
WHERE title = _title AND description = _desc
)
, ins AS (
INSERT INTO univ.results (title, description)
SELECT _title, _desc
WHERE NOT EXISTS (SELECT 1 FROM sel)
RETURNING id
)
SELECT id
FROM sel NATURAL FULL OUTER JOIN ins
INTO result_id; …Run Code Online (Sandbox Code Playgroud) 我有一个从表格中选择一些数据的功能。我想返回所选数据和该表中的总行数。
我怎样才能做到这一点,或者我怎样才能以最有效的方式获得相同的结果?
我尝试了几件事,最后得到了下面的代码,现在这是我想要的格式,但count(*) over () as total_count会一直返回 1,我需要它返回的是该records选择的总行数。
SELECT
row_to_json(selected_records) as data
FROM
(
SELECT
count(*) over () as total_count,
array_to_json(array_agg(row_to_json(records))) as data
FROM (
SELECT
sum(entrances) as entrances
FROM report_la
WHERE profile_id = 3777614
GROUP BY landing_path_id
limit 10 offset 0
) records
) as selected_records
Run Code Online (Sandbox Code Playgroud)
更新,下面的代码产生了我想要的结果,如果我可以total_count从records选择中隐藏该列就好了
SELECT
row_to_json(selected_records) as data
FROM
(
SELECT
min(total_count) as total_count
,array_to_json(array_agg(row_to_json(records))) as data
FROM (
SELECT
sum(entrances) as entrances
,count(*) over () as total_count …Run Code Online (Sandbox Code Playgroud) WITH upd AS (
UPDATE univ.products
SET source = source::int[] || _source
WHERE project_id = _project_id AND product_id = _products AND NOT(_source = ANY(source))
RETURNING id
)
, ins AS (
INSERT INTO univ.products(project_id, product_id, source, tracked)
SELECT _project_id, _product_id, ARRAY[_source], _tracked
WHERE NOT EXISTS (SELECT 1 FROM upd)
RETURNING id
)
SELECT id
FROM upd NATURAL FULL OUTER JOIN ins
INTO _project_product_id;
Run Code Online (Sandbox Code Playgroud)
我的情况,我有这个函数,其中包含上述所有内容以及更多内容,我试图避免重复项目/产品对,但同时通过附加新源来更新源。现在每个产品/项目对的源必须是唯一的,这就是我添加的原因NOT(_source = ANY(source)),但如果这是真的,select 1 from up将不会返回任何内容,因此将尝试将记录插入数据库以避免这种情况,我添加了以下内容例外。
EXCEPTION WHEN UNIQUE_VIOLATION THEN
EXIT;
END;
Run Code Online (Sandbox Code Playgroud)
这几乎是我想要的,但没有返回任何 …
下面的选择返回我所有用户拥有的所有项目的数组。
WITH user_projects AS
(SELECT
u.id as user_id
,COALESCE(array_agg(DISTINCT pa.project_id), '{0}'::integer[]) as project_ids
FROM users u
LEFT JOIN project_assignments pa on pa.user_creator_id = u.id
GROUP BY u.id
)
user: 1, project_ids: {1, 2}
user: 2, project_ids: {3, 4}
Run Code Online (Sandbox Code Playgroud)
使用该选择,我想进行报告,该报告将为每个用户显示 12 个月的摘要。
SELECT
to_char(pk.created_at,'Mon') as mon
,extract(year from pk.created_at) as yyyy
,up.user_id
,COALESCE(count(distinct pk.keyword_id), 0) as total_keywords
FROM user_projects up
LEFT JOIN project_keywords pk on pk.project_id = ANY(up.project_ids::int[])
GROUP BY up.user_id, up.project_ids, 1, 2
Run Code Online (Sandbox Code Playgroud)
输出:
mon: sept, yyyy: 2014, user_id: 1, …Run Code Online (Sandbox Code Playgroud) 我想构建一个函数,如果表中不存在电子邮件值并返回email_id行的值,则该函数将插入电子邮件。我怎样才能做到这一点?
另外,如果电子邮件没有插入并且它已经存在于数据库中,我该如何返回 ID?我需要执行另一个SELECT吗?
BEGIN;
LOCK TABLE mailing_list IN SHARE ROW EXCLUSIVE MODE;
INSERT INTO mailing_list (email)
SELECT 'email'
WHERE NOT EXISTS (
SELECT * FROM mailing_list WHERE email='email'
);
COMMIT;
Run Code Online (Sandbox Code Playgroud)
我试过添加,returning id但它不起作用。我有:
查询没有结果数据的目的地
我有两个表可以执行一些批量插入:
第一INSERT:
values_data = "($$key_1$$), ($$key_2$$)"
INSERT INTO key (key_name) VALUES values_data
Run Code Online (Sandbox Code Playgroud)
秒INSERT:
values_data = "(1, `the id of the first value inserted in key`)
, (1, `the id of the sec value inserted in key`)"
INSERT INTO related_key (related_key_id, key_id) VALUES values_data
Run Code Online (Sandbox Code Playgroud)
我不知道如何做第二个,INSERT因为我不知道如何为插入到key表中的行获取这些 id 。
或者有没有更好的方法来做到这一点?
我有两个表,proj: id name和proj_reports: id, position, created_at, key_id, proj_id我想从选择key_reports每个proj_id:
- total number of `key_id` which can be done with `count(.key_id)`
- total number of DISTINCT `key_id` `count(DISTINCT .key_id)`
- total number of `key_id` where `position` > 1
- total number of `key_id` where `position` > 2 AND < 5
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是我不知道如何添加这些条件来检查位置是 > 或 < 一个数字还是在一个范围内。
我有以下选择,它是从带有列的表中选择的:
id、project_id、keyword_id、位置、数据示例:
i, p_id, k_id, p
1, 1, 1, 4
2, 1, 1, 5
3, 1, 1, 6
5, 1, 2, 7
6, 1, 2, 8
7, 1, 3, 5
8, 1, 3, 7
Run Code Online (Sandbox Code Playgroud)
询问
SELECT
pr.project_id,
COUNT(DISTINCT pr.keyword_id) as total_keywords,
COUNT(CASE WHEN position BETWEEN 4 AND 10 THEN position ELSE NULL END ) AS pos4,
date(pr.created_at) AS created_at
FROM
project_reports pr
GROUP BY pr.project_id, date(created_at)
Run Code Online (Sandbox Code Playgroud)
我只想在 pos 4-10 中获取不同的 keyword_id 的数量。但是使用我的SELECT我得到了所有这些。
预期数据示例:
p_id, total_keywords, pos4
1, 3, …Run Code Online (Sandbox Code Playgroud) 我有一个物化视图,创建大约需要 57 秒,并且我使用的是 PostgreSQL 9.4。
当我插入表时,触发器将调用触发器函数,该函数将REFRESH MATERIALIZED VIEW CONCURRENTLY view触发触发器after each statement(插入、更新、删除)
发生的情况是,执行插入操作大约需要 57 秒。
如何解决此问题并仍然使用物化视图?
我已经实现了很长时间,从来没有出现过这个问题,最近我添加了pgbouncer,会不会是这个原因?
我需要使用两个表构建一些报告:
AuthorTitles: id(pk), author_id, title_id
AuthorReports: id(pk), author_id, title_id, items_sold, date
Run Code Online (Sandbox Code Playgroud)
我的报告需要输出以下内容: author_id, max_items_sold_wavg, items_sold_wavg, date
下面的代码可能有一些错误,请检查小提琴。
max_items_sold_wavg 是空闲查询的加权平均值:
WITH maxitems AS (
SELECT
at.author_id,
at.title_id,
max(ar.items_sold) as sold,
ar.date::date as date
FROM author_titles at
LEFT JOIN author_reports ar ON ar.author_id = at.author_id AND at.title_id = ar.title_id
GROUP BY 1, 2, 4
), totitems AS (
SELECT
mi.author_id
count(ti.title_id) as total,
count(CASE WHEN (mi.sold = 1) THEN mi.title_id END) AS sold1,
count(CASE WHEN (mi.sold = 2) THEN mi.title_id END) AS …Run Code Online (Sandbox Code Playgroud) 从带有列的表中: id(pk), type_id, book_id, title_id, page_id, lines(int4), created_at(date)
如何选择带有min(lines)和max(lines)for (type_id, book_id, title_id, page_id) 的行以及created_atwhen min(lines) 的值和最大值的值。
虚拟数据:
type_id, book_id, title_id, page_id, lines, created_at
1, 1, 1, 1, 12, 2015-04-01
1, 1, 1, 1, 10, 2015-03-01
1, 1, 1, 1, 11, 2015-03-02
1, 1, 1, 2, 3, 2015-04-01
1, 1, 1, 2, 5, 2015-03-01
1, 1, 1, 2, 6, 2015-03-04
Run Code Online (Sandbox Code Playgroud)
预期输出:
type_id, book_id, title_id, page_id, min, min_created_at, max, max_created_at
1, 1, 1, 1, 10, 2015-03-01, …Run Code Online (Sandbox Code Playgroud) postgresql ×11
aggregate ×1
bulk-insert ×1
concurrency ×1
cte ×1
insert ×1
join ×1
pgbouncer ×1
plpgsql ×1