Ниже приведен фиктивный пример, демонстрирующий отличие результатов запроса, реальный запрос является более сложным, поэтому в этом примере структура запроса может показаться излишней. Установите соединение с базой данных sqlite3 и добавьте для начала следующие записи:
import sqlite3
connection = sqlite3.connect(
'file:test_database',
detect_types=sqlite3.PARSE_DECLTYPES,
isolation_level=None,
check_same_thread=False,
uri=True
)
cursor = connection.cursor()
tableA_records = [(1, 202003), (2, 202003), (3, 202003), (4, 202004), (5, 202004), (6, 202004), (7, 202004), (8, 202004), ]
tableB_records = [(1, 202004), (2, 202004), (3, 202004), (4, 202004), (5, 202004),]
tableA_ddl = """
create table tableA
(
ID int,
RunYearMonth int
);
"""
tableB_ddl = """
create table tableB
(
ID int,
RunYearMonth int
);
"""
cursor.execute(tableA_ddl)
cursor.execute(tableB_ddl)
cursor.executemany("INSERT INTO tableA VALUES (?, ?)", tableA_records)
cursor.executemany("INSERT INTO tableB VALUES (?, ?)", tableB_records)
Теперь у нас есть две таблицы (A и B) с 8 и 5 записями соответственно. Я хочу посчитать записи с одинаковым идентификатором и датой между ними, когда дата 202004
.
У меня есть этот запрос сейчас:
SELECT COUNT(*)
FROM (
SELECT *
FROM `tableA`
WHERE `RunYearMonth` = 202004
) AS `A`
INNER JOIN (
SELECT *
FROM `tableB`
WHERE `RunYearMonth` = 202004
) AS `B`
ON `A`.`ID` = `B`.`ID`
AND `A`.`RunYearMonth` = `B`.`RunYearMonth`
Это, как и ожидалось, возвращает 2
при запуске в консоли sqlite.
Однако при запуске в Python вы получите другой результат.
q = """
SELECT COUNT(*)
FROM (
SELECT *
FROM `tableA`
WHERE `RunYearMonth` = 202004
) AS `map1`
INNER JOIN (
SELECT *
FROM `tableB`
WHERE `RunYearMonth` = 202004
) AS `map2`
ON `map1`.`ID` = `map2`.`ID`
AND `map1`.`RunYearMonth` = `map2`.`RunYearMonth`
"""
cursor.execute(q)
print(cursor.fetchall())
Вместо этого возвращается 5
, который фактически игнорирует WHERE
предложения в подзапросах и условие соединения имеют одинаковые RunYearMonth
, в обоих есть записи 1-5.
Что может вызвать эту разницу? Разве Python не просто пропускает строку запроса?
Соответствующие версии:
sqlite3.version == 2.6.0
sqlite3.sqlite_version == 3.31.1
sys.version == 3.6.5