Sql 如何通过过程根据其他列的值更新列值?

Sql 如何通过过程根据其他列的值更新列值?,sql,postgresql,Sql,Postgresql,在PostgreSQL数据库中,我有一个名为RELATIONSHIP的表: | SURVEY_ID | EMPLOYEE | ORGANIZATION_NAME | STATUS (default: false) | |--------------------------------------|----------|-------------------|-------------------------| | d5f9c639-13e6-

PostgreSQL数据库中,我有一个名为
RELATIONSHIP
的表:

| SURVEY_ID                            | EMPLOYEE | ORGANIZATION_NAME | STATUS (default: false) |
|--------------------------------------|----------|-------------------|-------------------------|
| d5f9c639-13e6-42c1-9043-30783981724b | Mark     | Apple             | false                   |
| d5f9c639-13e6-42c1-9043-30783981724b | Bob      | Apple             | true                    |
此表具有可由下一条sql语句创建的唯一键:

ALTER TABLE RELATIONSHIP ADD CONSTRAINT RELATIONSHIP_UNIQUE_KEY UNIQUE (SURVEY_ID, EMPLOYEE);
假设我想在
RELATIONSHIP
表中按过程添加新的3条记录

CALL creator(
    'd5f9c639-13e6-42c1-9043-30783981724b',
    ARRAY['Mark', 'Bob', 'Kate'],
    ARRAY['Google', 'Google', 'HP']
);
如果
SURVEY\u ID
EMPLOYEE
值是唯一的,并且表中没有此类记录,我希望将该记录添加到表中。例如,第三条记录在开始时不在表中。这就是为什么我加上它。同时,如果
SURVEY\u ID
EMPLOYEE
值不是唯一的,并且表中有这样的记录,我不想添加它们。例如,第一个和第二个记录。问题是,如果status为true,我需要更新
ORGANIZATION\u NAME
列的值。例如,第一条记录的状态为false。因此,我需要将苹果的
ORGANIZATION\u NAME
列的值更新到谷歌。第二条记录不变。如何正确进行此更新

换句话说,我最终想要这样的结果:

| SURVEY_ID                            | EMPLOYEE | ORGANIZATION_NAME | STATUS (default: false) |
|--------------------------------------|----------|-------------------|-------------------------|
| d5f9c639-13e6-42c1-9043-30783981724b | Mark     | Google            | false                   |
| d5f9c639-13e6-42c1-9043-30783981724b | Bob      | Apple             | true                    |
| d5f9c639-13e6-42c1-9043-30783981724b | Kate     | HP                | false                   |
现在我的程序如下所示:

CREATE OR REPLACE PROCEDURE creator(SURVEY_IDENTIFIER uuid, EMPLOYEES VARCHAR[], ORGANIZATION_NAMES VARCHAR[]) AS $FUNCTION$
    BEGIN
        INSERT INTO RELATIONSHIP (SURVEY_ID, EMPLOYEE, ORGANIZATION_NAME) 
        SELECT 
            SURVEY_IDENTIFIER SURVEY_ID,
            EMPLOYEE FROM UNNEST(ARRAY[EMPLOYEES]) EMPLOYEE,
            ORGANIZATION_NAME FROM UNNEST(ARRAY[ORGANIZATION_NAMES]) ORGANIZATION_NAME
        ON CONFLICT ON CONSTRAINT RELATIONSHIP_UNIQUE_KEY 
        DO NOTHING;
    END;
$FUNCTION$ LANGUAGE plpgsql;

问题

SQL Error [21000]: ERROR: ON CONFLICT DO UPDATE command cannot affect row a second time Tip: Ensure that no rows proposed for insertion within the same command have duplicate constrained values.
添加您建议的
选择DISTINCT
后,问题部分解决

如果我使用这些值调用过程,则不会出现错误:

CALL creator(
  '99c89a24-fff2-4cbc-a542-b1e956a352f9',
  ARRAY['Mark', 'Kate', 'Mark'],
  ARRAY['NEXT', 'U12', 'NEXT']
);
如果我使用以下值调用过程,问题是相同的:

CALL creator(
  '99c89a24-fff2-4cbc-a542-b1e956a352f9',
  ARRAY['Mark', 'Kate', 'Mark'],
  ARRAY['NEXT', 'U12', 'HP']
);

你认为在这种情况下可以做什么?我认为在这种情况下,最好的方法是设置
ORGANIZATION\u NAME
的最后一个值。也就是说,最好设置
HP

您想要更改
ON CONFLICT
子句:

INSERT INTO RELATIONSHIP (SURVEY_ID, EMPLOYEE, ORGANIZATION_NAME) 
    SELECT SURVEY_IDENTIFIER as SURVEY_ID,
           u.EMPLOYEE, u.ORGANIZATION
    FROM UNNEST(ARRAY[EMPLOYEES],
                ARRAY[ORGANIZATION_NAMES]
               )  u(EMPLOYEE, ORGANIZATION_NAME)
    ON CONFLICT ON CONSTRAINT RELATIONSHIP_UNIQUE_KEY 
        DO UPDATE SET ORGANIZATION_NAME = EXCLUDED.ORGANIZATION_NAME
                  WHERE NOT RELATIONSHIP.STATUS;
注意,我还将
FROM
子句更改为对数组进行并行取消测试。我不认识您问题中查询中使用的双
语法

对于最后一个问题,我认为这个版本的查询可以工作:

    SELECT DISTINCT ON (u.EMPLOYEE) SURVEY_IDENTIFIER as SURVEY_ID,
           u.EMPLOYEE, u.ORGANIZATION
    FROM UNNEST(ARRAY[EMPLOYEES],
                ARRAY[ORGANIZATION_NAMES]
               ) WITH ORDINALITY u(EMPLOYEE, ORGANIZATION_NAME, n)
    ORDER BY u.EMPLOYEE, n DESC

谢谢你的回答。在我看来,更新
ORGANIZATION\u NAME
列的值时需要一个条件。正如我之前在帖子中所说,只有当现有记录的
STATUS
列具有
false
值时,我才需要更新
ORGANIZATION\u NAME
列的值。例如,马克的组织名称已更改,但鲍勃的组织名称未更改。你对这一刻有什么想法吗?@Nurzhanogerbek。您可以添加一个
WHERE
子句。对于这个问题,很抱歉,但是我需要如何正确地调用这个过程?在我最初的帖子中,您可以注意到我如何调用过程的示例代码。现在,当我尝试运行该过程时,它会向我显示这样的错误:
SQL错误[42P01]:错误:表“u”的子句条目中缺少。其中:PL/pgSQL函数创建者(uuid,字符变化[],字符变化[])SQL语句第3行
。你有什么想法吗?我从
u.ORGANIZATION\u NAME
改为
excluded.ORGANIZATION\u NAME
。现在它说,
where
condition:
SQL Error[42702]:Error:column reference“status”不明确
@NurzhanNogerbek。
选择DISTINCT
是否解决该问题?