1. 问题所示
多表联动查询的语句大致如下:
SELECT
tbsystemdata.strCraneName,
tbfaultdic.strFaultName,
tbfaultdata.strHappenTime,
tbfaultdata.strResetTime,
tbfaultdata.strConfirmTime,
tbfaultdic.lngItemNo,
tbfaultdic.strFaultNo,
tbfaultdic.strDevice
FROM
tbfaultdic
JOIN
tbfaultdata ON tbfaultdic.lngDataNo = tbfaultdata.lngDataNo
JOIN
tbsystemdata ON tbfaultdata.lngCraneNo = tbsystemdata.lngCraneNo
WHERE
tbsystemdata.strCraneName = 'RMGC54'
AND tbfaultdata.strHappenTime BETWEEN '2024-04-01' AND '2024-04-02'
GROUP BY
tbfaultdata.strHappenTime
ORDER BY
tbfaultdata.strHappenTime DESC;
结果查询出来的语句个别字段明显不符合要求
2. 原理分析
一般多表联动,四大常错的位置出处(前提是确保数据没有异常,满足自身的逻辑):
-
查询逻辑错误:检查查询语句中的逻辑是否正确。确保所有表都正确地连接在一起,并且每个条件都适用于查询目标
-
条件不匹配:检查查询条件是否正确。特别是在多个表之间进行连接时,确保条件正确地指向相关的字段,并且能够准确地过滤出符合条件的结果
-
数据重复:查询结果中存在重复的数据,可能是由于查询条件不够严格,或者在 GROUP BY 子句中使用了不正确的字段
-
表关联错误:检查表之间的关联逻辑是否正确。确保每个表通过正确的字段进行关联,并且每个关联条件都是必要的
对应的排查解决方案如下:
-
优化条件:对查询条件进行优化,确保它们足够严格以过滤出正确的结果。如果条件太宽松,可能会导致结果集中包含不符合预期的数据
-
使用别名:查询涉及多个表,使用表别名来提高查询可读性和维护性。确保别名使用正确,不会引起混淆
-
测试查询:在进行更改之前,先在数据库中进行测试查询。检查查询结果是否与预期一致,并逐步调整查询逻辑以达到预期结果
-
查看数据库约束:检查数据库中的约束条件,例如外键约束和唯一约束。这些约束可能会影响查询结果,因此需要确保它们与查询逻辑一致
-
查看数据库索引:确保数据库中的索引设置正确。索引可以提高查询性能,并确保查询结果的准确性
3. 解决方案
SELECT
tbsystemdata.strCraneName,
tbfaultdic.strFaultName,
tbfaultdata.strHappenTime,
tbfaultdata.strResetTime,
tbfaultdata.strConfirmTime,
tbfaultdic.lngItemNo,
tbfaultdic.strFaultNo,
tbfaultdic.strDevice
FROM
tbfaultdic
JOIN
tbfaultdata ON tbfaultdic.lngDataNo = tbfaultdata.lngDataNo
JOIN
tbsystemdata ON tbfaultdata.lngCraneNo = tbsystemdata.lngCraneNo
AND tbfaultdic.lngItemNo = tbsystemdata.lngItemNo -- 添加此条件
WHERE
tbsystemdata.strCraneName = 'RMGC54'
AND tbfaultdata.strHappenTime BETWEEN '2024-04-01' AND '2024-04-02'
GROUP BY
tbfaultdata.strHappenTime
ORDER BY
tbfaultdata.strHappenTime DESC;
额外条件的加入可能是为了进一步限制查询结果,以确保结果集中的数据符合更严格的要求。在添加了这个条件之后,查询结果可能会更加准确
最终引入到Python代码中:
def select_fault_data(before, after, en, timer):
"""获取故障信息"""
return db.session.query(
FaultDict.strFaultName, FaultData.strHappenTime, FaultData.strResetTime, FaultData.strConfirmTime,
FaultDict.strFaultNo, FaultDict.strDevice
).join(SystemData, FaultData.lngCraneNo == SystemData.lngCraneNo).join(
FaultDict, FaultData.lngDataNo == FaultDict.lngDataNo
).filter(
and_(
timer.between(before, after),
SystemData.strCraneName == en,
FaultDict.lngItemNo == SystemData.lngItemNo
)
).group_by(
FaultData.strHappenTime
).order_by(
FaultData.strHappenTime.desc()
).all()
推荐阅读:详细分析Python中的SQLAlchemy库(附Demo)