我的应用程序允许用户匹配,我不希望他们在匹配结束后的间隔内匹配更多次。
我使用(zadd)匹配和unix时间戳存储在redis上。
在我的postgres查询中,所以我希望能够做到:
SELECT user_id FROM users WHERE user_id NOT IN %s
这只是子查询,其中有许多其他条件,但问题是当redis返回空列表时,因为用户在该间隔期间未处于活动状态,NOT IN()会返回错误。
处理它的最佳方法是什么?用例和什么时候?另外我想在默认情况下放一个假的负user_id在列表redis返回,但我不喜欢这个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返回的元组(或者更好的redis返回一个列表并将其转换为元组)。它只包含[1234,356,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,所以它永远不会是空的,但我不喜欢这个hack,我希望能够找到更好的解决方案。
答案 0 :(得分:2)
而不是user_id NOT IN (%s)
您可以使用user_id <> ALL(ARRAY[%s]::int[])
或NOT user_id = ANY(ARRAY[%s]::int[])
(请注意,我建议从参数值中排除括号)
所以,对于非空列表:
select 1 <> all(array[1,2]::int[]);
和空列表
select 1 <> all(array[]::int[]);
两者都很好。
更新:对于psycopg2
,更好的方法是让它解析参数格式。对于数组,它可能只是:
a = [1,2,3]
cursor.execute("... NOT user_id = ANY(%s) ...",(a,))
答案 1 :(得分:0)
Simpl tsql查询可以写成:
select * from table_name where coulmnName NOT IN ('value1','value2','value3')
例如:
select username from user where user NOT IN ('ranjeet', 'jha')
其中user是table_name,username是columnname,&#39; ranjeet&#39;和&#39; jha&#39;两个提供的值。
答案 2 :(得分:0)
您可以在此处尝试异常处理。像这样的东西 -
select coalesce(username,0) from user where user NOT IN ('ranjeet', 'jha')
or user IS NULL;