2011-07-03 121 views
0

我在游戏的数据库下表:在globalRank表SQL:查询复杂的子查询

rankedUp (image_id, user_id, created_at) 
globalRank (image_id, rank) 
matchups (user_id, image_id1, image_id2) 

所有image_ids被分配一个等级是从0浮子1

假设我有登录用户的“USER_ID”值目前,我正在寻找一个查询,将返回一对图像的IDS(imageid1,imageid2)使得:

  1. imageid1具有更低的等级比imageid2,但也是未来最高的ra NK小于imageid2
  2. 对决表不具有(用户ID,imageid1,imageid2)或(用户ID,imageid2,imageid1)
  3. rankedup表不具有(用户ID,imageid1),或者如果是这样,createdat柱比X小时之前

我到目前为止的要求1,这是:

SELECT lowerImages.image_id AS lower_image, higherImages.image_id AS higher_image 
FROM global_rank AS lowerImages, global_rank AS higherImages 
WHERE lowerImages.rank < higherImages.rank 
AND lowerImages.image_id = ( 
    SELECT image_id 
    FROM (
     SELECT image_id 
     FROM global_rank 
     WHERE rank < higherImages.rank 
     ORDER BY rank DESC 
     LIMIT 1 , 1 
     ) AS tmp 
    ) 

,但它不工作,因为我不能在子查询中引用higherImages.rank。

有谁知道我怎么能满足所有这些要求在一个查询?

感谢您的帮助

编辑:

我现在有这个疑问,但我不知道的效率,我需要测试它的正确性:

SELECT lowerImages.image_id AS lower_image, 
     max(higherImages.image_id) AS higher_image 
FROM global_rank AS lowerImages, global_rank AS higherImages 
WHERE lowerImages.rank < higherImages.rank 

AND 1 NOT IN (select 1 from ranked_up where 
    lowerImages.image_id = ranked_up.image_id 
    AND ranked_up.user_id = $user_id 
    AND ranked_up.created_at > DATE_SUB(NOW(), INTERVAL 1 DAY)) 

AND 1 NOT IN (
    SELECT 1 from matchups where user_id = $userId 
      AND lower_image_id = lowerImages.image_id 
      AND higher_image_id = higherImages.image_id 
      UNION 
      SELECT 1 from matchups where user_id = $user_id 
      AND lower_image_id = higherImages.image_id 
      AND higher_image_id = lowerImages.image_id 
) 
GROUP BY 1 

的“不在“我使用的声明都是索引,所以他们应该快速运行。效率问题我已经是该组并选择global_rank表


的这个问题的Pretty Complex SQL Query修订,不应再回答。

+0

需要什么数据库引擎和版本? MySQL的? – gbn

+0

对不起,这是MySQL – user257543

+0

我很高兴看到你删除了“随机性”的要求;这绝对使它更容易一些。 –

回答

0
select 
(
select image_id, rank from 
rankedup inner join globalRank 
on rankedup.image_id = globalRank .image_id 
where user_id = XXX 
limit 1, 1 
) as highest, 
(
select image_id, rank from 
rankedup inner join globalRank 
on rankedup.image_id = globalRank .image_id 
where user_id = XXX 
limit 2, 1 
) as secondhighest 

我通常使用SQL Server中,但是这个我觉得是翻译为MySQL :)

0

这应该做的伎俩:

SELECT lowerImages.*, higherImages.* 
FROM globalrank AS lowerImages, globalrank AS higherImages 
WHERE lowerImages.rank < higherImages.rank 
AND lowerImages.image_id = ( 
    SELECT image_id 
    FROM (
     SELECT image_id 
     FROM globalrank 
     WHERE rank < higherImages.rank 
     ORDER BY rank DESC 
     LIMIT 1,1 
     ) AS tmp 
    ) 
AND NOT EXISTS (
    SELECT * FROM matchups 
    WHERE user_id = $user_id 
    AND ((image_id1 = lowerImages.image_id AND image_id2 = higherImages.image_id) 
     OR (image_id2 = lowerImages.image_id AND image_id1 = higherImages.image_id)) 
) 
AND higherImages.image_id NOT IN (
    SELECT image_id FROM rankedup 
    WHERE created_at < DATE_ADD(NOW(), INTERVAL 1 DAY) 
    AND USER_ID <> $user_id 
) 
ORDER BY higherImages.rank 

我假设对决的PKS和排名包括这些表中的所有列。这将允许第二个2个子查询使用PK索引。您可能需要globalrank.rank上的有序索引来加速第一个子查询。

+0

看起来像子查询中对higherImages.rank的引用会导致整个查询失败 – user257543