【问题标题】:Exclude "grouped" data from query从查询中排除“分组”数据
【发布时间】:2017-07-24 23:52:36
【问题描述】:

我有一个看起来像这样的表(简化):

  CREATE TABLE IF NOT EXISTS records (
    user_id   uuid NOT NULL
    ts        timestamptz NOT NULL,
    op_type   text NOT NULL,
    PRIMARY KEY (user_id, ts, op_type)
  );

出于实际目的,我无法更改主键。

我正在尝试编写一个查询,以获取给定 user_id 的所有 records,其中,对于特定记录,tsop_type 与排除数组不匹配。

我不太确定正确的 postgres 术语,所以让我看看这个例子是否让我的约束更清晰:

这个数组看起来像这样(在 JavaScript 中):

var excludes = [
  [DATE1, 'OP1'],
  [DATE2, 'OP2']
]

如果对于给定的用户 ID,数据库中有如下所示的行:

             ts             |   op_type   
----------------------------+-------------
 DATE1                      | OP1
 DATE2                      | OP2
 DATE1                      | OP3
 DATE2                      | OP1
 OTHER DATE                 | OP1
 OTHER DATE                 | OP2

然后,使用上面的excludes,我想运行一个查询,返回除前两行之外的所有内容,因为它们完全匹配。

我的尝试是这样做:

client.query(`
    SELECT * FROM records
      WHERE
        user_id = $1
        AND (ts, op_type) NOT IN ($2)
`, [userId, excluding])

但我得到“未实现匿名复合类型的输入”。我不确定如何正确输入excluding,或者这是否是正确的方法。

【问题讨论】:

  • 没有$0这样的东西,变量以$1开头。
  • 问题中的错字,谢谢指出

标签: sql postgresql node-postgres


【解决方案1】:

查询可能如下所示

SELECT * 
FROM records
WHERE user_id = 'a0eebc999c0b4ef8bb6d6bb9bd380a11'
AND (ts, op_type) NOT IN (('2016-01-01', 'OP1'), ('2016-01-02', 'OP2'));

因此,如果您想将条件作为单个参数传递,那么excluding 应该是格式为的字符串:

('2016-01-01', 'OP1'), ('2016-01-02', 'OP2')

似乎没有简单的方法将条件字符串作为参数传递给query()。您可以尝试编写一个函数来获取正确格式的字符串(我不是 JS 开发人员,但这段代码似乎运行良好):

excluding = function(exc) {
    var s = '(';
    for (var i = 0; i < exc.length; i++)
        s = s+ '(\''+ exc[i][0]+ '\',\''+ exc[i][1]+ '\'),';
    return s.slice(0, -1)+ ')';
};

var excludes = [
    ['2016-01-01', 'OP1'],
    ['2016-01-02', 'OP2']
];

// ...

client.query(
    'SELECT * FROM records '+
    'WHERE user_id = $1 '+
    'AND (ts, op_type) NOT IN ' + excluding(excludes),
    [userId])

【讨论】:

  • 这似乎确实有效——关于如何让类似的东西转义以正确使用 node-postgress 的任何想法?关于我上面尝试的 $1、$2 为什么不起作用的任何想法?
  • @AaronYodaiken 那是因为你没有使用$1$2,你使用了$0$1,这是不正确的,格式化变量以$1开头。
  • @vitaly-t - 这是一个明显的错误,但问题是如何格式化这种表达式并将其正确传递给query()
  • 上面的例子不是已经提供了所有的细节吗?与node-postgres 一起使用有什么问题?
  • @klin 欢迎您!如果您想要一个非常强大的查询格式化引擎,除其他外,请查看pg-promise
猜你喜欢
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-21
  • 1970-01-01
  • 2018-04-01
相关资源
最近更新 更多