当我运行一个简单的SQL语句时:
SELECT SUM(perfect) FROM damagelog WHERE driverid = 3
我得到的2的输出,这是正确
当我执行更复杂的SQL语句时:
SELECT
dr.id,
dr.drivername,
ra.driverid,
AVG(ra.rating),
SUM(dam.perfect)
FROM
drivers AS dr
JOIN driverratings AS ra ON ra.driverid = dr.id
JOIN damagelog as dam ON dam.driverid = dr.id
WHERE dr.id =3
我的值为12。我的代码在做什么错?
答案 0 :(得分:0)
这通常发生在不包括group by子句中的所有字段列表时,请尝试
SELECT
dr.id,
dr.drivername,
ra.driverid,
AVG(ra.rating),
SUM(dam.perfect)
FROM
drivers AS dr
JOIN driverratings AS ra ON ra.driverid = dr.id
JOIN damagelog as dam ON dam.driverid = dr.id
WHERE dr.id =3
GROUP BY
dr.id,
dr.drivername,
ra.driverid
我希望能奏效,因为您在汇总函数时使用了棘手的东西,因此我无法预测其行为,但是您已经有了大致的想法
答案 1 :(得分:0)
欢迎使用S / O。您的问题很普遍,但是由于您是新手,所以不知道原因,也不知道术语。您遇到的是笛卡尔结果(或乘积)。基本上,这意味着当连接到多个表时,您的原始记录可以与其他表中的多个记录匹配,从而使答案answer肿。
您有驱动程序A,B和C。现在,例如,驱动程序“ A”具有3个损坏日志,您的计数是3。但是现在,您还在查询驱动程序等级。驾驶员“ A”有20人。因此,您的查询现在将驱动程序A应用于每个驱动程序日志的每个等级。所以现在1 * 3 * 20 = 60计数。
要解决此问题,您需要对第二张表和第三张表进行预汇总,以便每个驱动程序仅获得一个答案,以防止重复。这就是我想找的。 p>
SELECT
dr.id,
dr.drivername,
ra.driverAvgRating,
dam.PerfectCnt
FROM
drivers dr
LEFT JOIN
( Select
driverid,
avg( rating ) driverAvgRating
from
driverratings
group by
driverid ) ra
ON dr.id = ra.driverid
LEFT JOIN
( select
driverid,
sum( perfect ) as PerfectCnt
from
damagelog
group by
driverid ) dam
ON dr.id = dam.driverid
现在,上述位置将返回所有驱动程序及其各自的等级。请注意,子查询是对原始驱动程序表的联接。但是在这里,我有LEFT-JOINS。意思是,在此查询中,我希望所有驾驶员均获得评级或损坏日志。您的驱动程序可能只有一个,而另一个却没有。您是否还不想看到驱动程序是否丢失了其他表中的内容?如果您将查询作为常规(INNER隐含的)JOIN进行查询,那么这意味着必须在两个结果集中都存在一条记录才能返回。
在字段列表中,我具有子查询的别名,但该子查询中的列名称也代表各个等级或计数。现在,该列表可能会根据所述的LEFT-JOIN在任一侧显示NULL值。
为防止NULL,有一个coalesce()函数,其编写方式为
SELECT
dr.id,
dr.drivername,
coalesce( ra.driverAvgRating, 0 ) FinalAvgRating,
coalesce( dam.PerfectCnt, 0 ) FinalPerfectCnt
FROM
coalcece()的状态给我第一个值是什么,但是如果它为NULL,则给我第二个。这样一来,您的结果可以在返回时具有预期的正确数据类型,并且您不必在任何需要的地方都对空值进行测试以最终输出。
现在,我知道您的原始查询是针对特定驱动程序的,只要在查询返回的列中仅返回1个值,则可以简化选择查询的结果,简化查询。
SELECT
dr.id,
dr.drivername,
( Select avg( rating )
from driverratings
where driverid = 3) FinalAvgRating,
( select sum( perfect )
from damagelog
where driverid = 3) FinalPerfectCnt
FROM
drivers dr
where
id = 3
请注意,COLUMNS只是一个选择查询,仅获取该驱动程序的平均值,并且仅为该驱动程序。
希望这对您的问题和将来的任务提供了很好的说明