首页 文章

LEFT JOIN仅第一行

提问于
浏览
104

我读了许多关于只获得左连接的第一行的线程,但是,由于某种原因,这对我不起作用 .

这是我的结构(当然简化)

Feeds

id |  title | content
----------------------
1  | Feed 1 | ...

Artists

artist_id | artist_name
-----------------------
1         | Artist 1
2         | Artist 2

feeds_artists

rel_id | artist_id | feed_id
----------------------------
1      |     1     |    1 
2      |     2     |    1 
...

现在我想获得文章并加入第一位艺术家,我想到了这样的事情:

SELECT *
    FROM feeds 
    LEFT JOIN feeds_artists ON wp_feeds.id = (
        SELECT feeds_artists.feed_id FROM feeds_artists
        WHERE feeds_artists.feed_id = feeds.id 
    LIMIT 1
    )
WHERE feeds.id = '13815'

只是为了获得feed_artists的第一行,但这已经不起作用了 .

我不能使用 TOP 因为我的数据库而且我无法按 feeds_artists.artist_id 对结果进行分组,因为我需要按日期对它们进行排序(我通过这种方式对它们进行分组得到结果,但结果不是最新的)

用OUTER APPLY尝试了一些东西 - 也没有成功 . 说实话,我无法想象在这些行中发生了什么 - 可能是我无法让这个工作的最大原因 .

解:

SELECT *
FROM feeds f
LEFT JOIN artists a ON a.artist_id = (
    SELECT artist_id
    FROM feeds_artists fa 
    WHERE fa.feed_id = f.id
    LIMIT 1
)
WHERE f.id = '13815'

4 回答

  • 47

    我想给出一个更广泛的答案 . 当您只想选择LEFT JOIN中的第一个项目时,它将处理任何情况 .

    你可以使用GROUP_CONCATS你想要的子查询(也是排序的!),然后只拆分GROUP_CONCAT的结果并只采用它的第一项,就像这样......

    LEFT JOIN Person ON Person.id = (
        SELECT SUBSTRING_INDEX(
            GROUP_CONCAT(FirstName ORDER BY FirstName DESC SEPARATOR "_" ), '_', 1)
        ) FROM Person
    );
    

    由于我们将DESC作为ORDER BY选项,因此将为"Zack"之类的人返回一个Person id . 如果我们想要名称为"Andy"的人,我们会将ORDER BY FirstName DESC更改为ORDER BY FirstName ASC .

    这是灵活的,因为这将订购的力量完全放在您的手中 . 但是,经过大量测试后,在拥有大量用户和大量数据的情况下,它无法很好地扩展 .

    但是,它对于管理员运行数据密集型报告很有用 .

  • 84

    没有子选择的版本:

    SELECT f.title,
              f.content,
              MIN(a.artist_name) artist_name
         FROM feeds f
    LEFT JOIN feeds_artists fa ON fa.feed_id = f.id
    LEFT JOIN artists a ON fa.artist_id = a.artist_id
     GROUP BY f.id
    
  • 0

    我已经使用了其他东西(我认为更好......)并希望分享它:

    我创建了一个具有“组”子句的VIEW

    CREATE VIEW vCountries AS SELECT * PROVINCES GROUP BY country_code
    
    SELECT * FROM client INNER JOIN vCountries on client_province = province_id
    

    我想说,我认为我们需要做这个解决方案,因为我们在分析中有些错误...至少在我的情况下......但有时这样做更便宜,重新设计一切......

    我希望它有所帮助!

  • 1

    如果您可以假设艺术家ID随着时间的推移而增加,则 MIN(artist_id) 将是最早的 .

    所以尝试这样的事情(未经测试......)

    SELECT *
      FROM feeds f
      LEFT JOIN artists a ON a.artist_id = (
        SELECT
          MIN(fa.artist_id) a_id
        FROM feeds_artists fa 
        WHERE fa.feed_id = f.feed_id
      ) a
    

相关问题