본문 바로가기
MySql

MySQL 상위 쿼리의 필드를 참조하는 MySQL 하위 쿼리

by 베이스 공부 2020. 10. 10.
반응형

평가 데이터에 대해 일부 필터링을 수행하는 쿼리를 작성 중입니다.

온라인 평가 도구의 데이터를 저장하는 다음과 같은 ratings 라는 간단한 테이블이 있다고 가정합니다.

최근 10 개의 평점에서 낮은 값의 빈도가 높은 페이지를 추출하고이 쿼리를 지난 주에 최소 20 개의 평점을 생성 한 페이지로 제한해야합니다. 이것은 내가 생각 해낸 엄청나게 긴 쿼리입니다.

SELECT a1.page_title, COUNT(*) AS rvol, AVG(a1.rating) AS theavg, 
(
     SELECT COUNT(*) FROM
     (
         SELECT * FROM ratings a2 WHERE a2.page_title = a1.page_title 
         AND DATE(timestamp) <= '2011-04-24' ORDER BY timestamp DESC LIMIT 10
     ) 
     AS latest WHERE rating >=1 AND rating <=2 ORDER BY timestamp DESC
)
AS lowest FROM ratings a1
WHERE DATE(a1.timestamp) <= "2011-04-24" AND DATE(a1.timestamp) >= "2011-04-17" 
GROUP BY a1.page_title HAVING COUNT(*) > 20

최상위 쿼리는 2011-04-24에 종료되는 주에 20 개 이상의 평점을 가진 페이지를 찾습니다. 하위 쿼리는 각 기사의 최근 10 개 평점에서 [1,2] 사이의 값을 가진 평점 수를 검색해야합니다. 최상위 쿼리입니다.

MySQL은 하위 쿼리의 WHERE 절에있는 a1.page_title이 알 수없는 열이라고 불평합니다. 이것은 a1이 두 번째 수준 쿼리에서 별칭으로 정의되지 않고 최상위 쿼리에서만 정의 되었기 때문이라고 생각하지만 단서가 없습니다. 이 문제를 해결하는 방법.

(편집 됨)

나는 절대적으로 잘 작동하는 다른 쿼리를 참조하는 교차 수준에 대한 위의 용의자에 대한 설명으로 추가하고 있습니다. 여기서 a1은 하위 쿼리에 정의되어 있지 않지만 직계 부모에 있습니다.

SELECT a1.page_title, COUNT(*) AS rvol, AVG(a1.rating) AS theavg, 
(
    SELECT COUNT(*) FROM ratings a2 WHERE DATE(timestamp) <= '2011-04-24'
    AND DATE(timestamp) >= '2011-04-17' AND rating >=1 
    AND rating <=2 AND a2.page_title = a1.page_title
) AS lowest FROM ratings a1 
WHERE DATE(a1.timestamp) <= '2011-04-17' AND DATE(a1.aa_timestamp) >= '2011-04-11' 
GROUP BY a1.page_title HAVING COUNT(*) > 20

 

해결 방법

 

두 개를 라인 뷰로 결합하면 일이 더 쉬워 질 수 있다고 생각합니다.

SELECT * 
FROM   (SELECT COUNT(*), 
               a2.page_title 
        FROM   ratings a2 
        WHERE  DATE(timestamp) <= '2011-04-24' 
               AND DATE(timestamp) >= '2011-04-17' 
               AND rating >= 1 
               AND rating <= 2 

        GROUP  BY a2.page_title) current 
       JOIN 
        (SELECT a1.page_title, 
                    COUNT(*)       AS rvol, 
                    AVG(a1.rating) AS theavg 
             FROM   ratings a1 
             WHERE  DATE(a1.timestamp) <= '2011-04-17' 
                    AND DATE(a1.a_timestamp) >= '2011-04-11' 
             GROUP  BY a1.page_title 
             HAVING COUNT(*) > 20) morethan20 
         ON current .page_title = morethan20.page_title 

 

참조 페이지 https://stackoverflow.com/questions/5781349

 

 

반응형

댓글