高级MySQL LEFT JOIN查询问题

时间:2014-01-19 03:10:03

标签: mysql sql

我在下面有这个查询。 “stats”表中有多行用户名。每个服务器1个。它不断重复杀戮和死亡值基于stats表中带有用户名的行数。例如,如果用户名测试在pvp表中有2次杀戮和1次死亡,并且stats表中有2行,其中用户名为一个用于server1,一个用于server2,那么在运行此查询时,它显示4次杀戮和2次死亡。我不知道为什么。

这是一个SQLFiddle:http://sqlfiddle.com/#!2/c7049/1

SELECT st.*, 
COALESCE(SUM(pvp.killer = st.username), 0) AS kills,
COALESCE(SUM(pvp.username = st.username), 0) as deaths,
COALESCE(ROUND(SUM(pvp.killer = st.username) / SUM(pvp.username = st.username), 2), 0.00) 
as kd FROM stats AS st 
LEFT JOIN pvp ON pvp.username = st.username OR pvp.killer = st.username 
WHERE st.username="Username"

2 个答案:

答案 0 :(得分:1)

我认为您正在混淆服务器详细信息,因此您的查询中可能需要AND(st.server = pvp.server)(在JOIN条件下)

SELECT st.id,st.username,st.balance,st.xplevel,st.server,
COALESCE(SUM(pvp.killer = st.username), 0) AS kills,
COALESCE(SUM(pvp.username = st.username), 0) as deaths,
COALESCE(ROUND(SUM(pvp.killer = st.username) / SUM(pvp.username = st.username), 2), 0.00) 
as kd
 FROM stats AS st 
LEFT JOIN pvp ON (pvp.username = st.username OR pvp.killer = st.username)
              AND(st.server = pvp.server)
WHERE st.username="tacoboboy32"
GROUP BY st.id,st.username,st.balance,st.xplevel,st.server

此外,如果你不使用GROUP BY,你只会获得一行,所以只需按st中的每个字段进行分组。它会为每个服务器提供不同的信息。

sqlFiddle

答案 1 :(得分:0)

这是因为LEFT JOIN返回查询左半部分的所有行,因此您将获得每个统计信息行的结果。

试试这个:

SELECT stats.*, 
COALESCE(SUM(pvp.killer = stats.username), 0) AS kills,
COALESCE(SUM(pvp.username = stats.username), 0) as deaths,
COALESCE(ROUND(SUM(pvp.killer = stats.username) / SUM(pvp.username = stats.username), 2), 0.00) 
as kd 
FROM pvp  
LEFT JOIN stats ON pvp.username = stats.username OR pvp.killer = stats.username 
WHERE stats.username="Username"

这实际上是一个不错的指南http://www.w3schools.com/sql/sql_join_left.asp