我正在学习在Python项目中使用MySQL查询。
我正在使用Python中的MySQLDB模块将数据上传到MySQL数据库,现在,我想比较数据并打印出差异。
我有3个表(仅包括相关列):
我需要根据日期比较同一人的'总数'。
例如从2020-05-02到2020-05-09,如果origdata总数和rawdata总数与匹配的日期和人员不匹配,我想打印origid,rawid,名称,日期和总数。
我可以比较并返回相关信息的查询是什么?
我要完成的工作类似于以下内容:
SELECT n.name
, o.date
, o.total
, r.total raw_total
FROM origdata o
LEFT
JOIN name n
ON n.origid = o.origId
LEFT
JOIN rawdata r
ON r.rawId = n.rawId
WHERE o.date >= '2020-05-02'
AND o.date < '2020-05-10'
GROUP
BY o.origId
, o.date
运行时,rawdata
。total
未显示正确的值; origdata
和total
。rawdata
的值相同。
非常感谢您的帮助!
如果您的“日期”列为DATETIME类型,则可以使用CAST:
total
由于您可能在同一表中具有相同日期的记录,因此首先需要将它们汇总(分组依据-总和)
SELECT n.name
, o.date
, o.total
, r.total raw_total
FROM origdata o
LEFT
JOIN name n
ON n.origid = o.origId
LEFT
JOIN rawdata r
ON r.rawId = n.rawId
WHERE CAST(o.date AS DATE) BETWEEN '2020-05-02' AND '2020-05-10'
GROUP
BY o.origId
, o.date
考虑到这只会在两个表中返回一致的日期。如果要包含空日期值,则需要使用LEFT AND RIGHT JOIN,因为MySql不支持OUTER JOINS
SELECT n.name, o.date,
o.total as orig_total,
r.total as raw_total
FROM
(
select o.origid, o.date, sum(o.total) as total
from origdata o
group by o.origid, o.date
) o
JOIN
(
select r.rawid, r.date, sum(r.total) as total
from rawdata r
group by r.rawid, r.date
) r
on o.origid = r.rawid
and o.date = r.date
LEFT JOIN name n
on o.origid = n.origid
and r.rawid = n.rawid
WHERE o.date >= '2020-05-02'
and o.date < '2020-05-10'
and not o.total = r.total
注意:一种方法是使用CTE,但在版本8之前,MySql不支持。然后我尝试使用临时表来简化操作,但是显然同一条temp_table无法在同一条语句中读取两次,给我一个错误代码:1137。无法重新打开表'o'(我使用的是MySql 5.7) >
SELECT n.name, o.date,
o.total as orig_total,
r.total as raw_total
FROM (
select o.origid, o.date, sum(o.total) as total
from origdata o
group by o.origid, o.date
) o
LEFT JOIN (
select r.rawid, r.date, sum(r.total) as total
from rawdata r
group by r.rawid, r.date
) r
on o.origid = r.rawid
and o.date = r.date
LEFT JOIN name n
on o.origid = n.origid
and r.rawid = n.rawid
WHERE r.rawid is null
and o.date >= '2020-05-02'
and o.date < '2020-05-10'
UNION
SELECT n.name, r.date,
o.total as orig_total,
r.total as raw_total
FROM (
select o.origid, o.date, sum(o.total) as total
from origdata o
group by o.origid, o.date
) o
RIGHT JOIN (
select r.rawid, r.date, sum(r.total) as total
from rawdata r
group by r.rawid, r.date
) r
on o.origid = r.rawid
and o.date = r.date
LEFT JOIN name n
on o.origid = n.origid
and r.rawid = n.rawid
WHERE o.origid is null
and r.date >= '2020-05-02'
and r.date < '2020-05-10'