【问题标题】:select single row from foreign table in left join在左连接中从外部表中选择单行
【发布时间】:2021-04-02 07:44:57
【问题描述】:

我想获取外键匹配的第一行。我不知道如何选择第一行 外键匹配的地方

事件表

id   |  name 
----------------
 1   |  john
----------------
 2  |  Cat

event_attendee 表

id   |  event_id | type
--------------------------
 1   |  1        | User
--------------------------
 2   |  1        | Local
--------------------------
 3   |  1        | User
--------------------------
 4   |  2        | User
--------------------------
 5   |  2        | User

我想要这个结果

id   |  name    | event_id | type
------------------------------------
 1   |  John    | 1        | User
------------------------------------
 2   |  Cat     | 2        | User   

试过

select
a.*,
b.*
from
events as a
left join (
select
distinct
event_attendee.events_id,
event_attendee.type
from
event_attendee
left join events on
event_attendees.events_id = events.id
where
events.id = event_attendees.events_id
limit 1 

) as b on
a.id = b.events_id

问题

它只适用于第一行,第二行显示为空

id   |  name    | type
------------------------------------
 1   |  John    | User
------------------------------------
 2   |  Cat     |  

【问题讨论】:

    标签: sql postgresql join


    【解决方案1】:

    您可以使用横向连接来做到这一点。在 Postgres 中,语法是:

    select e.*, ea.*
    from events e left join lateral
         (select ea.event_Id, ea.Type
          from event_attendee ea
          where ea.event_id = e.id
          order by ea.id
         ) ea
         on 1=1;
    

    但是,distinct on 是一种无需子查询的方式:

    select distinct on (e.event_id) e.*, ea.*
    from events e join
         event_attendee ea
         on ea.event_id = e.id
    order by e.event_id, ea.id;
    

    我希望横向连接在较大的表上工作得更好,尤其是在索引正确的情况下。

    【讨论】:

    • 横向连接没有给出正确的结果。但是 distinct on 给出了期望的输出。您可以在我的问题中看到实际结果示例。谢谢(Y)
    【解决方案2】:

    cross apply 很容易:

    select *
    from events e
    cross apply (
        select top (1) event_Id, Type
        from event_attendee ea
        where ea.event_id=e.id
        order by id
    )x
    

    编辑,替代兼容方法!

    select e.*,ea.event_Id, (select type from event_attendee ea2 where ea2.id=ea.id ) Type
    from (
        select Min(id) Id, event_id
        from event_attendee
        group by event_id
    )ea
    join events e on e.id=ea.event_id
    

    【讨论】:

    • 为什么它在应用附近出现错误,在“应用”上或附近出现语法错误
    • 是的,不幸的是我没有注意你的 postgres 标签——它需要使用 lateral join 的语法略有不同——你现在已经有了这个解决方案。顺便说一句,我在上面进行了编辑,并添加了一种仅使用标准相关子查询来编写它的替代方法。问候斯图。
    【解决方案3】:

    一种获取排名并使用它来过滤第一条记录的方法:

    select
    t_.id, t_.name, t_.type
    from
    (
    select a.*, b.type,
    rank() OVER (PARTITION BY a.id ORDER BY b.id asc) rank_
    from events a
    left join event_attendees b
    on 
    a.id = b.events_id
    ) t_
    where
    t_.rank_ = 1
    

    【讨论】:

    • 请提供小提琴网址。它的工作。 [小提琴网址] : (dbfiddle.uk/…)
    猜你喜欢
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    • 2013-10-11
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2013-08-01
    • 2023-03-03
    相关资源
    最近更新 更多