За последние 24 часа нас посетили 16864 программиста и 1291 робот. Сейчас ищут 1469 программистов ...

Лимит при выборке с группировкой (лимит по 2 записи)

Тема в разделе "MSSQL", создана пользователем Baltazar5000, 14 окт 2011.

  1. Baltazar5000

    Baltazar5000 Активный пользователь

    С нами с:
    14 окт 2011
    Сообщения:
    2
    Симпатии:
    0
    [sql]SELECT * FROM events WHERE daydate>=1 AND daydate<=31 GROUP BY daydate[/sql]

    Данный запрос выберет по 1 му событию на каждый день. Как выбрать по 3 события? Спасибо.
     
  2. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Baltazar5000
    [sql]SELECT * FROM events WHERE daydate>=1 AND daydate<=31 GROUP BY daydate HAVING count(*) > 2[/sql]
     
  3. Baltazar5000

    Baltazar5000 Активный пользователь

    С нами с:
    14 окт 2011
    Сообщения:
    2
    Симпатии:
    0
    Не подходит. Это доп условие чтобы количество элементов в группе было больше 2х. А мне надо вывести именно по 2 или 3 элемента с каждой группы. Можно не используя GROUP.
     
  4. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Поскольку MySQL 5 не поддерживает limit в выражения IN задача просто не решается.

    Есть решение в лоб, но учтите, оно убьёт вашу БД.
    Для выбора двух строк в день:
    [sql]select * from events
    where id in (
    select id from events group by day union
    select id from events where id not in (select id from events t1 group by day) group by day
    )
    [/sql]

    для трёх:
    [sql]select * from events
    where id in(
    select id from events group by day union
    select id from events where id not in (select id from events t1 group by day) group by day union
    select id from events where id not in (
    select id from events group by day union
    select id from events where id not in (select id from events t1 group by day) group by day
    ) group by day
    )
    [/sql]

    исходные данные:
    [sql] CREATE TABLE `events` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `day` int(11) NOT NULL,
    `text` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`)
    );
    INSERT INTO `events` VALUES (1,1,'some1'),(2,1,'some2'),(3,1,'some3'),(4,1,'some4'),(5,1,'some5'),(6,1,'some6'),(7,2,'some7'),(8,2,'some8'),(9,3,'some9'),(10,4,'some10'),(11,4,'some11'),(12,4,'some12'),(13,4,'some13'),(14,4,'some14'),(15,4,'some15'),(16,4,'some16'),(17,4,'some17'),(18,4,'some18'),(19,4,'some19'),(20,4,'some20'),(21,4,'some21');
    [/sql]
    Код (Text):
    1. mysql> select * from events;
    2. +----+-----+--------+
    3. | id | day | text   |
    4. +----+-----+--------+
    5. |  1 |   1 | some1  |
    6. |  2 |   1 | some2  |
    7. |  3 |   1 | some3  |
    8. |  4 |   1 | some4  |
    9. |  5 |   1 | some5  |
    10. |  6 |   1 | some6  |
    11. |  7 |   2 | some7  |
    12. |  8 |   2 | some8  |
    13. |  9 |   3 | some9  |
    14. | 10 |   4 | some10 |
    15. | 11 |   4 | some11 |
    16. | 12 |   4 | some12 |
    17. | 13 |   4 | some13 |
    18. | 14 |   4 | some14 |
    19. | 15 |   4 | some15 |
    20. | 16 |   4 | some16 |
    21. | 17 |   4 | some17 |
    22. | 18 |   4 | some18 |
    23. | 19 |   4 | some19 |
    24. | 20 |   4 | some20 |
    25. | 21 |   4 | some21 |
    26. +----+-----+--------+
    27. 21 rows in set (0.00 sec)
    28.  
    29. mysql> select * from events
    30.     -> where id in (
    31.     ->   select id from events group by day union
    32.     ->   select id from events where id not in (select id from events t1 group by day) group by day
    33.     -> )
    34.     -> ;
    35. +----+-----+--------+
    36. | id | day | text   |
    37. +----+-----+--------+
    38. |  1 |   1 | some1  |
    39. |  2 |   1 | some2  |
    40. |  7 |   2 | some7  |
    41. |  8 |   2 | some8  |
    42. |  9 |   3 | some9  |
    43. | 10 |   4 | some10 |
    44. | 11 |   4 | some11 |
    45. +----+-----+--------+
    46. 7 rows in set (0.02 sec)
    47.  
    48. mysql> select * from events
    49.     -> where id in(
    50.     ->   select id from events group by day union
    51.     ->   select id from events where id not in (select id from events t1 group by day) group by day union
    52.     ->   select id from events where id not in (
    53.     ->     select id from events group by day union
    54.     ->     select id from events where id not in (select id from events t1 group by day) group by day
    55.     ->   ) group by day
    56.     -> )
    57.     -> ;
    58. +----+-----+--------+
    59. | id | day | text   |
    60. +----+-----+--------+
    61. |  1 |   1 | some1  |
    62. |  2 |   1 | some2  |
    63. |  3 |   1 | some3  |
    64. |  7 |   2 | some7  |
    65. |  8 |   2 | some8  |
    66. |  9 |   3 | some9  |
    67. | 10 |   4 | some10 |
    68. | 11 |   4 | some11 |
    69. | 12 |   4 | some12 |
    70. +----+-----+--------+
    71. 9 rows in set (0.48 sec)
    Несмотря на то, что это грубое решения для MySQL, оно может помочь вам найти более простое и элегантное решение.
     
  5. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Что касается меня, то считаю следующий вариант правильным:
    [sql]SELECT * FROM (
    SELECT day FROM (
    SELECT distinct day, c1 FROM `events` t2
    CROSS JOIN (
    SELECT 1 as c1 UNION SELECT 2 UNION SELECT 3
    ) t3
    ) t5
    ) t4
    LEFT JOIN `events` e1 ON e1.day = t4.day
    [/sql]
    Но MySQL категорически против и плавно превращает LEFT JOIN в RIGHT JOIN

    Второй вариант MySQL тоже отверг:
    [sql]SELECT * FROM events t1 WHERE id in (SELECT id FROM events t2 WHERE t2.day = t1.day LIMIT 3)[/sql]