하위 쿼리를 통해 여러 열 선택


18

다음 쿼리의 하위 쿼리에서 2 열을 선택하려고하지만 그렇게 할 수 없습니다. 별칭 테이블을 만들려고했지만 여전히 가져올 수 없습니다.

SELECT
  DISTINCT petid,
  userid,
  (SELECT MAX(comDate) FROM comments WHERE petid=pet.id) AS lastComDate,
  (SELECT userid FROM comments WHERE petid=pet.id ORDER BY id DESC LIMIT 1) AS lastPosterID
FROM 
  pet LEFT JOIN comments ON pet.id = comments.petid
WHERE 
  userid='ABC'      AND 
  deviceID!='ABC'   AND 
  comDate>=DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 2 MONTH);

기본적으로, 나는 같은 행에서 lastComDate& 를 얻으려고합니다 lastPosterID-특정 애완 동물에 대한 의견에서 최신 행입니다. 어떻게 효율적으로 구할 수 있는지 제안하십시오.

위의 쿼리는 작동하지만 동일한 행이 두 번 페치되면 과도한 것으로 보입니다. 또한 ORDER BY쿼리를 프로파일 링하는 동안 발견 한 것처럼 이 절은 집계 함수보다 훨씬 느립니다. 따라서 정렬을 피하는 솔루션이 좋습니다.


1
코멘트 테이블에 index (petid, id)가 있다면, 순서는 느리지 않을 것입니다. 그러나 가장 먼저해야 할 일은 : 쿼리가 사용자 ID 'ABC'가 코멘트 한 모든 애완 동물을 요구하는 것처럼 보입니다. 마지막 2 개월 이내에 deviceID가 'ABC'가 아닌 경우 (어떤 테이블 deviceID가 열 (애완 동물 및 주석 일 수도 있음)인지, 마지막 주석자가 누구인지, 마지막 주석 날짜인지는 확실하지 않습니다). 맞습니까?
— Michael-sqlbot

@ Michael-sqlbot-그래, 내가 모 으려고하는 것입니다. 이것은 테이블 deviceID에서 가져온 것입니다. pets즉, 'ABC'자신이 제출 한 애완 동물을 보내지 마십시오.
— BufferStack

답변:


13
SELECT DISTINCT petid, userid, lastComDate, lastPosterId
FROM 
    pet 
    LEFT JOIN comments ON pet.id = comments.petid 
    LEFT JOIN (
        SELECT MAX(comDate), userid, petid FROM comments GROUP BY userid
    ) a ON a.petid = pet.id
WHERE 
    userid='ABC' 
    AND deviceID!='ABC' 
    AND comDate>=DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 2 MONTH)
;

성능이 길 어딘가에 영향을 미치는 경우 하위 쿼리를 임시 테이블로 가져올 수도 있습니다.


나는 ... 이전뿐만 아니라이 수익률이 시도했던 NULL모두 lastComDate및 lastPosterId기록 모두를.
— BufferStack

사용 가능한 샘플 데이터가 있습니까?
— Valkyrie

샘플 데이터는 어떻게 제공합니까?
— BufferStack

이 게시물의 힌트를보십시오 : meta.stackexchange.com/questions/156729/…
— Valkyrie

1
좋지만 SQLFiddle이 더 좋습니다.). 여기 예를 참조 하십시오 . 포맷해야 할 테이블이 아니라 코드 및 시드 데이터를 보는 것이 더 좋습니다.
— Marian

6

테이블이 다음과 같다고 가정하면 :

create table pet (id int, userid int, deviceid int);
create table comments (id int, petid int, comdate date);

이 쿼리는 트릭을 수행해야합니다.

SELECT 
        p.id, 
        p.userid,
        (SELECT MAX(comDate)
         FROM comments
         WHERE petid = p.id
         AND comDate >= DATE_SUB(
                 CURRENT_TIMESTAMP, INTERVAL 2 MONTH)
               ) AS lastComDate,
        (SELECT userid
         FROM comments
         WHERE petid = p.id
         AND comDate >= DATE_SUB(
              CURRENT_TIMESTAMP, INTERVAL 2 MONTH
         ) ORDER BY id DESC LIMIT 1) AS lastPosterID
    FROM 
        pet p

    WHERE 
        p.userid=1
        AND p.deviceID!=1
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.