Сгруппируйте страницы и получите х номер строки из каждой группы - PullRequest
2 голосов
/ 24 октября 2011

В ответ на вопрос , который я задал ранее, я сделал запрос ниже, но он не может ограничить определенное количество строк в каждой группе,

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 Ответ

1 голос
/ 24 октября 2011

Ваш запрос не инициализировал переменную @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, необходимый для сброса переменной, поэтому вы получаете 1+ для каждого page_url

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.

...