限制在合作社的右侧部分

时间:2013-10-01 21:45:31

标签: mysql sql join limit

我有两个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'
你知道吗? = /

感谢。

2 个答案:

答案 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