使用 NOT IN 和 NULL 处理查询

Handle query using NOT IN and NULL

我的应用程序允许用户进行匹配,但我不希望他们在匹配结束后的一段时间内进行更多次匹配。

我用 (zadd) 匹配项和 unix 时间戳存储在 redis 上。

在我的 postgres 查询中,所以我希望能够做到:

SELECT user_id FROM users WHERE user_id NOT IN %s

那只是子查询,where 中还有很多其他条件,但问题是当 redis returns 一个空列表时,因为用户在该时间间隔内没有活动,NOT IN () returns 一个错误。

最好的处理方法是什么?用例和什么时候?我还想在列表 redis returns 中默认放置一个假的否定 user_id,但我不太喜欢这个 hack

编辑: 我的查询示例是:

UPDATE users SET status = %s WHERE user_id IN (SELECT user_id FROM users WHERE user_id NOT IN % LIMIT 1)

查询工作正常,但今天我在子查询中添加了 user_id NOT in %s 部分。我将 redis returns 的元组传递给那里(或者更好的是 redis returns 一个列表,然后我将它转换成一个元组)。它只包含 [1234, 3456, 678] 之类的整数。当元组不为空(内部至少有一个元素)时它工作正常但如果元组为空我得到这个错误:

psycopg2.ProgrammingError: ERROR:  syntax error at or near ")"
LINE 1: ...ocked = 0 AND bot_lang = 'en' AND user_id NOT IN () ORDER BY...

我确实解决了这个问题,默认情况下在元组中添加一个假的 user_id,这样它就永远不会为空,但我不喜欢这种技巧,我希望能够找到一个更好的解决方案。

简单的tsql查询可以写成:

select * from table_name where coulmnName NOT IN ('value1','value2','value3')

例如:

select username from user where user NOT IN ('ranjeet', 'jha') 

其中用户是 table_name,用户名是列名,'ranjeet' 和 'jha' 两个提供的值。

您可以在这里尝试异常处理。像这样 -

select coalesce(username,0) from user where user NOT IN ('ranjeet', 'jha') 
or user IS NULL;

您可以使用 user_id <> ALL(ARRAY[%s]::int[])NOT user_id = ANY(ARRAY[%s]::int[]) 而不是 user_id NOT IN (%s)(请注意,我建议从参数值中排除括号)

因此,对于非空列表:

select 1 <> all(array[1,2]::int[]);

对于空列表

select 1 <> all(array[]::int[]);

两者都很好。

Update: 对于psycopg2更好的方法是让它解析参数的格式。对于数组,它可能只是:

a = [1,2,3]
cursor.execute("... NOT user_id = ANY(%s) ...",(a,))