通过子查询选择多列


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

基本上,我试图从同一行中获取lastComDatelastPosterID,该行是针对特定宠物的注释中的最新行。请提出如何有效地获取它们的建议。

上面的查询有效,但由于两次获取同一行而显得有些矫kill过正。而且,该ORDER BY子句比聚合函数要慢得多-正如我在分析查询时发现的那样。因此,避免排序的解决方案将不胜感激。


1
如果您在评论表上有一个索引(petid,id),则排序的顺序可能不会很慢,但是首先要考虑的事情是:您的查询似乎在询问所有用户ID为“ ABC”的宠物它们在过去两个月内,其中deviceID不是'ABC'(尽管目前尚不清楚deviceID是哪个表中的一列,可能是宠物,也可能是注释),最后一个评论者是谁,以及最后一个评论日期。那正确吗?
Michael-sqlbot

@ Michael-sqlbot-是的,这正是我要收集的内容。在deviceIDpets表-也就是说,只是不明白我这是由“ABC”自己提交的宠物。
BufferStack

Answers:


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两个lastComDatelastPosterId所有记录。
BufferStack

您有可用的样本数据吗?
女武神

如何提供样本数据?
BufferStack


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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.