通过 pymysql 执行查询未返回与 MySQL 中的 运行 相同的结果
Executing query through pymysql not returning the same results as running in MySQL
我是 Python 和 PyMySQL 的新手,所以我可能配置有误。
我连接到 MySQL 没有任何问题。我在 table 上执行了 SELECT 和 DESC 测试,并且能够查看结果。
我现在有一个查询,我将日期参数替换到其中并希望返回列(客户)的计数和客户总数乘以一个值。
客户数返回正确,但产品计算 returns None。在执行查询之前,我将其打印到控制台并将其复制到 MySQLWorkbench 到 运行,然后返回正确的值。
在我的 main 模块中,我连接到数据库并获得一个游标。然后我获取要在查询中使用的日期值并调用执行查询的函数。
connection = dbConnection()
cursor = connection.cursor()
startDate = input("enter start date (yyyy-mm-dd): ").strip()
endDate = input("enter end date (yyyy-mm-dd): ").strip()
my_queries.queryTotals(cursor, startDate, endDate)
connection.close()
在我的 my_queries 模块中,我有查询并将输入的日期替换为查询字符串,然后执行查询并获取结果:
totalsSQL = '''select
@total:=count(cus.customer_id) as customers, format(@total * 1.99, 2) as total
from customer cus
join membership mem on mem.membership_id=cus.current_membership_id
where mem.request='START'
and (mem.purchase_date > (unix_timestamp(date('{}'))*1000) and mem.purchase_date < unix_timestamp(date('{}'))*1000);'''
formattedSQL = totalsSQL.format(startDate, endDate)
cursor.execute(formattedSQL)
result = cursor.fetchone()
我得到的结果是 (32, None) 而不是获取第二列值的数值。
我在这里错过了什么?
谢谢。
您不能将变量用于聚合函数,并稍后在同一个 SELECT
列表中引用它。在选择所有行之前,聚合不会获得它们的值,但在选择行时会计算其他列。
只需在两个地方使用 COUNT(*)
。
SELECT COUNT(*) AS customers, FORMAT(COUNT(*) * 1.99, 2) AS total
join membership mem on mem.membership_id=cus.current_membership_id
where mem.request='START'
and (mem.purchase_date > (unix_timestamp(date('{}'))*1000)
and mem.purchase_date < unix_timestamp(date('{}'))*1000)
此外,为了防止 SQL 注入,您应该使用参数化查询而不是用 format()
.
替换变量
totalsSQL = '''
SELECT COUNT(*) AS customers, FORMAT(COUNT(*) * 1.99, 2) AS total
join membership mem on mem.membership_id=cus.current_membership_id
where mem.request='START'
and (mem.purchase_date > (unix_timestamp(date(%s))*1000)
and mem.purchase_date < unix_timestamp(date(%s))*1000)
'''
cursor.execute(totalsSQL, (startDate, endDate))
我是 Python 和 PyMySQL 的新手,所以我可能配置有误。
我连接到 MySQL 没有任何问题。我在 table 上执行了 SELECT 和 DESC 测试,并且能够查看结果。
我现在有一个查询,我将日期参数替换到其中并希望返回列(客户)的计数和客户总数乘以一个值。
客户数返回正确,但产品计算 returns None。在执行查询之前,我将其打印到控制台并将其复制到 MySQLWorkbench 到 运行,然后返回正确的值。
在我的 main 模块中,我连接到数据库并获得一个游标。然后我获取要在查询中使用的日期值并调用执行查询的函数。
connection = dbConnection()
cursor = connection.cursor()
startDate = input("enter start date (yyyy-mm-dd): ").strip()
endDate = input("enter end date (yyyy-mm-dd): ").strip()
my_queries.queryTotals(cursor, startDate, endDate)
connection.close()
在我的 my_queries 模块中,我有查询并将输入的日期替换为查询字符串,然后执行查询并获取结果:
totalsSQL = '''select
@total:=count(cus.customer_id) as customers, format(@total * 1.99, 2) as total
from customer cus
join membership mem on mem.membership_id=cus.current_membership_id
where mem.request='START'
and (mem.purchase_date > (unix_timestamp(date('{}'))*1000) and mem.purchase_date < unix_timestamp(date('{}'))*1000);'''
formattedSQL = totalsSQL.format(startDate, endDate)
cursor.execute(formattedSQL)
result = cursor.fetchone()
我得到的结果是 (32, None) 而不是获取第二列值的数值。
我在这里错过了什么?
谢谢。
您不能将变量用于聚合函数,并稍后在同一个 SELECT
列表中引用它。在选择所有行之前,聚合不会获得它们的值,但在选择行时会计算其他列。
只需在两个地方使用 COUNT(*)
。
SELECT COUNT(*) AS customers, FORMAT(COUNT(*) * 1.99, 2) AS total
join membership mem on mem.membership_id=cus.current_membership_id
where mem.request='START'
and (mem.purchase_date > (unix_timestamp(date('{}'))*1000)
and mem.purchase_date < unix_timestamp(date('{}'))*1000)
此外,为了防止 SQL 注入,您应该使用参数化查询而不是用 format()
.
totalsSQL = '''
SELECT COUNT(*) AS customers, FORMAT(COUNT(*) * 1.99, 2) AS total
join membership mem on mem.membership_id=cus.current_membership_id
where mem.request='START'
and (mem.purchase_date > (unix_timestamp(date(%s))*1000)
and mem.purchase_date < unix_timestamp(date(%s))*1000)
'''
cursor.execute(totalsSQL, (startDate, endDate))