每个连接的MySQL查询限制

每个连接的MySQL查询限制,mysql,greatest-n-per-group,hierarchical-data,Mysql,Greatest N Per Group,Hierarchical Data,我以前试过问这个问题,但如果没有我不太熟悉的正确术语,很难具体地问。下面是一个例子 以这个查询为例: ( SELECT * FROM comments WHERE depth = 0 ORDER BY id DESC LIMIT 2 ) UNION ALL ( SELECT c.* FROM comments c JOIN ( SELECT id FROM comments WHERE depth = 0 ORDER BY i

我以前试过问这个问题,但如果没有我不太熟悉的正确术语,很难具体地问。下面是一个例子

以这个查询为例:

(
SELECT *
FROM comments
WHERE depth = 0
ORDER BY id DESC
LIMIT 2
)
UNION ALL
(
  SELECT c.*
    FROM comments c JOIN 
    (
      SELECT id
      FROM comments
      WHERE depth = 0
      ORDER BY id DESC
      LIMIT 2
    ) p ON c.parent_id = p.id
    LIMIT 5
)


id  parent_id   depth   title
1   0           0       Title 1
2   0           0       Title 2
3   1           1       Title 3
4   1           1       Title 4
5   1           1       Title 5
6   1           1       Title 6
7   1           1       Title 7
id  parent_id   depth   title
1   0           0       Title 1
2   0           0       Title 2
3   1           1       Title 3
4   1           1       Title 4
5   1           1       Title 5
6   1           1       Title 6
7   1           1       Title 7
8   2           1       Title 8
9   2           1       Title 9
10  2           1       Title 10
11  2           1       Title 11
12  2           1       Title 12
我得到两个深度为0的行,在join中,我还得到了这两个返回查询的5个子元素。我想要得到的是这两个查询中的每一个都有5个子元素,总共10行,深度为1。例如:

(
SELECT *
FROM comments
WHERE depth = 0
ORDER BY id DESC
LIMIT 2
)
UNION ALL
(
  SELECT c.*
    FROM comments c JOIN 
    (
      SELECT id
      FROM comments
      WHERE depth = 0
      ORDER BY id DESC
      LIMIT 2
    ) p ON c.parent_id = p.id
    LIMIT 5
)


id  parent_id   depth   title
1   0           0       Title 1
2   0           0       Title 2
3   1           1       Title 3
4   1           1       Title 4
5   1           1       Title 5
6   1           1       Title 6
7   1           1       Title 7
id  parent_id   depth   title
1   0           0       Title 1
2   0           0       Title 2
3   1           1       Title 3
4   1           1       Title 4
5   1           1       Title 5
6   1           1       Title 6
7   1           1       Title 7
8   2           1       Title 8
9   2           1       Title 9
10  2           1       Title 10
11  2           1       Title 11
12  2           1       Title 12
如果有邻接列表和将所有内容返回为联合平面的要求,这是否可能

编辑: 多亏了比尔·卡温的回答,我现在可以工作了。我仍然想知道是否有一个更短的方式来写这个。我有6个0-5个深度级别,因此我的查询相当长,可能不是最优的。下面是三个级别的外观,您可以想象完整级别的外观

-- DEPTH LEVEL 0
(
  SELECT * FROM (
    SELECT *, 1 as _rn, @parent:=0
    FROM comments
    WHERE depth = 0
    ORDER BY id DESC
    LIMIT 2
  ) as D0
)
union all

-- DEPTH LEVEL 1
(
SELECT *
FROM (
  SELECT c.*, @row:=IF(@parent=c.comment_id,@row+1,1) AS _rn, @parent:=c.comment_id
    FROM (SELECT @parent:=null) AS _init 
    STRAIGHT_JOIN comments c 
    INNER JOIN 
    (
      SELECT id
      FROM comments
      WHERE depth = 0
      ORDER BY id DESC
      LIMIT 2
    ) p ON c.comment_id = p.id
  ) AS _ranked
WHERE _ranked._rn <= 5
)
union all

-- DEPTH LEVEL 2
(
SELECT *
FROM (
  SELECT c.*, @row:=IF(@parent=c.comment_id,@row+1,1) AS _rn, @parent:=c.comment_id
    FROM (SELECT @parent:=null) AS _init 
    STRAIGHT_JOIN comments c 
    INNER JOIN 
    (

      (
      SELECT *
      FROM (
        SELECT c.*, @row:=IF(@parent=c.comment_id,@row+1,1) AS _rn, @parent:=c.comment_id
          FROM (SELECT @parent:=null) AS _init 
          STRAIGHT_JOIN comments c 
          INNER JOIN 
          (
            SELECT id
            FROM comments
            WHERE depth = 0
            ORDER BY id DESC
            LIMIT 2
          ) p ON c.comment_id = p.id
        ) AS _ranked
      WHERE _ranked._rn <= 2
      )

    ) p ON c.comment_id = p.id
  ) AS _ranked
WHERE _ranked._rn <= 2
)

使用LIMIT无法做到这一点,因为LIMIT是在结果集完全完成之后应用的,在所有连接、分组、排序等之后应用的

您正在使用查询类型的变体。在MySQL中这样做很棘手,因为MySQL不支持许多其他SQL数据库支持的行数窗口功能

以下是MySQL的一个解决方案,其中用户定义的变量可以代替分区的行号:

SELECT *
FROM (
  SELECT c.*, @row:=IF(@parent=c.parent_id,@row+1,1) AS _rn, @parent:=c.parent_id
    FROM (SELECT @parent:=null) AS _init 
    STRAIGHT_JOIN comments c 
    INNER JOIN 
    (
      SELECT id
      FROM comments
      WHERE depth = 0
      ORDER BY id DESC
      LIMIT 2
    ) p ON c.parent_id = p.id
  ) AS _ranked
WHERE _ranked._rn <= 5

使用LIMIT无法做到这一点,因为LIMIT是在结果集完全完成之后应用的,在所有连接、分组、排序等之后应用的

您正在使用查询类型的变体。在MySQL中这样做很棘手,因为MySQL不支持许多其他SQL数据库支持的行数窗口功能

以下是MySQL的一个解决方案,其中用户定义的变量可以代替分区的行号:

SELECT *
FROM (
  SELECT c.*, @row:=IF(@parent=c.parent_id,@row+1,1) AS _rn, @parent:=c.parent_id
    FROM (SELECT @parent:=null) AS _init 
    STRAIGHT_JOIN comments c 
    INNER JOIN 
    (
      SELECT id
      FROM comments
      WHERE depth = 0
      ORDER BY id DESC
      LIMIT 2
    ) p ON c.parent_id = p.id
  ) AS _ranked
WHERE _ranked._rn <= 5

MySQL没有内置的N-per-group支持,但是如果您使用该标签搜索其他问题,您会发现各种解决方法。MySQL没有内置的N-per-group支持,但是如果您使用该标签搜索其他问题,您会发现各种解决方法。非常好,非常感谢!有没有一种更简单的方法可以扩展到60-5个深度?MySQL确实还有很多需要改进的地方。我不知道你在想什么。您应该编辑您的问题,以显示所需输出的示例,或者提出新问题。再次感谢Bill。我想知道是否可以缩短查询,我增加了一个例子。你可能想考虑使用另一种方法来组织除了邻接表之外的层次数据。例如,见。太好了,非常感谢!有没有一种更简单的方法可以扩展到60-5个深度?MySQL确实还有很多需要改进的地方。我不知道你在想什么。您应该编辑您的问题,以显示所需输出的示例,或者提出新问题。再次感谢Bill。我想知道是否可以缩短查询,我增加了一个例子。你可能想考虑使用另一种方法来组织除了邻接表之外的层次数据。例如,见。