我有两个SQL表:
collections(id, user_id, name)
files(id, collection_id, name, start_date)
我希望,只需一个请求,就每个集合中“预览”3个文件(最大值)检索给定用户的每个集合。
我的第一个(也是唯一的)想法是这样的:
SELECT f.*
FROM collections c
LEFT JOIN files f
ON f.collection_id = c.id
WHERE c.user_id = 1 AND f.id IN
(
SELECT id
FROM files
WHERE collection_id = c.id
ORDER BY start_date DESC
LIMIT 3
)
ORDER BY c.name, f.start_date DESC
但它不适用于MySQL,给出:
#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
你知道吗? = /
感谢。
答案 0 :(得分:0)
Innern join只返回它们在两个表上匹配的行。
所以只需在主查询结束时设置限制。
SELECT f.*
FROM collections c
JOIN files f
ON f.collection_id = c.id
INNER JOIN
(
SELECT id
FROM files
WHERE collection_id = c.id
ORDER BY start_date DESC
) ff ON f.id=ff.id WHERE c.user_id = 1
ORDER BY c.name, f.start_date DESC LIMIT 3
答案 1 :(得分:0)
您可以使用一个使用GROUP_CONCAT和FIND_IN_SET的小技巧,如下所示:
SELECT
f.*
FROM
collections c INNER JOIN files f
ON c.id = f.collection_id
INNER JOIN (
SELECT
collection_id, GROUP_CONCAT(id ORDER BY start_date DESC) ids
FROM
files
GROUP BY
collection_id) cf
ON f.collection_id = cf.collection_id
AND FIND_IN_SET(f.id, cf.ids)<=3
WHERE c.user_id = 1
请参阅小提琴here。它不会很快,但如果你只需要返回一些记录就应该没问题。
或者您可以使用此查询:
SELECT
f.*
FROM
collections c INNER JOIN files f
ON c.id = f.collection_id
INNER JOIN (
SELECT f.collection_id, f.id
FROM
files f LEFT JOIN files f2
ON f.collection_id = f2.collection_id
AND (f.start_date < f2.start_date
OR ((f.start_date = f2.start_date) AND (f.id<f2.id)))
GROUP BY
f.id
HAVING
COUNT(f2.id)<3
) last_three
ON f.collection_id = last_three.collection_id
AND f.id = last_three.id