การเลือกหลายคอลัมน์ผ่านแบบสอบถามย่อย


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) บนตารางความคิดเห็นลำดับโดยอาจไม่ช้า แต่สิ่งแรกก่อน: ดูเหมือนว่าข้อความค้นหาของคุณกำลังขอสัตว์เลี้ยงทั้งหมดที่ userid 'ABC' แสดงความคิดเห็นไว้ ภายในสองเดือนที่ผ่านมาที่ deviceID ไม่ใช่ 'ABC' (แม้ว่าจะไม่ชัดเจนว่า deviceID ของตารางใดที่เป็นคอลัมน์ในอาจเป็นสัตว์เลี้ยงและอาจเป็นความคิดเห็น) และใครเป็นผู้วิจารณ์คนสุดท้ายและวันที่แสดงความคิดเห็นล่าสุด นั่นถูกต้องใช่ไหม?
Michael - sqlbot

@ Michael-sqlbot - ใช่นั่นคือสิ่งที่ฉันพยายามรวบรวม deviceIDจากpetsตาราง - หมายความว่าเพียงแค่ไม่ได้รับฉันสัตว์เลี้ยงที่ถูกส่งมาโดย 'เอบีซี' ตัวเอง
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 นั้นดีกว่า;) ดูตัวอย่างที่นี่ วิธีที่ดีกว่าในการดูรหัสและข้อมูลเมล็ดไม่ใช่บางตารางที่คุณต้องจัดรูปแบบ
แมเรียน

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.