SQL left join two tables independently

一曲冷凌霜 提交于 2021-02-10 20:39:49

问题


If I have these tables:

Thing
id | name
---+---------
1  | thing 1
2  | thing 2
3  | thing 3

Photos
id | thing_id | src
---+----------+---------
1  | 1        | thing-i1.jpg
2  | 1        | thing-i2.jpg
3  | 2        | thing2.jpg

Ratings
id | thing_id | rating
---+----------+---------
1  | 1        | 6
2  | 2        | 3
3  | 2        | 4

How can I join them to produce

id | name    | rating | photo
---+---------+--------+--------
1  | thing 1 | 6      | NULL
1  | thing 1 | NULL   | thing-i1.jpg
1  | thing 1 | NULL   | thing-i2.jpg

2  | thing 2 | 3      | NULL
2  | thing 2 | 4      | NULL
2  | thing 2 | NULL   | thing2.jpg

3  | thing 3 | NULL   | NULL

Ie, left join on each table simultaneously, rather than left joining on one than the next?

This is the closest I can get:

SELECT Thing.*, Rating.rating, Photo.src
From Thing
Left Join Photo on Thing.id = Photo.thing_id
Left Join Rating on Thing.id = Rating.thing_id

回答1:


You can get the results you want with a union, which seems the most obvious, since you return a field from either ranking or photo.

Your additional case (have none of either), is solved by making the joins left join instead of inner joins. You will get a duplicate record with NULL, NULL in ranking, photo. You can filter this out by moving the lot to a subquery and do select distinct on the main query, but the more obvious solution is to replace union all by union, which also filters out duplicates. Easier and more readable.

select
  t.id,
  t.name,
  r.rating,
  null as photo
from
  Thing t
  left join Rating r on r.thing_id = t.id
union
select
  t.id,
  t.name,
  null,
  p.src
from
  Thing t
  left join Photo p on p.thing_id = t.id
order by
  id,
  photo,
  rating



回答2:


MySQL has no support for full outer joins so you have to hack around it using a UNION:

Here's the fiddle: http://sqlfiddle.com/#!2/d3d2f/13

SELECT *
FROM (
    SELECT Thing.*,
           Rating.rating,
           NULL AS photo
    FROM Thing
    LEFT JOIN Rating ON Thing.id = Rating.thing_id

    UNION ALL

    SELECT Thing.*,
           NULL,
           Photo.src
    FROM Thing
    LEFT JOIN Photo ON Thing.id = Photo.thing_id
) s
ORDER BY id, photo, rating



回答3:


Here's what I came up with:

SELECT
  Thing.*,
  rp.src,
  rp.rating
FROM
  Thing
  LEFT JOIN (
    (
      SELECT
        Photo.src,
        Photo.thing_id AS ptid,
        Rating.rating,
        Rating.thing_id AS rtid
      FROM
        Photo
        LEFT JOIN Rating
          ON 1 = 0
    )
    UNION
    (
      SELECT
        Photo.src,
        Photo.thing_id AS ptid,
        Rating.rating,
        Rating.thing_id AS rtid
      FROM
        Rating
        LEFT JOIN Photo
          ON 1 = 0
    )
  ) AS rp
    ON Thing.id IN (rp.rtid, rp.ptid)


来源:https://stackoverflow.com/questions/25822489/sql-left-join-two-tables-independently

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!