分组页面并从每个组中获取x行数

时间:2011-10-24 03:46:16

标签: mysql sql greatest-n-per-group

从我之前提到的question开始,我在下面进行了查询,但不能限制每个组的特定行数,

SELECT *
  FROM (SELECT p.page_id AS page_id,
               p.page_url AS page_url,
           SUBSTRING(p.page_title,LOCATE('{',p.page_title),LOCATE('}',p.page_title)) AS group_title,
               p.page_created AS page_created,
               @row_number := @row_number + 1 AS row_number
          FROM root_pages AS p
         WHERE p.parent_id = '8'
           AND p.page_id != '8'
           AND p.page_hide != '1'
           AND p.category_id = '1'
      ORDER BY p.page_backdate DESC) a
 WHERE row_number <= 2

结果,

page_id page_url    group_title page_created    row_number
----------------------------------------------------------
44      abc         {a}         2011-10-21...   NULL
43      def         {a}         2011-10-21...   NULL
42      qwe         {b}         2011-10-21...   NULL
41      rty         {b}         2011-10-21...   NULL
40      tyu         {c}         2011-10-21...   NULL
39      ghj         {c}         2011-10-21...   NULL
59      sss         {c}         2011-10-21...   NULL

但我希望得到这个结果,

结果,

page_id page_url    group_title page_created    row_number
----------------------------------------------------------
44      abc         {a}         2011-10-21...   1
43      def         {a}         2011-10-21...   2
42      qwe         {b}         2011-10-21...   1
41      rty         {b}         2011-10-21...   2
40      tyu         {c}         2011-10-21...   1
39      ghj         {c}         2011-10-21...   2

有什么想法我错过了吗?

编辑1:

查询,

SELECT a.*
  FROM (SELECT p.page_id,
               p.page_url,
               SUBSTRING(p.page_title, LOCATE('{',p.page_title),LOCATE('}', p.page_title)) AS group_title,
               p.page_created,
               @row_number := @row_number + 1 AS row_number
          FROM root_pages AS p
          JOIN (SELECT @row_number := 0, @url) r -- Initialize the variable
         WHERE p.parent_id = '8'
           AND p.page_id != '8'
           AND p.page_hide != '1'
           AND p.category_id = '1'
      ORDER BY p.page_backdate DESC) a

结果,

page_id page_url    group_title page_created    row_number
----------------------------------------------------------
44      abc         {a}         2011-10-21...   1
43      def         {a}         2011-10-21...   2
42      qwe         {b}         2011-10-21...   3
41      rty         {b}         2011-10-21...   4
40      tyu         {c}         2011-10-21...   5
39      ghj         {c}         2011-10-21...   6
59      sss         {c}         2011-10-21...   7

查询,

SELECT a.*
  FROM (SELECT p.page_id,
               p.page_url,
               SUBSTRING(p.page_title, LOCATE('{',p.page_title),LOCATE('}', p.page_title)) AS group_title,
               p.page_created,
               @row_number := @row_number + 1 AS row_number
          FROM root_pages AS p
          JOIN (SELECT @row_number := 0, @url) r -- Initialize the variable
         WHERE p.parent_id = '8'
           AND p.page_id != '8'
           AND p.page_hide != '1'
           AND p.category_id = '1'
      ORDER BY p.page_backdate DESC) a
WHERE a.row_number <= 2

结果,

page_id page_url    group_title page_created    row_number
----------------------------------------------------------
44      abc         {a}         2011-10-21...   1
43      def         {a}         2011-10-21...   2

查询,

SELECT *

FROM(
    SELECT 

        p.page_id AS page_id,
        p.page_url AS page_url,
        SUBSTRING(p.page_title,LOCATE('{',p.page_title),LOCATE('}',p.page_title)) AS group_title,
        p.page_created AS page_created,
         @url = p.page_url,
               @row_number := CASE 
                                WHEN p.page_url = @url THEN @row_number + 1 
                                ELSE 1
                              END AS row_number

    FROM root_pages AS p
    JOIN (SELECT @row_number := 0, @url) r -- Initialize the variable

    WHERE p.parent_id = '8'
    AND p.page_id != '8'
    AND p.page_hide != '1'
    AND p.category_id = '1'

    ORDER BY p.page_backdate DESC


) a 
where  row_number <= 2

