相关疑难解决方法(0)

选择每个GROUP BY组中的第一行?

正如标题所示,我想选择用a组成的每组行的第一行GROUP BY.

具体来说,如果我有一个purchases看起来像这样的表:

SELECT * FROM purchases;
Run Code Online (Sandbox Code Playgroud)

我的输出:

id | customer | total
---+----------+------
 1 | Joe      | 5
 2 | Sally    | 3
 3 | Joe      | 2
 4 | Sally    | 1

我想查询每个产品id的最大购买量(total)customer.像这样的东西:

SELECT FIRST(id), customer, FIRST(total)
FROM  purchases
GROUP BY customer
ORDER BY total DESC;
Run Code Online (Sandbox Code Playgroud)

预期产出:

FIRST(id) | customer | FIRST(total)
----------+----------+-------------
        1 | Joe      | 5
        2 | Sally    | 3

sql sqlite postgresql group-by greatest-n-per-group

1205
推荐指数
16
解决办法
95万
查看次数

如何在PostgreSQL中使用RETURNING和ON CONFLICT?

我在PostgreSQL 9.5中有以下UPSERT:

INSERT INTO chats ("user", "contact", "name") 
           VALUES ($1, $2, $3), 
                  ($2, $1, NULL) 
ON CONFLICT("user", "contact") DO NOTHING
RETURNING id;
Run Code Online (Sandbox Code Playgroud)

如果没有冲突,则返回如下内容:

----------
    | id |
----------
  1 | 50 |
----------
  2 | 51 |
----------
Run Code Online (Sandbox Code Playgroud)

但如果存在冲突,则不会返回任何行:

----------
    | id |
----------
Run Code Online (Sandbox Code Playgroud)

id如果没有冲突,我想返回新列,或者返回id冲突列的现有列.
可以这样做吗?如果是这样,怎么样?

sql postgresql upsert sql-returning

127
推荐指数
7
解决办法
4万
查看次数

SELECT或INSERT是否容易出现竞争条件?

我写了一个函数为一个简单的博客引擎创建帖子:

CREATE FUNCTION CreatePost(VARCHAR, TEXT, VARCHAR[])
RETURNS INTEGER AS $$
    DECLARE
        InsertedPostId INTEGER;
        TagName VARCHAR;
    BEGIN
        INSERT INTO Posts (Title, Body)
        VALUES ($1, $2)
        RETURNING Id INTO InsertedPostId;

        FOREACH TagName IN ARRAY $3 LOOP
            DECLARE
                InsertedTagId INTEGER;
            BEGIN
                -- I am concerned about this part.
                BEGIN
                    INSERT INTO Tags (Name)
                    VALUES (TagName)
                    RETURNING Id INTO InsertedTagId;
                EXCEPTION WHEN UNIQUE_VIOLATION THEN
                    SELECT INTO InsertedTagId Id
                    FROM Tags
                    WHERE Name = TagName
                    FETCH FIRST ROW ONLY;
                END;

                INSERT INTO Taggings (PostId, TagId) …
Run Code Online (Sandbox Code Playgroud)

sql postgresql concurrency upsert plpgsql

25
推荐指数
2
解决办法
8449
查看次数

使用ON CONFLICT从INSERT返回行而无需更新

我有一种情况,我经常需要从具有唯一约束的表中获取一行,如果不存在,则创建它并返回.例如我的表可能是:

CREATE TABLE names(
    id SERIAL PRIMARY KEY,
    name TEXT,
    CONSTRAINT names_name_key UNIQUE (name)
);
Run Code Online (Sandbox Code Playgroud)

它包含:

id | name
 1 | bob 
 2 | alice
Run Code Online (Sandbox Code Playgroud)

然后我想:

 INSERT INTO names(name) VALUES ('bob')
 ON CONFLICT DO NOTHING RETURNING id;
Run Code Online (Sandbox Code Playgroud)

也许:

 INSERT INTO names(name) VALUES ('bob')
 ON CONFLICT (name) DO NOTHING RETURNING id
Run Code Online (Sandbox Code Playgroud)

让它返回bob的id 1.但是,RETURNING只返回插入或更新的行.所以,在上面的例子中,它不会返回任何东西.为了让它按照需要运行,我实际上需要:

INSERT INTO names(name) VALUES ('bob') 
ON CONFLICT ON CONSTRAINT names_name_key DO UPDATE
SET name = 'bob'
RETURNING id;
Run Code Online (Sandbox Code Playgroud)

这看起来有点麻烦.我想我的问题是:

  1. 不允许(我)期望行为的原因是什么?

  2. 有没有更优雅的方式来做到这一点?

sql postgresql upsert postgresql-9.5

16
推荐指数
1
解决办法
3961
查看次数

postgresql 上的冲突 - 不能再次影响行

我有一张桌子,我在 data_id 上有自动编号/序列

tabledata
---------
data_id   [PK]
data_code [Unique]
data_desc
Run Code Online (Sandbox Code Playgroud)

示例代码:

insert into tabledata(data_code,data_desc) values(Z01,'red')
on conflict (data_code) do update set data_desc=excluded.data_desc
Run Code Online (Sandbox Code Playgroud)

工作正常,然后我再次插入

insert into tabledata(data_code,data_desc) values(Z01,'blue')
on conflict (data_code) do update set data_desc=excluded.data_desc
Run Code Online (Sandbox Code Playgroud)

我收到这个错误

[Err] 错误:ON CONFLICT DO UPDATE 命令不能再次影响行 提示:确保建议在同一命令中插入的行没有重复的约束值。

这是我的真实代码

insert into psa_aso_branch(branch_code,branch_desc,regional_code,status,created_date,lastmodified_date) 
    (select branch_code, branch, kode_regional, 
    case when status_data='Y' then true 
    else false end, current_date, current_date 
    from branch_history) on conflict (branch_code) do
    update set branch_desc = excluded.branch_desc, regional_code = excluded.regional_code,status = (case when excluded.status='Y' then true …
Run Code Online (Sandbox Code Playgroud)

postgresql

11
推荐指数
4
解决办法
2万
查看次数

从条件INSERT中获取Id

对于像这样的表:

CREATE TABLE Users(
    id SERIAL PRIMARY KEY,
    name TEXT UNIQUE
);
Run Code Online (Sandbox Code Playgroud)

以下操作的正确单一查询插入是什么:

给定用户name,插入新记录并返回新记录id.但如果name已经存在,只需返回id.

我知道PostgreSQL 9.5中的新语法ON CONFLICT(column) DO UPDATE/NOTHING,但我无法弄清楚,如果有的话,它可以提供帮助,因为我需要id返回.

这似乎RETURNING idON CONFLICT不属于一起.

sql postgresql concurrency upsert

8
推荐指数
1
解决办法
1893
查看次数