MySQL: ограничить запрос до 10 строк, где каждый индекс имеет 5 тегов - PullRequest
1 голос
/ 11 сентября 2010

Я хотел бы сделать запрос, в котором я могу получить интервал из 10 строк с 5 тегами на каждый.

У меня есть таблицы houses и tags, я знаю, как это сделатьтолько для простых запросов с SELECT с использованием LIMIT, но как я могу это сделать в этом случае?

table houses
id    house            country
1     Grunt Mansion    us
2     Hororo Suneku    jp
3     Casa Cattani     it
4     Sweet Home       uk
5     Heinzvaiter      de
6     F56X-5           us
7     Swan Jong        cn
8     Drupnowevo       ru
9     Bambagiador      br
10    El Stanco        es

table houses_tags
id    id_house    id_tag
1     1           1
2     1           2
3     1           3
4     1           4
5     2           1
6     2           2
7     2           3
8     2           4

table tags
id    tag
1     minimal
2     baroque
3     cosy
4     simple

Если создать запрос, подобный этому, чтобы получить первые 10 домов:

SELECT *
FROM houses
LEFT JOIN (
    SELECT *
    FROM tags
    INNER JOIN houses_tags
    ON id_house = houses.id
    LIMIT 5
) house_tag
LIMIT 0, 10

Я получаю что-то вроде этого:

query result
row    house            country    tag      id_house     id_tag
1      Grunt Mansion    us         minimal  1            1
2      Grunt Mansion    us         baroque  1            2
3      Grunt Mansion    us         cosy     1            3
4      Grunt Mansion    us         simple   1            4
5      Hororo Suneku    jp         minimal  2            1
6      Hororo Suneku    jp         baroque  2            2
7      Hororo Suneku    jp         cosy     2            3
8      Hororo Suneku    jp         simple   2            4
9      Casa Cattani     it         NULL     NULL         NULL
10     Sweet Home       uk         NULL     NULL         NULL

Моя проблема в том, что я получаю только первые 10 строк, вырезая последние houses из запроса, потому что tags из первых занимаютвсе строки

Могу ли я написать запрос, в котором я могу получить первые 10 домов и 5 тегов для каждого?

query result
row    house            country    tag      id_house     id_tag
1      Grunt Mansion    us         minimal  1            1
2      Grunt Mansion    us         baroque  1            2
3      Grunt Mansion    us         cosy     1            3
4      Grunt Mansion    us         simple   1            4
5      Hororo Suneku    jp         minimal  2            1
6      Hororo Suneku    jp         baroque  2            2
7      Hororo Suneku    jp         cosy     2            3
8      Hororo Suneku    jp         simple   2            4
9      Casa Cattani     it         NULL     NULL         NULL
10     Sweet Home       uk         NULL     NULL         NULL
11     Heinzvaiter      de         NULL     NULL         NULL
12     F56X-5           us         NULL     NULL         NULL
13     Swan Jong        cn         NULL     NULL         NULL
14     Drupnowevo       ru         NULL     NULL         NULL
15     Bambagiador      br         NULL     NULL         NULL
16     El Stanco        es         NULL     NULL         NULL

В конце мне нужен результат, который я отображаю вот такпример:

Mansions          Tags
Grunt Mansion     minimal, baroque, cosy, simple
Hororo Suneku     minimal, baroque, cosy, simple
Casa Cattani      -
Sweet Home        -
Heinzvaiter       -
F56X-5            -
Swan Jong         -
Drupnowevo        -
Bambagiador       -
El Stanco         -

pages 1 | 2 | 3

можно ли это сделать?

Ответы [ 2 ]

1 голос
/ 11 сентября 2010

MySQL не имеет аналитических функций, что бы вы использовали для этого до LIMIT:

    SELECT x.id,
           x.house,
           x.country,
           x.id_tag
      FROM (SELECT h.id,
                   h.house,
                   h.country,
                   ht.id_tag,
                   CASE 
                     WHEN @id = h.id THEN @rownum := @rownum + 1
                     ELSE @rownum := 1
                   END AS rank,
                   @id := h.id,
                   @house_count := @house_count + 1 AS house_count
              FROM HOUSE h
         LEFT JOIN HOUSES_TAGS ht ON ht.id_house = h.id
              JOIN (SELECT @rownum := 0, @id := -1, @house_count := 0) r
          ORDER BY h.id, ht.id_tag) x
   WHERE x.house_count <= 10
     AND x.rank <= 4        
ORDER BY x.id, x.id_tag
1 голос
/ 11 сентября 2010

Я думаю, вы хотите, чтобы ваш подвыбор вернул вам 10 идентификаторов домов, для которых вы хотите получить результаты, а затем просто оставил соединение с подвыбором таблицы тегов (предел 5)

...