Postgres:使用查询输出创建列并更新列值

mmT*_*mmR 6 sql postgresql

我有一个没有主键的文件。为了加载文件并执行分析,我想连接 2 个现有列并将输出发送到一个新列。然后我将对这个结果列进行散列并将其用作 PK。

我什至还没有到散列部分,因为我一生都无法弄清楚如何用数据填充我的连接列。

我尝试使用的查询是:

ALTER TABLE members_250815
ADD COLUMN email_id VARCHAR;
UPDATE members_250815
INSERT INTO members_250815(email_id)(
SELECT ARRAY_TO_STRING(ARRAY[emailaddress, id], ' ') AS email_id
FROM members_250815);
Run Code Online (Sandbox Code Playgroud)

作为单独的查询

ALTER TABLE members_250815
ADD COLUMN email_id VARCHAR; 
Run Code Online (Sandbox Code Playgroud)

SELECT ARRAY_TO_STRING(ARRAY[emailaddress, id], ' ') AS email_id
FROM members_250815;
Run Code Online (Sandbox Code Playgroud)

似乎按照我希望的方式工作(即 - 1)创建新列和 2)连接 2 列)但是我的问题似乎是将它们连接在一起。

我真的在做一些愚蠢的事情吗?我试图研究这个几个小时,但我一无所获。基本上,我试图实现的任务是:

Create new column on existing table
Concatenate 2 existing columns
Run Code Online (Sandbox Code Playgroud)

获取连接的结果并使用此数据更新此新列,而不会影响我的任何其他现有数据。

这可能吗?

提前谢谢了

---更新260815

非常感谢您的快速建议,非常感谢!结合你的建议,我已经到了这里:

CREATE TABLE members_update AS 
SELECT * FROM members_250815;

ALTER TABLE members_update
   ADD COLUMN email_id VARCHAR;<br/>

UPDATE members_update
SET email_id = email || id;

ALTER TABLE members_update
   ADD COLUMN hashed_primary_key VARCHAR;

UPDATE members_update
SET hashed_primary_key = md5(email_id::VARCHAR);

ALTER TABLE members_update
   ADD CONSTRAINT hashed_primary_key_urn
   PRIMARY KEY (hashed_primary_key);

ANALYSE members_update;
Run Code Online (Sandbox Code Playgroud)

我已经检查过,在添加主键之前,一切都按预期工作。这是因为结果证明我的电子邮件字段包含许多 NULL 值,然后将这些值带入 email_id 和散列列,并阻止散列版本用作 PK。

因此,我一直在试验 IF THEN ELSE 和 WHERE ELSE 语句,例如

UPDATE members_update(
   IF email IS NOT NULL
   THEN SET email_id = email || id
   ELSE SET email_id = id
   END IF);
Run Code Online (Sandbox Code Playgroud)

我尝试了很多组合,有括号和没有括号等,但我永远无法让它工作!我想我很接近,但似乎无法让这最后一部分工作 - 有没有人有任何想法?

非常感谢,

标记

Jua*_*eza 5

问题是你的更新语句是错误的

您需要SET, 并且CASE应该是:

ALTER TABLE members_250815
    ADD COLUMN email_id VARCHAR;

UPDATE members_250815
SET email_id = CASE 
                   WHEN email IS NULL THEN id
                   ELSE email || id
               END;
Run Code Online (Sandbox Code Playgroud)

ARRAY_TO_STRING(ARRAY[emailaddress, id], ' ') 也可能有效,但需要进一步研究才能知道是否比仅连接字符串更有效。

创建 PK 列的更好方法: 只需更改表并添加一个串行列

SQL 小提琴演示

CREATE TABLE members_250815
    ("DMDUNIT" varchar(5), 
     "IND" int)
;

INSERT INTO members_250815 VALUES ('TM001', 1);
INSERT INTO members_250815 VALUES ('TM002', 1);
INSERT INTO members_250815 VALUES ('TM003', 1);

ALTER TABLE members_250815
ADD COLUMN id SERIAL NOT NULL PRIMARY KEY;
Run Code Online (Sandbox Code Playgroud)

附加信息

在 postgres 中更新非常慢。所以在某些情况下最好考虑只创建一个新表:

CREATE new_table AS 
    SELECT *, CASE 
                   WHEN email IS NULL THEN id
                   ELSE email || id
              END as email_id
    FROM members_250815
Run Code Online (Sandbox Code Playgroud)

进而

DROP TABLE IF EXITS members_250815;
ALTER TABLE new_table RENAME TO members_250815
Run Code Online (Sandbox Code Playgroud)

  • 使用 `||` 而不是 `+` 进行字符串连接。或者最好使用带有 `%s` 占位符的 `format(...)`。 (2认同)