Bir alt sorgu aracılığıyla birden çok sütun seçme


18

Aşağıdaki sorguda alt sorgudan 2 sütun SEÇMEK çalışıyorum, ancak bunu yapamıyorum. Takma ad tablosu oluşturmaya çalıştım, ancak yine de alamadım.

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

Temelde, almaya çalışıyorum lastComDate& lastPosterIDbelirli evcil hayvan için yapılan yorumlar son biridir satırda - Aynı satırdan. Lütfen bunları nasıl verimli bir şekilde elde edebileceğimi önerin.

Yukarıdaki sorgu işe yarıyor, ancak aynı satır iki kez getirildiği için aşırı görünüyor. Ayrıca, ORDER BYyan tümce toplama işlevinden önemli ölçüde daha yavaştır - sorgu oluşturma sırasında bulduğum gibi. Bu nedenle, sınıflandırmayı önleyen bir çözüm takdir edilecektir.


1
Yorumlar tablosunda bir dizin (petid, id) varsa, tarafından sıralaması yavaş olmayacaktı, ancak ilk önce ilk şey: Görünüşe göre sorgunuz 'ABC' userid'in yorum yaptığı tüm evcil hayvanları istiyor cihaz kimliği 'ABC' olmadığında (hangi tablo cihazID'sinin bir sütun, muhtemelen evcil hayvanlar ve muhtemelen yorumlar olduğu bir sütun olduğu belirsizdir) ve son yorumcunun kim olduğu ve son yorum tarihi olan son iki ay içinde bunları. Bu doğru mu?
Michael - sqlbot 13:13

@ Michael-sqlbot - Evet, tam olarak toplamaya çalışıyorum. deviceIDDan petsmasanın - bana 'ABC' kendisi tarafından gönderilen hayvan alamadım anlamına gelir.
BufferStack

Yanıtlar:


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

Performans yolun herhangi bir yerinde etkilendiyse, alt sorgunuzu geçici tabloya da çekebilirsiniz.


Ben ... Daha önce de bu döner bu denemişti NULLikisi için lastComDateve lastPosterIdkayıtları herkes için.
BufferStack

Kullanılabilir örnek veriniz var mı?
Valkyrie

Örnek verileri nasıl sağlayabilirim?
BufferStack

Bu yayındaki ipuçlarını deneyin: meta.stackexchange.com/questions/156729/…
Valkyrie

1
Bu iyi, ancak SQLFiddle daha iyidir;). Burada bir örneğe bakın . Biçimlendirmeniz gereken bazı tabloları değil, yalnızca kod ve tohum verilerini görmek daha iyi.
Marian

6

Tablolarınızın şöyle göründüğü göz önüne alındığında:

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

Bu sorgu hile yapmalıdır:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.