我有以下查询,我想在其中替换列表中的级别和内容的值。
SELECT count(DISTINCT(USERS)) AS TOTAL_USERS FROM db.CCN
JOIN UCR ON CCN.COLLECTIVE = UCR.COLLECTIVE
WHERE USER NOT LIKE 'IMM%%'
AND USER NOT LIKE 'UWEB%%'
AND(
(CCN.CONTENT='C1' AND CCN.LEVEL='L1')OR
(CCN.CONTENT='C2' AND CCN.LEVEL='L2')OR
(CCN.CONTENT='C3' AND CCN.LEVEL='L3')
)
有什么方法可以简化此查询,以便能够使用 python 替换内容和级别的值?我曾想过使用两个 IN 表达式,但这不会以相同的方式工作。我有必须替换的内容和级别的组合列表。我宁愿避免当前的语法,因为我认为我必须使用 f 字符串来构建查询,并且我更喜欢使用 pymysql 支持的正确替换。我尝试过在 WHERE 中使用 CONCAT,但这太慢了。
谢谢你,
动态生成
OR
表达式序列,以创建具有适当数量的 %s
占位符的参数化语句。
content_levels = [('C1', 'L1'), ('C2', 'L2'), ('C3', 'L3')]
conditions = ' OR '.join(['(CCN.CONTENT=%s AND CCN.LEVEL=%s)'] * len(content_levels))
sql = f'''SELECT count(DISTINCT(USERS)) AS TOTAL_USERS FROM db.CCN
JOIN UCR ON CCN.COLLECTIVE = UCR.COLLECTIVE
WHERE USER NOT LIKE 'IMM%%'
AND USER NOT LIKE 'UWEB%%'
AND ({conditions})'''
# flatten content_levels
params = sum(content_levels, start=())
cursor.execute(sql, params)