Python - 光标 - 列表中的多个过滤器

Python - Cursor - Multiple filters from lists

我想要运行一个基于两个列表中的值过滤两列的查询。

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

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

但是来自客户的值和 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 进行上述查询?

谢谢!

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

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. 有可能匹配错误的记录:'John' 的 WHERE customers in ("John","Peter") AND customers_numbers IN ('1','2') 没有 care/check 有 cust_number 1 或 2。所以它可以匹配 John-2 和 Peter-1,而不是你想要的 John-1 和 Peter-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 更容易参数化。