将两个复杂的连接查询组合到一个

时间:2014-04-23 15:40:00

标签: mysql sql

首先查询:

SELECT a.* 
FROM `records` a 
INNER JOIN (SELECT map, MIN(time) as time 
            FROM `records` GROUP BY map) as b ON a.time=b.time ORDER BY a.map

第二次查询:

SELECT a.* 
FROM (SELECT * 
      FROM `players` 
      WHERE cheat=0) c JOIN `records` a ON a.authid = c.authid

第一个查询会查找具有最低map值的每个唯一time的行。

第二个查询查找records表中{em>未的所有行,players表中的cheat表设置为{ {1}}。

我尝试将这两个查询结合起来,找到每个唯一地图的最低非作弊时间如下:

1

很明显发生了什么,但我不知道如何纠正它:而不是在没有启用SELECT a.* FROM `records` a JOIN (SELECT * FROM `players` WHERE cheat=0) c ON a.authid=c.authid INNER JOIN (SELECT map, MIN(time) as time FROM `records` GROUP BY map) as b ON a.time=b.time ORDER BY a.map 标志的情况下检索最低的time最低cheat 是合法时间,并忽略该time的记录。

关于如何正确组合这两个查询的任何想法?

编辑:


map结构:

records

map [varchar(32)] | authid [varchar(35)] | name [varchar(32)] | time [decimal(13,6)] | date [datetime] | weapon [varchar(32)] 结构:

players

2 个答案:

答案 0 :(得分:1)

我认为您在第一个查询中的加入缺少标准,应该是

ON a.time=b.time
AND a.Map=b.map

虽然这不是问题所在,但问题是你要为每张地图选择第一条记录,然后只保留那些由非作弊完成的记录。你需要得到每个地图的第一个记录,由非作弊者竞争。这是一个微妙的区别,你只需要将你的联接移动到玩家表中进入子查询:

SELECT  a.*
FROM    records AS a
        INNER JOIN
        (   SELECT  r.Map, MIN(r.time) AS Time
            FROM    records AS r
                    INNER JOIN players AS p
                        ON p.authid = r.authid
            WHERE   p.Cheat = 0
            GROUP BY r.map
        ) AS MinR
            ON MinR.map = a.map
            AND MinR.time = a.time
ORDER BY a.map;

答案 1 :(得分:0)

以下查询将为您提供所需的结果:

SELECT a.* 
FROM `records` a 
INNER JOIN 
    (SELECT map, MIN(time) as time
     FROM `records` r
     INNER JOIN `players` p
     ON a.authid = c.authid
     WHERE p.cheat = 0
     GROUP BY map) as b 
ON a.map = b.map AND a.time=b.time 
ORDER BY a.map;

首先,仅为非作弊玩家获得最短时间。然后获取这些时间的记录。

此外,我在a.map = b.map中添加了JOIN以确保相同的地图已加入(如果有多个地图具有相同的记录时间)。