子查询左连接引用父ID

Posted

技术标签:

【中文标题】子查询左连接引用父ID【英文标题】:Subquery left join refer to parent ID 【发布时间】:2020-10-02 19:04:48 【问题描述】:

我正在尝试查询以获取每个用户的最新汽车:

select * from users 
    left join 
       (select cars.* from cars 
        where cars.userid=users.userid 
        order by cars.year desc limit 1) as cars
    on cars.userid=users.userid

看起来它在 where 子句中显示未知列“users.userid” 我试图删除 cars.userid=users.userid 部分,但它只获取 1 辆最新的汽车,并将其粘贴到每个用户身上。

有什么方法可以完成我所追求的吗?谢谢!!

【问题讨论】:

能否请您发布创建表和一些数据,以便我们更好地理解您的问题,请参阅meta.***.com/questions/333952/… 请在代码问题中给出minimal reproducible example--cut & paste & runnable code,包括最小的代表性示例输入为代码;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。给出尽可能少的代码,即您显示的代码可以通过您显示的代码扩展为不正常的代码。 (调试基础。)对于包含 DBMS 和 DDL(包括约束和索引)和输入为格式化为表的代码的 SQL。 How to Ask 暂停总体目标的工作,将代码砍到第一个表达式,没有给出你期望的内容,说出你的期望和原因。 【参考方案1】:

为此,我通常使用row_number()

select *
from users u left join
     (select c.* , row_number() over (partition by c.userid order by c.year desc) as seqnum
      from cars c
     ) c 
     on c.userid = u.userid and c.seqnum = 1;

【讨论】:

您好,谢谢您的回答。我得到```“SQL语法错误......靠近'(按c.userid顺序按c.year desc分区)作为seqnum来自汽车c)c”```【参考方案2】:

一种选择是使用子查询过滤left join

select * -- better enumerate the columns here
from users u
left join cars c 
    on  c.userid = u.userid
    and c.year = (select max(c1.year) from cars c1 where c1.userid = c.userid)

为了提高性能,请考虑在car(userid, year) 上建立索引。

请注意,如果您在 cars 中有重复的 (userid, year),这可能会为每位用户返回多辆汽车。最好有一个真实的日期而不仅仅是年份。

【讨论】:

效果很好!非常好的解决方案,我不认为在连接语句上使用 AND。多谢!似乎也很快【参考方案3】:

也许有更好、更有效的方法来查询这个。这是我的解决方案;

select users.userid, cars.*
from users
         left join cars on cars.userid = users.userid
         join (SELECT userid, MAX(year) AS maxDate
               FROM cars
               GROUP BY userid) as sub on cars.year = sub.maxDate;

【讨论】:

您好,感谢您的回答,但看起来每个用户返回的汽车不止一辆。

以上是关于子查询左连接引用父ID的主要内容,如果未能解决你的问题,请参考以下文章

左连接与子查询的性能问题以找出最新日期

mysql - 子查询和连接

如何在 Laravel 5.1 中编写这个(左连接、子查询)?

子表单连接,主/子,引用表单控件或使用查询连接,哪个更可取

在子查询 JOIN 中引用外部查询

左连接子查询访问