使用node和pg-promise连接到postgres中的值列表

时间:2019-04-04 20:40:44

标签: node.js postgresql pg-promise

我正在尝试创建一个查询,例如

SELECT e.col1, e.col2 
FROM entity e
INNER JOIN (
    VALUES
    (1377776),(1377792),(1377793),(1377794),(1377795),(1377796)
) ex(ex_entityid) ON (entityid = ex_entityid)

鉴于我有一个包含数字13777xx的数组,该如何生成此查询?

我从以下问题中得到了这种语法:https://stackoverflow.com/a/17824797/425544。我的输入列表很大,以至于使用IN的速度太慢。

到目前为止,使用$ 0:csv,我可以将值设为逗号分隔的列表。我不知道如何设置值的格式,以使其带有括号。如果我不带:csv标记的数组,则在值之前添加“ array”,然后出现语法错误。

2 个答案:

答案 0 :(得分:1)

  

鉴于我有一个包含数字13777xx的数组,该如何生成此查询?

任意数字

如果您有实际的 array ,只需传递以下形式的数组文字即可:

multipart/form-data

对于只有一堆值的小型数组,您可以在联接中使用data.append('my_photo', { uri: uri, name: 'my_photo.jpg', type: 'image/jpg' }) fetch('endpoint', { method: 'PUT', headers : { 'x-ms-blob-type': 'BlockBlob' , }, body: data }) 构造:

'{1377776,1377792,1377793}'

对于字符串文字,您将需要如所示的显式类型转换。

对于长数组,将数组取消嵌套到集合(派生表),然后加入like mu commented会更有效:

ANY

使用与未嵌套编号匹配的列名,您可以方便地将短SELECT col1, col2 FROM entity WHERE entityid = ANY ($my_array::int[]); 子句用于连接条件。

请注意一个细微的区别:第一个查询隐式折叠输入中的重复项,而第二个查询使用联接为输入中的重复项生成重复项。您的选择。

或者,您也可以将各个值传递给SELECT col1, col2 FROM unnest(my_array::int[]) ex(entityid) JOIN entity USING (entityid); 表达式。但这通常比较慢。 (再次:折叠重复项。)例如:

USING

请参阅:

对于重复操作,您可以创建一个IN函数并传递各个数字作为参数(或选择单个数组文字)。参见:

不是那么随意的数字

如果您实际上要基于 “数字13777xx” 进行查询,这表示1377700和1377799之间的所有数字,请使用 ... WHERE entityid IN (1377776, 1377792, 1377793); < / strong>。喜欢:

VARIADIC

或者,最简单,最快的方法是,使用单个范围谓词修改generate_series()子句:

SELECT col1, col2 
FROM   generate_series(1377700, 1377799) entityid
JOIN   entity USING (entityid);

答案 1 :(得分:1)

这是非标准格式,因此您需要使用Custom Type Formatting

const wrap = arr => ({
    rawType: true,
    toPostgres: () => arr.map(a => pgp.as.format('($1)', [a])).join()
});

现在,您可以将这种包装好的数组用作简单的格式变量:

const data = [1377776, 1377792, 1377793];
db.any('... INNER JOIN (VALUES $1)', [wrap(data)]);