在列的子集上选择“不同”,命名要返回的不同列集

Tom*_*Doe 3 postgresql

我正在使用 PostgreSQL 并且有两个表:

Table_A
colA | colB | colC | colD | colE | colF | colG | colH | colI | colJ

Table_B
colA | colB | colC | columnD | colE | columnF | colG | colH | colI | colJ
Run Code Online (Sandbox Code Playgroud)

我正在尝试将多行插入table_B到 中table_A。我的问题是Table_A有一个基于colA, colB, colC, colD, and colE. Table_B没有这个限制,这意味着简单的方法insert不起作用:

INSERT INTO Table_A (colA, colB, colC, colD, colE, colF, colG, colH, colI, colJ) 
SELECT colA, colB, colC, columnD, colE, columnF, colG, colH, colI, colJ FROM Table_B;
Run Code Online (Sandbox Code Playgroud)

我正在尝试通过DISTINCT在我的选择中使用来解决这个问题Table_Bselect distinct但是,我无法确定中使用的 5 个主键列的正确语法Table_A,并选择要插入的所有 10 列。我努力了

INSERT INTO Table_A (colA, colB, colC, colD, colE) 
SELECT DISTINCT colA, colB, colC, columnD, colE FROM Table_B;
Run Code Online (Sandbox Code Playgroud)

它正确地提取唯一的条目,但不填充列 FJ,我已经尝试过

INSERT INTO Table_A (colA, colB, colC, colD, colE, colF, colG, colH, colI, colJ) 
SELECT DISTINCT(colA, colB, colC, columnD, colE) colA, colB, colC, columnD, colE, columnF, colG, colH, colI, colJ FROM Table_B;
Run Code Online (Sandbox Code Playgroud)

但这会失败,因为第一个列条目是 5 个唯一列的包装版本,并且由于列长度限制而导致插入失败 - 括号中SELECT DISTINCT返回 '' ,这显然不适合:

错误:值对于类型字符变化来说太长(12)

我的目标是形成一个查询,获取colA, colB, colC, columnD, colEfrom的所有唯一组合Table_B,并插入这些完整行,包括columnF, colG, colH, colI, colJ插入Table_A

Ste*_*vie 5

你快到了。SELECT DISTINCT正如您所发现的,返回该组列。如果您DISTINCT ON改为使用,您将获得您正在查找的行。

INSERT INTO Table_A 
    (colA, colB, colC, colD, colE, colF, colG, colH, colI, colJ) 
SELECT DISTINCT ON (colA, colB, colC, columnD, colE) 
    colA, colB, colC, columnD, colE, columnF, colG, colH, colI, colJ 
FROM
    Table_B
Run Code Online (Sandbox Code Playgroud)

正如 ypercube 和Postgres 文档中所指出的,您可以通过添加来改进此查询ORDER BY。如果没有它,两个冲突行之间的选择似乎是不可预测的。

INSERT INTO Table_A 
    (colA, colB, colC, colD, colE, colF, colG, colH, colI, colJ) 
SELECT DISTINCT ON (colA, colB, colC, columnD, colE) 
    colA, colB, colC, columnD, colE, columnF, colG, colH, colI, colJ 
FROM
    Table_B
ORDER BY
    colA, colB, colC, columnD, colE    -- needed as it is
--  , colX, colY                       -- to choose which row to pick
  ;
Run Code Online (Sandbox Code Playgroud)