【问题标题】:Compare table with array in Postgres在 Postgres 中比较表和数组
【发布时间】:2020-06-18 17:03:09
【问题描述】:

我需要将我的数组与表格进行比较。

我需要知道数组中存在哪些代码,而表中缺少哪些代码。 以及表中存在哪些代码,而数组中缺少哪些代码。

我正在使用 Node+KnexJS+PostgreSQL:

const myArray = `array['10001517','1509','1524','155400X','903B','910','1009201X']`
let divergence = await app.db.raw(`
    select file, t.code as acc_missing
    from unnest(${myArray}) file full join
        table_a as t 
        on t.code LIKE file
    where t.code is null or file is NULL
    AND t.version LIKE '010'
    AND t.inst = 300
`)

const errorDivergence = divergence.rows

我当前的查询会这样做,但会产生以下错误:

(node:26060) UnhandledPromiseRejectionWarning:
error: FULL JOIN is only supported with merge-joinable or hash-joinable join conditions

【问题讨论】:

    标签: sql node.js postgresql outer-join


    【解决方案1】:

    就像错误消息说的那样,Postgres 只支持FULL [OUTER] JOIN 的连接条件,可用于合并连接或哈希连接。 t.code LIKE file 没有资格。

    这是一个已知的限制。对这种罕见的案例没有足够的兴趣来激发修复。见:

    但是,您的问题中没有任何内容表明您实际上需要LIKE

    我需要知道数组中存在哪些代码,而表中缺少哪些代码。以及表中存在哪些代码,而数组中缺少哪些代码。

    这表明相等 (=) - 效果很好:

    SELECT file, t.code AS acc_missing
    FROM   unnest('{10001517,1509,1524,155400X,903B,910,1009201X}'::text[]) file
    FULL   join table_a t ON t.code = file    -- !
    WHERE  t.code IS NULL
       OR  file IS NULL AND t.version LIKE '010' AND t.inst = 300;
    

    您格式化查询的方式表明您需要在(t.code IS NULL OR file IS NULL) 周围加上括号。 ANDOR 之前绑定。 The manual about operator precedence.

    OTOH,添加的谓词 AND t.version LIKE '010' AND t.inst = 300 只有在没有括号的情况下才有意义。因此,这是使用 LEFTRIGHT JOIN 实现原始查询的解决方法:

    SELECT file, t.code AS acc_missing
    FROM   unnest('{10001517,1509,1524,155400X,903B,910,1009201X}'::text[]) file
    LEFT   JOIN table_a t ON t.code LIKE file
    WHERE  t.code IS NULL
    
    UNION ALL
    SELECT file, t.code AS acc_missing
    FROM   unnest('{10001517,1509,1524,155400X,903B,910,1009201X}'::text[]) file
    RIGHT  JOIN table_a t ON t.code LIKE file
    WHERE  file IS NULL AND t.version LIKE '010' AND t.inst = 300;
    

    或者:

    SELECT file, t.code AS acc_missing
    FROM   unnest('{10001517,1509,1524,155400X,903B,910,1009201X}'::text[]) file
    LEFT   JOIN table_a t ON t.code LIKE file
    WHERE  t.code IS NULL
    
    UNION ALL
    SELECT NULL, t.code
    FROM   table_a t
    WHERE (t.code LIKE ANY ('{10001517,1509,1524,155400X,903B,910,1009201X}'::text[])) IS NOT TRUE;
    

    db小提琴here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 2018-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-25
      • 2019-04-07
      相关资源
      最近更新 更多