it-swarm-eu.dev

VÝBĚR více sloupců prostřednictvím poddotazu

V následujícím dotazu se pokouším VYBRAT 2 sloupce z poddotazu, ale nedokážu to. Pokusil se vytvořit aliasovou tabulku, ale stále je nemohl získat.

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);

V zásadě se snažím získat lastComDate & lastPosterID ze stejného řádku - řádku, který je poslední v komentářích pro konkrétní mazlíčky. Navrhněte, jak je mohu efektivně získat.

Výše uvedený dotaz funguje, ale zdá se, že je nadměrný, protože stejný řádek je vyvolán dvakrát. Navíc ORDER BY klauzule je výrazně pomalejší než agregovaná funkce - jak jsem zjistil při profilování dotazu. Bylo by tedy oceněno řešení, které by zabránilo třídění.

18
BufferStack
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)
;

Můžete také vytáhnout svůj poddotaz do dočasné tabulky, pokud se výkon projeví někde po silnici.

13
Valkyrie

Vzhledem k tomu, že vaše tabulky vypadají takto:

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

Tento dotaz by měl udělat trik:

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
6
druzin