【问题标题】:Group pages and get x number of row from each group分组页面并从每个组中获取 x 行
【发布时间】:2011-10-24 03:46:15
【问题描述】:

继我之前的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

【问题讨论】:

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


    【解决方案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 不一致。

    【讨论】:

    • 谢谢。第一个查询显示行号,但第二个不显示。但是,第一个查询仍然没有返回我之后的查询,因为行号是 - 1,2,3,4,5,6,7 请参阅我上面的编辑。
    • @lauthiamkok:啊,你想要group_title上的排名。必须跑去上班,但在我下班回家之前,你应该有足够的工作时间。
    • 我试过了,但我在数字行中得到了1,1,1,1,1,1,1 请查看我上面的编辑。谢谢。
    • 在更改此行JOIN (SELECT @g:=null, @r:= 0) n -- Initialize the variable 后现在可以工作了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多