结果,

page_id page_url    group_title page_created    row_number
----------------------------------------------------------
44      abc         {a}         2011-10-21...   1
43      def         {a}         2011-10-21...   1
42      qwe         {b}         2011-10-21...   1
41      rty         {b}         2011-10-21...   1
40      tyu         {c}         2011-10-21...   1
39      ghj         {c}         2011-10-21...   1
59      sss         {c}         2011-10-21...   1

编辑2:

查询,

SELECT 
    a.*,
    @r := CASE WHEN @g = a.group_title THEN @r+1 ELSE 1 END AS r,
    @g := a.group_title AS dummy

FROM(
    SELECT 

        p.page_id AS page_id,
        p.page_url AS page_url,
        SUBSTRING(p.page_title,LOCATE('{',p.page_title),LOCATE('}',p.page_title)) AS group_title,
        p.page_created AS page_created

    FROM root_pages AS p

    WHERE p.parent_id = '8'
    AND p.page_id != '8'
    AND p.page_hide != '1'
    AND p.category_id = '1'

    ORDER BY p.page_backdate DESC

) a

JOIN (SELECT @r := 0, @g) r -- Initialize the variable

结果,

page_id page_url    group_title page_created    dummy       row_number
44      abc         {a}         2011-10-21...   {a}                 1
43      def         {a}         2011-10-21...   {a}                 1
42      qwe         {b}         2011-10-21...   {b}                 1
41      rty         {b}         2011-10-21...   {b}                 1
40      tyu         {c}         2011-10-21...   {c}                 1
39      ghj         {c}         2011-10-21...   {c}                 1
59      sss         {c}         2011-10-21...   {c}                 1

解答:

SELECT *

FROM
(
    SELECT 
        a.*,
        @r := CASE WHEN @g = a.group_title THEN @r+1 ELSE 1 END AS r,
        @g := a.group_title AS dummy

    FROM(
        SELECT 

            p.page_id AS page_id,
            p.page_url AS page_url,
            SUBSTRING(p.page_title,LOCATE('{',p.page_title),LOCATE('}',p.page_title)) AS group_title,
            p.page_created AS page_created

        FROM root_pages AS p

        WHERE p.parent_id = '8'
        AND p.page_id != '8'
        AND p.page_hide != '1'
        AND p.category_id = '1'

        ORDER BY p.page_backdate DESC

    ) a

    JOIN (SELECT @g:=null, @r:= 0) n -- Initialize the variable
) b
WHERE r <= 2

1 个答案:

答案 0 :(得分:1)

您的查询未初始化@row_number变量:

SELECT a.*
  FROM (SELECT p.page_id,
               p.page_url,
               SUBSTRING(p.page_title, LOCATE('{',p.page_title),LOCATE('}', p.page_title)) AS group_title,
               p.page_created,
               @row_number := @row_number + 1 AS row_number
          FROM root_pages AS p
          JOIN (SELECT @row_number := 0, @url) r -- Initialize the variable
         WHERE p.parent_id = '8'
           AND p.page_id != '8'
           AND p.page_hide != '1'
           AND p.category_id = '1'
      ORDER BY p.page_backdate DESC) a
WHERE a.row_number <= 2

否则,您需要在发布的查询之前使用SET声明。

其次,您发布的内容不包括重置变量所需的CASE语句,因此每个page_url获得1+

SELECT a.*
  FROM (SELECT p.page_id,
               p.page_url,
               SUBSTRING(p.page_title, LOCATE('{',p.page_title),LOCATE('}', p.page_title)) AS group_title,
               p.page_created,
               @url = p.page_url,
               @row_number := CASE 
                                WHEN p.page_url = @url THEN @row_number + 1 
                                ELSE 1
                              END AS row_number
          FROM root_pages AS p
          JOIN (SELECT @row_number := 0, @url) r -- Initialize the variable
         WHERE p.parent_id = '8'
           AND p.page_id != '8'
           AND p.page_hide != '1'
           AND p.category_id = '1'
      ORDER BY p.page_url, p.page_backdate DESC) a
WHERE a.row_number <= 2

IME,该变量适用于InnoDB表,但与MyISAM不一致。