2011-07-03 2 views
0

복잡한 서브 쿼리와 쿼리 imageid1가 imageid2보다 낮은 순위가SQL : 내 게임의 데이터베이스에 다음과 같은 테이블이있다

  1. 뿐만 아니라 옆에 : 사용자의 "USER_ID"값을 현재 로그인은, 나는 그런 것을 이미지 IDS (imageid1, imageid2)의 한 쌍을 반환하는 쿼리를 찾고 있어요 가장 높은 ra NK 미만 imageid2
  2. 매치업 테이블 (사용자 ID, imageid1, imageid2) 또는 rankedup 테이블이없는
  3. (사용자 ID, imageid2, imageid1) (사용자 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 

은 " not in "문은 모두 인덱싱되므로 빨리 실행해야합니다. 내가 가진 효율성 문제는이 질문은 더 이상 대답해서는 안 Pretty Complex SQL Query의 개정이다 global_rank 테이블


의 그룹화 및 선택이다.

+0

어떤 DB 엔진과 버전을 사용 하시겠습니까? 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 서버를 사용

,하지만 난 생각이이 트릭해야

0

: MySQL의에 대한 번역입니다 :

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 

내가 매치업의 PK와 있으리라 믿고있어 및 여기에는 해당 테이블의 모든 열이 포함됩니다. 이렇게하면 두 번째 두 개의 하위 쿼리가 PK 인덱스를 활용할 수 있습니다. 첫 번째 하위 쿼리의 속도를 높이려면 globalrank.rank에 정렬 된 인덱스가 필요할 것입니다.

+0

은 하위 쿼리의 higherImages.rank에 대한 참조처럼 보이며 전체 쿼리가 실패하게됩니다. – user257543

관련 문제