ВИБІР декількох стовпців за допомогою підпиту


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
Якби у вас в таблиці коментарів був індекс (petid, id), порядок замовлення, швидше за все, не буде повільним, але спочатку спочатку: начебто ваш запит запитує всіх домашніх тварин, де користувач «ABC» прокоментував їх протягом останніх двох місяців, коли 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

Чи є у вас доступні вибіркові дані?
Валькірія

Як надати вибіркові дані?
BufferStack

Спробуйте підказки у цій публікації: meta.stackexchange.com/questions/156729/…
Валькірія

1
Це добре, але SQLFiddle краще;). Дивіться приклад тут . Шлях краще просто переглянути код і насінні дані, а не якусь таблицю, яку вам потрібно буде форматувати.
Мар’ян

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.