首页 > 解决方案 > Python - 光标 - 列表中的多个过滤器

问题描述

我想运行一个查询,根据两个列表中的值过滤两列。

基本上,我想模拟两个这样的过滤器:

SELECT *
FROM my_table
WHERE customers in ("John","Peter") AND customers_numbers IN ('1','2')

但是来自customers 和customers_number 的值在两个列表中。为了尝试这个,我正在编写以下代码:

list1 = ["John","Peter"]
list2 = [1,2]
query_sql = "DELETE FROM vw_bill_details WHERE customers in (%s) and customers_numbers in (%s)" % ','.join(['?'] * len(list1)) % ','.join(['?'] * len(list2))
cursor.execute(query_sql, list1,list2)

但我收到以下错误:

    query_sql = "DELETE FROM vw_bill_details WHERE customers in (%s) and customers_numbers in (%s)" % ','.join(['?'] * len(list1)) % ','.join(['?'] * len(list2))
TypeError: not enough arguments for format string

如何使用 python 进行上述查询?

谢谢!

标签: pythonsqllistfiltercursor

解决方案


您的查询中有错误,%这两个术语之间有一个额外的而不是逗号。此外,当您使用%包含多个术语的格式时,您需要将整个变量部分%放在括号后面:

query_sql = "DELETE FROM vw_bill_details WHERE customers in (%s) and customers_numbers in (%s)" % (','.join(['?'] * len(list1)), ','.join(['?'] * len(list2)))

改进:

  1. 考虑在文档字符串中编写查询,以便更容易阅读、编写和调试:

    query_sql = """DELETE FROM vw_bill_details
    WHERE customers in (%s)
    and customers_numbers in (%s)""" % (
    ','.join(['?'] * len(list1)), ','.join(['?'] * len(list2)))
    
  2. str.join()适用于任何可迭代对象,包括字符串,因此这些','.join(['?'] * len(list1))部分可以写成','.join('?' * len(list1))-?标记是单个字符串而不是具有单个元素的列表。

  3. 有可能匹配错误的记录:WHERE customers in ("John","Peter") AND customers_numbers IN ('1','2')'John' 的不关心/检查有 cust_number 1 或 2。所以它可以匹配 John-2 和 Peter-1,而不是你想要的 John-1和彼得 2。

    不匹配的例子可以在这里看到:http ://sqlfiddle.com/#!9/caa7f3/2

    您可以通过指定每个匹配的名称和编号来避免这种不匹配:

    WHERE (customers = 'John' AND customers_numbers = '1')
       OR (customers = 'Peter' AND customers_numbers = '2')
    

    也可以写成一对:

    WHERE (customers, customers_numbers) = ('John', 1)
    

    您可以通过以下方式将其扩展为多个选项:

    WHERE (customers, customers_numbers) IN (('John', 1), ('Peter', 2))
    

    ?这比上面的扩展 AND/OR 版本更容易用 s 参数化。


推荐阅读