2011-03-21 64 views
2

假设我有一个SQLite表是这样的:如何撰写此查询?

Id|B|C|D 

而且我有一个包含Id一些值的列表。也许[1,3,45,67](类似的东西)。

我想获得列表中Id的行,其B值大于5,并最终命令C

我认为我为此编出的标题太糟糕了,如果你能想到更好的标题,请修改它。

回答

3

相关问题,从中我会偷亚历马尔泰利的答案:

Parameter substitution for a SQLite "IN" clause

这是我所创建的数据:

sqlite> create table x(a,b,c,d); 
sqlite> insert into x values(1, 10, 2, null); 
sqlite> insert into x values(2, 10, 3, null); 
sqlite> insert into x values(3, 10, 4, null); 

而Python来取,

>>> ids = [2, 3] 
>>> query = "SELECT b, c, d FROM x WHERE a IN ({0}) AND b > 5 ORDER BY c".format(','.join('?' for i in ids)) 
>>> query 
'SELECT b, c, d FROM x WHERE a IN (?,?) AND b > 5 ORDER BY c' 
>>> conn.execute(query, ids).fetchall() 
[(10, 3, None), (10, 4, None)] 
+1

+1,但该方案在超过SQLITE_MAX_VARIABLE_NUMBER时将失败,即语句中占位符的数量(默认值为999)。 – XORcist 2011-03-21 15:35:02

0

我不知道蟒蛇和SQLite之间的API,但是这个伪代码应该有所帮助:

list_id = [1,3,45,67] 
ids = ",".join(["%s" % el for el in list_id]) 
print 'SELECT * FROM table WHERE B>5 AND ID IN (%s) ORDER BY C DESC' % (ids) 
+2

请记住,你既不应该使用'SELECT *'你也不应该建立使用字符串连接查询(使用预处理语句这里)。 – 2011-03-21 14:22:56

3

假设ids_list是你的ID和表名的列表是你的表:

c = sqlite3.connect('foo').cursor() 
c.execute(""" 
select Id, B, C, D 
from tablename 
where 
    Id in (%s) and 
    B >= 5 
order by C 
""" % ",".join(str(int(id)) for id in ids_list)) 

%s替换是不好的做法,因为受SQL注入。应该使用?来代替,但它似乎不适用于in子句。因此,STR(INT(ID))绝招,为“的sanitize”(或检查)的ID值(会失败,如果没有有效的值)

+0

为什么使用占位符时可以正确使用它的技巧? – 2011-03-21 15:39:39

+1

是的,如果列表的长度足够小,它会更好地动态地构建占位符,就像你提出的那样。占位符的主要目的是防止SQL注入,如果ids列表不是来自用户,而是另一个查询,例如,应该没问题。请注意,在后一种情况下,联合会更好:) – 2011-03-21 15:44:28

2

我会用以下内容:

ids = [1, 3, 45, 67] 
cnx = sqlite3.connect('my_database.db') 
cursor = cnx.cursor() 
cursor.execute(""" 
    SELECT Id, B, C, D FROM table 
    WHERE Id IN (%s) AND B > 5 ORDER BY C 
    """ % ','.join('?' * len(ids)), tuple(ids)) 
results = cursor.fetchall()