2011-07-03 161 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