MySQL中的表JOIN和聚合问题

时间:2008-12-12 21:41:48

标签: sql mysql join

我有三张桌子。此查询将记下正确的答案(btv.id_user的x行与适当的btv.cas和race.id_zavod

SELECT `btv.id_user`, `btv.id_zavod`,`btv.cas`
FROM `btv`
JOIN `btu` ON `btv.id_user` = `btu.id_user`
JOIN `race` ON 'btv.id_zavod' = `race.id_zavod`
WHERE `race.type` = '8' AND `btv.id_user` = '607'

结果:

| 607 |  512 | 03:15:58 |  
| 607 |  730 | 03:01:18 |  
| 607 |  164 | 03:07:26 |  
| 607 |  767 | 02:58:31 |  
| 607 | 1147 | 03:06:47 |  
| 607 | 1149 | 03:09:41 |  
| 607 | 1178 | 03:24:20 | 

但是当我尝试通过id_user将它聚合到一行时,它返回正确的min btv.cas但错误的连接错误的race.id_zavod

SELECT `btv.id_user`, `btv.id_zavod`, MIN( `btv.cas` )
FROM `btv`
JOIN `btu` ON `btv.id_user` = `btu.id_user`
JOIN `race` ON 'btv.id_zavod' = `race.id_zavod`
WHERE `race.type` = '8' AND `btv.id_user` = '607'
GROUP BY `btv.id_user`

结果:

| 607 | 512 | 02:58:31 |

5 个答案:

答案 0 :(得分:1)

您撰写的查询:

SELECT `btv.id_user`, `btv.id_zavod`, MIN( `btv.cas` )
FROM `btv`
JOIN `btu` ON `btv.id_user` = `btu.id_user`
JOIN `race` ON 'btv.id_zavod' = `race.id_zavod`
WHERE `race.type` = '8' AND `btv.id_user` = '607'
GROUP BY `btv.id_user`

不会运行。你需要一个id_zavod组或者其他东西。你能告诉我们你正在运行什么查询吗?你期望得到什么结果?

答案 1 :(得分:0)

使用GROUP BY时,select-list中的列必须满足以下条件之一:

  • 列在GROUP BY中命名(例如,在您的示例中为btv.id_user
  • 列位于聚合函数内(例如MIN( btv.cas )
  • 列是您在GROUP BY中命名的列的功能依赖

这是您的查询中的错误:btv.id_zavodbtv.id_user的每个值都包含许多值。这不满足功能依赖性。对于id_zavod的每个值,id_user中必须只有一个值才能成为函数依赖。

在某些数据库品牌中,此查询实际上会给您一个错误。 MySQL更灵活,相信您只能命名select-list中的列,这些列是您在GROUP BY中命名的列的功能依赖性。

这是一个返回所需内容的查询,btv.casid_user的MIN值,相应的值为btv.id_zavod

SELECT b1.id_user, b1.id_zavod, b1.cas
FROM btv AS b1
 JOIN btu ON (b1.id_user = btu.id_user)
 JOIN race ON (b1.id_zavod = race.id_zavod)
 LEFT OUTER JOIN btv AS b2 ON (b1.id_user = bt2.id_user AND 
   (b1.cas > b2.cas OR (b1.cas = b2.cas AND b1.primarykey > b2.primarykey))
WHERE race.type = '8' AND b1.id_user = '607'
 AND b2.id_user IS NULL;

换句话说,您需要像以前一样进行加入,然后再将其加入btv,以查看是否有另一行具有相同的id_user值且cas中的值更小1}}。使用OUTER JOIN,因为您正在寻找没有匹配的情况。您可以使用b2.id_user IS NULL对其进行测试,因为OUTER JOIN会在没有匹配项时使所有列为NULL。

请注意,可能存在关联,因此我们使用主键作为决胜局添加额外的术语。

您不需要在此查询中使用GROUP BY。这是隐含的,因为只有一行满足OUTER JOIN条件。

答案 2 :(得分:0)

我不确定你想要完成什么,但你是否正在寻找GROUP_CONCAT function?

答案 3 :(得分:0)

您是否只是尝试获取最低的btv.cas值及其他相应的列?如果是这样,您可以通过btv.cas订购并限制为1次点击:

SELECT `btv.id_user`, `btv.id_zavod`,`btv.cas`
FROM `btv`
JOIN `btu` ON `btv.id_user` = `btu.id_user`
JOIN `race` ON 'btv.id_zavod' = `race.id_zavod`
WHERE `race.type` = '8' AND `btv.id_user` = '607'
ORDER BY `btv.cas` LIMIT 1

答案 4 :(得分:0)

尝试:

SELECT `btv.id_user`, `btv.id_zavod`, MIN( `btv.cas` )
FROM `btv`
Inner JOIN `btu` ON `btv.id_user` = `btu.id_user`
Inner JOIN `race` ON 'btv.id_zavod' = `race.id_zavod`
WHERE `btv.id_user` = '607'
GROUP BY `btv.id_user` having `race.type` = '8'