2017-07-30 95 views
2

我的应用程序允许用户匹配,并且我不希望他们在匹配结束后的间隔内匹配更多次。使用NOT IN和NULL处理查询

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

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

SELECT user_id FROM users WHERE user_id NOT IN %s 

,这仅仅是子查询,并有在那里许多许多其他条件,但问题是,当Redis的返回一个空列表由于用户在该时间间隔内未处于活动状态,NOT IN()会返回错误。

处理它的最好方法是什么?用例和时间?此外,我想在默认情况放个假阴性的user_id列表redis的回报,但我不喜欢那么多这种破解

编辑: 我的查询的样本是:

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,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的元组的内部,使得它永远不是空的,但我不喜欢这个黑客,我希望能找到一个更好的解决方案。

+3

编辑您的问题并提供样本数据和期望结果以显示错误是什么。你以'%s'传递什么?什么是错误?涉及“NULL”的地方在哪里? –

回答

2

相反的user_id NOT IN (%s)你可以使用user_id <> ALL(ARRAY[%s]::int[])NOT user_id = ANY(ARRAY[%s]::int[])(请注意,我建议排除从参数值parenthesizes)

因此,对于非空列表:

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,)) 
+0

这正是我问的。谢谢 – 91DarioDev

+0

@ user8372336顺便说一句,因为你没有在标签列表中指定'psycopg2'我在问题主体中错过了它。查看更新。 – Abelisto

0

SIMPL TSQL查询可以被当作使用:

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

例如:

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

其中用户是一个表名,用户名是列名,和 '兰吉特' 和 'JHA' 提供的两个值。

+0

问题是该列表是动态的,有时可能是空的。当它是空的我得到那个错误 – 91DarioDev

0

您可以在这里尝试异常处理。事情是这样的 -

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