Kdd*_*ddC 125 mysql join left-join groupwise-maximum
我读了许多关于只获得左连接的第一行的线程,但是,由于某种原因,这对我不起作用.
这是我的结构(当然简化)
饲料
id | title | content
----------------------
1 | Feed 1 | ...
Run Code Online (Sandbox Code Playgroud)
艺术家
artist_id | artist_name
-----------------------
1 | Artist 1
2 | Artist 2
Run Code Online (Sandbox Code Playgroud)
feeds_artists
rel_id | artist_id | feed_id
----------------------------
1 | 1 | 1
2 | 2 | 1
...
Run Code Online (Sandbox Code Playgroud)
现在我想获得文章并加入第一位艺术家,我想到了这样的事情:
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'
Run Code Online (Sandbox Code Playgroud)
只是为了获得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'
Run Code Online (Sandbox Code Playgroud)
Mat*_*dge 91
如果您可以假设艺术家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
Run Code Online (Sandbox Code Playgroud)
小智 51
没有子选择的版本:
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
Run Code Online (Sandbox Code Playgroud)
Kdd*_*ddC 16
@Matt Dodges的回答使我走上了正确的轨道。再次感谢您提供所有答案,在此期间,这对很多人都有所帮助。像这样工作:
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'
Run Code Online (Sandbox Code Playgroud)
基于这里的几个答案,我发现了一些对我有用的东西,我想概括和解释发生了什么。
转变:
LEFT JOIN table2 t2 ON (t2.thing = t1.thing)
Run Code Online (Sandbox Code Playgroud)
到:
LEFT JOIN table2 t2 ON (t2.p_key = (SELECT MIN(t2_.p_key)
FROM table2 t2_ WHERE (t2_.thing = t1.thing) LIMIT 1))
Run Code Online (Sandbox Code Playgroud)
连接 t1 和 t2 的条件从ON和移动到内部查询中WHERE。在MIN(primary key)或LIMIT 1确保只有1行由内部查询返回。
选择一个特定的行后,我们需要告诉ON它是哪一行。这就是为什么ON要比较连接表的主键。
您可以使用内部查询(即订单+限制),但它必须返回所需行的一个主键,该主键将告诉ON要加入的确切行。
更新 - 适用于 MySQL 5.7+
另一个与 MySQL 5.7+ 相关的选项是使用ANY_VALUE+ GROUP BY。它将选择一个不一定是第一个的艺术家姓名。
SELECT feeds.*,ANY_VALUE(feeds_artists.name) artist_name
FROM feeds
LEFT JOIN feeds_artists ON feeds.id = feeds_artists.feed_id
GROUP BY feeds.id
Run Code Online (Sandbox Code Playgroud)
关于 ANY_VALUE 的更多信息:https ://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
| 归档时间: |
|
| 查看次数: |
169968 次 |
| 最近记录: |