为什么我的JOIN增加/可能在我的查询中乘以SUM?

时间:2013-01-09 09:40:50

标签: mysql sql join

我正在尝试加入三张桌子。

第一个表格是 transactions ,其中包含学生获得的“积分”的详细信息。这里的相关字段是Recipient_ID(学生接收积分)。

transactions table

第二个表格是 purchases ,其中包含学生购买的“奖励”详情。此处的相关字段为Student_IDReward_ID

purchases table

决赛桌 rewards 详细说明了所购买的奖励。此处的相关字段为Reward_IDCost_to_User(学生为每个用于订购GROUP_CONCAT功能的奖励支付的价格)和Title

rewards table


我正在使用的查询如下:

SELECT
  t.Recipient_ID AS `ID` ,
  SUM( t.Points ) AS `Points Earned`,
  SUBSTRING_INDEX( GROUP_CONCAT(DISTINCT r.Title ORDER BY r.Cost_to_User DESC SEPARATOR ', '),', ',3 ) AS `Rewards`
FROM  `transactions` t
LEFT JOIN `purchases` p 
   ON t.Recipient_ID = p.Student_ID
LEFT JOIN `rewards` r 
  ON p.Reward_ID = r.Reward_ID
WHERE t.`Recipient_ID` 
  IN ( 90128, 90163, 33888, 34240, 137674 )
GROUP BY  t.`Recipient_ID`

出于某种原因Points Earned输出非常错误。 如果我删除LEFT JOIN上的purchasesPoints Earned输出正确

SUM命令发送到疯狂的加入是什么意思?


编辑:请注意我需要LEFT JOIN命令,因为我希望显示所有学生,包括那些尚未购买的学生。有关详细信息,请参阅此post


提前致谢,

2 个答案:

答案 0 :(得分:2)

问题是您从连接的事务表中获取多个记录。您可以在事务表上使用子查询,它应该解决此问题:

SELECT t.`ID` ,
  t.`Points Earned`,
  SUBSTRING_INDEX( GROUP_CONCAT(DISTINCT r.Title ORDER BY r.Cost_to_User DESC SEPARATOR ', '),', ',3 ) AS `Rewards`
FROM
(
  select t.Recipient_ID AS `ID`, sum(t.Points) AS `Points Earned`
  from `transactions` t
  group by t.Recipient_ID
) t
LEFT JOIN `purchases` p 
   ON t.`ID` = p.Student_ID
LEFT JOIN `rewards` r 
  ON p.Reward_ID = r.Reward_ID
WHERE t.`ID` 
  IN ( 90128, 90163, 33888, 34240, 137674 )
GROUP BY  t.`ID`

请参阅SQL Fiddle with Demo

points的奇怪总数来自表的连接。由于您只在Recipient_ID = Student_ID上加入表,如果两个表中都有记录,您将得到一个笛卡尔数的结果。因此,如果transactions表中的学生有3条记录,purchases表中有3条记录,则结果将显示该学生的9条记录,这些记录会改变总数。

请参阅SQL Fiddle with Demo

答案 1 :(得分:1)

尝试使用INNER JOIN

SELECT
    t.Recipient_ID AS `ID` ,
    SUM( t.Points ) AS `Points Earned`,
    SUBSTRING_INDEX( GROUP_CONCAT(DISTINCT r.Title ORDER BY r.Cost_to_User DESC SEPARATOR ', '),', ',3 ) AS `Rewards`
FROM  `transactions` t
LEFT JOIN `purchases` p 
ON t.Recipient_ID = p.Student_ID
INNER JOIN `rewards` r 
ON p.Reward_ID = r.Reward_ID
WHERE t.`Recipient_ID` 
IN ( 90128, 90163, 33888, 34240, 137674 )
GROUP BY  t.`Recipient_ID`