SQL根据两个表使用另一个表作为MySQL DB的键来查找不同的时间

问题描述 投票:0回答:2

我正在学习在Python项目中使用MySQL查询。

我正在使用Python中的MySQLDB模块将数据上传到MySQL数据库,现在,我想比较数据并打印出差异。

我有3个表(仅包括相关列):

名称

  • rawid
  • 原始
  • 名称

rawdata

  • rawid
  • 日期
  • 总计

origdata

  • 原始
  • 日期
  • 总计

我需要根据日期比较同一人的'总数'。

例如从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

运行时,rawdatatotal未显示正确的值; origdatatotalrawdata的值相同。

非常感谢您的帮助!

mysql python-3.x mysql-python
2个回答
0
投票

如果您的“日期”列为DATETIME类型,则可以使用CAST:

total

0
投票

由于您可能在同一表中具有相同日期的记录,因此首先需要将它们汇总(分组依据-总和)

 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'
    
© www.soinside.com 2019 - 2024. All rights reserved.