1

我花了几个小时寻找我的问题的答案,但没有令人满意的结果。

我想通过一个查询从玩家、村庄和联盟中选择所有内容 - 表格以及历史表格中的日期和人口。

必须使用以下规则过滤选择:

  1. 按日期选择最新信息。
  2. 仅当玩家当前拥有 <= 村庄数时才选择。
  3. 仅当玩家村庄的总人口目前 <= 时才选择

    1. 3.是那些导致我头疼的人。如何将这些添加到我的查询中?

这是我当前的查询:

SELECT players.name AS player, 
       players.uid as uid, 
       players.tid, 
       villages.name AS village, 
       villages.vid as vid, 
       villages.fid as fid, 
       alliances.name AS alliance, 
       alliances.aid as aid, 
       SQRT( POW( least(abs($xcoord - villages.x),
                        400-abs($xcoord - villages.x)), 2 ) + 
             POW( least(abs($ycoord - villages.y),
                        400-abs($ycoord - villages.y)), 2 ) ) AS distance
FROM histories
LEFT JOIN players ON players.uid = histories.uid
LEFT JOIN villages ON villages.vid = histories.vid
LEFT JOIN alliances ON alliances.aid = histories.aid
LEFT JOIN histories h2 
       ON ( histories.vid = h2.vid AND histories.idhistory < h2.idhistory )
WHERE h2.vid IS NULL
  AND histories.uid != $uid
  AND SQRT( POW(least(abs($xcoord - villages.x),
                      400-abs($xcoord - villages.x)), 2 ) + 
            POW(least(abs($ycoord - villages.y),
                      400-abs($ycoord - villages.y)), 2 ) ) < $rad
ORDER BY distance

注意:xcoord 和 ycoord 是从搜索表单中发布的。

示例输出:

PLayer| Village | Alliance | Distance

P1    | V1      | A1       | 1  
P2    | V4      | A2       | 2  
P1    | V2      | A1       | 3  
P1    | V3      | A1       | 4  
P2    | V5      | A2       | 5    

预先感谢您的帮助。:)

此查询可以找到拥有少于 2 个村庄的玩家。我只是不能把我原来的查询和这个放在一起。甚至可能吗?

SELECT
b.*, count(b.uid) as hasvillages
FROM 
histories b
WHERE 
b.vid IN (SELECT a.vid FROM villages a) 
GROUP BY 
b.uid
HAVING 
count(b.uid) < 2 

这是 SQLFIDDLE 的链接

这是我的数据库 EER 图的图片链接

4

1 回答 1

1

经过一周的尝试,我终于找到了答案。通过此查询,我可以使用以下搜索参数:

  1. 按日期查找最新行
  2. 通过限制玩家拥有的村庄数量来查找行。
  3. 通过限制玩家拥有的村庄的总人口来查找行。
  4. 通过计算距离查找行。
  5. 从选择中排除玩家或联盟。

这是查询

SELECT players.name AS player, players.uid as uid, players.tid, 
villages.name AS village, villages.vid as vid, villages.fid as fid, 
alliances.name AS alliance, alliances.aid as aid, 
SQRT( POW( least(abs(100 - villages.x),400-abs(100 - villages.x)), 2 ) + 
POW( least(abs(100 - villages.y),400-abs(100 - villages.y)), 2 ) ) AS distance
            FROM histories
            LEFT JOIN players ON players.uid = histories.uid
            LEFT JOIN villages ON villages.vid = histories.vid
            LEFT JOIN alliances ON alliances.aid = histories.aid
            WHERE histories.uid IN 
                     (SELECT b.uid FROM histories b
                      WHERE (b.vid IN (SELECT a.vid FROM villages a) and b.date
                      in (select max(date) from histories))
                      GROUP BY b.uid HAVING count(b.uid) < 4 AND
                      sum(b.population) < 2000)
       AND histories.uid != 1
       and histories.date in (select max(date) from histories)
       AND SQRT( POW( least(abs(100 - villages.x),400-abs(100 - villages.x)),2)+ 
       POW( least(abs(100 - villages.y),400-abs(100 - villages.y)), 2 ) ) < 200
       ORDER BY distance
于 2013-07-24T13:06:51.837 回答