Просмотр темы
Страница 1 из 2: 12
|
Зад. по MySQL
|
|
grungestranger |
Опубликовано 07.10.2014 14:26
|
![]() Пользователь ![]() Сообщений: 83 Зарегистрирован: 25.02.2013 21:52 |
Допустим, есть таблица: Таблица t1 id type 1- 1 2- 1 3- 1 4- 2 5- 2 6- 2 7- 3 8- 3 9- 3 10 4 Как сделать выборку, чтобы строк с каждым типом было, например, не больше 2 ? То есть получить: id type 1- 1 2- 1 4- 2 5- 2 7- 3 8- 3 10 4 |
|
|
spiker |
Опубликовано 08.10.2014 05:51
|
![]() Опытный пользователь ![]() Сообщений: 217 Зарегистрирован: 26.08.2010 08:49 |
Так не пойдёт?
|
|
|
grungestranger |
Опубликовано 08.10.2014 07:54
|
![]() Пользователь ![]() Сообщений: 83 Зарегистрирован: 25.02.2013 21:52 |
spiker написал: Так не пойдёт?
Неет)) Надо только через sql SELECT * FROM t1 WHERE type = '1' ORDER BY id LIMIT 2 UNION ALL (SELECT * FROM t1 WHERE type = '2' ORDER BY id LIMIT 2) UNION ALL (SELECT * FROM t1 WHERE type = '3' ORDER BY id LIMIT 2) ... Но так как подразумевается, что типов может быть бесконечно... Нужно что-то другое. |
|
|
spiker |
Опубликовано 08.10.2014 08:32
|
![]() Опытный пользователь ![]() Сообщений: 217 Зарегистрирован: 26.08.2010 08:49 |
Неет)) Надо только через sql Кому надо то? Поспорил что ль с кем? Цель какая — сделать, чтоб работало? Или сломать мозг как впихнуть 100500 UNION ALL'ов в SQL запрос? |
|
|
grungestranger |
Опубликовано 08.10.2014 08:55
|
![]() Пользователь ![]() Сообщений: 83 Зарегистрирован: 25.02.2013 21:52 |
spiker написал: Неет)) Надо только через sql Кому надо то? Поспорил что ль с кем? Цель какая — сделать, чтоб работало? Или сломать мозг как впихнуть 100500 UNION ALL'ов в SQL запрос? Это задачка, цель которой - выяснить, можно так сделать или нет. И union all тут не при чем, с ними так не получится. Тут надо делать, типа: SELECT * FROM ( SELECT *, [здесь как-то присваивать 1 только первым двум строкам типа, возможно с помощью переменных] AS x FROM t1 ORDER BY t1.type, id ) temp_table WHERE x = '1' ORDER BY t1.type, id Изменил(а) grungestranger, 08.10.2014 13:24 |
|
|
spiker |
Опубликовано 08.10.2014 09:19
|
![]() Опытный пользователь ![]() Сообщений: 217 Зарегистрирован: 26.08.2010 08:49 |
Ну не знаю. Я бы заморачиваться бы не стал. Простой вариант я написал. Ну если, неохота вбивать в массив, или не знаешь значения типов, можно "зацепить" уникальные отдельным SQL запросом. Как то так
|
|
|
grungestranger |
Опубликовано 08.10.2014 10:08
|
![]() Пользователь ![]() Сообщений: 83 Зарегистрирован: 25.02.2013 21:52 |
spiker, Такие запросы нужно делать без php, потому что иначе нельзя сделать постраничную разбивку данных. (Точнее можно, но это будет во много раз дольше) Вот такой вариант SELECT @i := 0; SELECT @j := 0; SELECT * FROM ( SELECT *, IF (@i != t1.type, @j := 0, @j := @j + 1) AS q, IF (@j < 2, 1, 0) AS x, IF (@i != t1.type, @i := t1.type, 0) AS w FROM t1 ORDER BY t1.type, id ) temp_table WHERE x = '1' ORDER BY t1.type, id должен был бы работать но, нет, видимо связано с подзапросом... SELECT @i := 0; SELECT @j := 0; SELECT *, IF (@i != t1.type, @j := 0, @j := @j + 1) AS q, IF (@j < 2, 1, 0) AS x, IF (@i != t1.type, @i := t1.type, 0) AS w FROM t1 ORDER BY t1.type, id а вот так работает, то есть ко всем нужным строкам в поле x ставит 1 Но как сделать, чтобы это было подзапросом, и чтобы из него выбирать.... Изменил(а) grungestranger, 08.10.2014 13:25 |
|
|
spiker |
Опубликовано 08.10.2014 10:47
|
![]() Опытный пользователь ![]() Сообщений: 217 Зарегистрирован: 26.08.2010 08:49 |
spiker, Такие запросы нужно делать без php, потому что иначе нельзя сделать постраничную разбивку данных. (Точнее можно, но это будет во много раз дольше) Чё там сложного не пойму. перевести в массив и разбить на страницы.. $types = array(); |
|
|
grungestranger |
Опубликовано 08.10.2014 11:37
|
![]() Пользователь ![]() Сообщений: 83 Зарегистрирован: 25.02.2013 21:52 |
spiker - это не сложно)) это будет выполняться НАМНОГО ДОЛЬШЕ!!! Объединено 08.10.2014 11:57: Вот так работает SET @i := 0; SET @j := 0; SELECT * FROM ( SELECT *, IF (@i != t1.type, @j := 0, @j := @j + 1) AS q, IF (@j < 2, 1, 0) AS x, IF (@i != t1.type, @i := t1.type, 0) AS w FROM t1 ORDER BY t1.type, id ) temp_table WHERE x = '1' ORDER BY t1.type, id Изменил(а) grungestranger, 08.10.2014 13:25 |
|
|
spiker |
Опубликовано 08.10.2014 12:15
|
![]() Опытный пользователь ![]() Сообщений: 217 Зарегистрирован: 26.08.2010 08:49 |
Ну... нам простым смертным вас — эстетов не понять. |
|
|
Rush |
Опубликовано 08.10.2014 12:29
|
![]() Администратор ![]() Разработчики ![]() Группа поддержки ![]() Сообщений: 1418 Зарегистрирован: 31.08.2010 14:41 |
намного это на одну миллионную секунды, лол?
|
|
|
grungestranger |
Опубликовано 08.10.2014 13:05
|
![]() Пользователь ![]() Сообщений: 83 Зарегистрирован: 25.02.2013 21:52 |
Rush )) Ну ты даешь)) Представь, у тебя есть миллион строк, и тебе надо разбить их по 10 штук на каждой странице) SQL справится с этим быстро, и с помощью LIMIT выдаст тебе нужные 10 строк. Ну и, например, тебе надо выбрать последние 10 строк, чтобы сделать это с помощью php, тебе придется весь миллион строк прогонять в массиве, плюс со всякими дополнительными запросами)). Что будет НАМНОГО ДОЛЬШЕ)) |
|
|
spiker |
Опубликовано 08.10.2014 13:26
|
![]() Опытный пользователь ![]() Сообщений: 217 Зарегистрирован: 26.08.2010 08:49 |
Ух ты.. миллион строк. Ну где результат танцев с бубном? Выкладывай, будем смотреть. С постраничной навигаций ![]() ЗЫ Массив да, будет тормозить (при таком объёме). Для постраничной навигации ещё же надо подсчитать общее количество на каких то условиях отсева ненужных строк. Изменил(а) spiker, 08.10.2014 13:33 |
|
|
grungestranger |
Опубликовано 08.10.2014 13:36
|
![]() Пользователь ![]() Сообщений: 83 Зарегистрирован: 25.02.2013 21:52 |
ЗЫ Массив да, будет тормозить (при таком объёме). - вот вотДля постраничной навигации ещё же надо подсчитать общее количество на каких то условиях отсева ненужных строк. spiker Ну у меня то не миллион строк, конечно, но надо всегда на такое рассчитывать)) Ну а мне, действительно нужно для работы) Интернет магазин, грубо говоря, есть типы и в них продукты, и надо выводить все это подряд, но в каждом типе выводить не более 8 первых продуктов. И все это с страничной навигацией, которая зависит именно от количества продуктов. |
|
|
Razor |
Опубликовано 08.10.2014 14:12
|
![]() Администратор ![]() Группа поддержки ![]() Сообщений: 508 Зарегистрирован: 20.08.2010 15:55 |
Ну чувак ты и наворотил..
Не благодари:) p/s но предыдущее решение выглядит круто.. Изменил(а) Razor, 08.10.2014 14:21 Sr. Software developer
plesk.com |
|
|
grungestranger |
Опубликовано 08.10.2014 14:32
|
![]() Пользователь ![]() Сообщений: 83 Зарегистрирован: 25.02.2013 21:52 |
Razor написал: Ну чувак ты и наворотил..
Не благодари:) p/s но предыдущее решение выглядит круто.. Этот запрос выбирает совсем не то, о чем здесь говорилось)) Его результат type----group_concat(distinct id) 4--------10 3--------9,8, 2--------6,5, 1--------3,2, |
|
|
Razor |
Опубликовано 08.10.2014 15:00
|
![]() Администратор ![]() Группа поддержки ![]() Сообщений: 508 Зарегистрирован: 20.08.2010 15:55 |
Всё правильно, во второй колонке как раз айдишники, а в первой группа к которой они принадлежат. Дальше юзаешь explode(',',$id); и получаешь собственно айдишники.. Объединено 08.10.2014 15:25: Чтоб было ещё более наглядно... Запрос : SET SESSION group_concat_max_len = 2; select type, group_concat(distinct id) as ids from test GROUP BY type DESC;
На выходе получим массив ключ(тип) => значение(массив айдишников) Вот пруф, тестил, всё работает. Выглядит гораздо более лаконично и работает не менее быстро. А вообще если вы используете подобные запросы, в первую очередь задайте себе вопрос, возможно в вашем приложении неправильно построена структура базы данных или логика работы приложения, т.к. подобные конструкции лучше обходить стороной. Изменил(а) Razor, 08.10.2014 15:51 Sr. Software developer
plesk.com |
|
|
grungestranger |
Опубликовано 08.10.2014 15:58
|
![]() Пользователь ![]() Сообщений: 83 Зарегистрирован: 25.02.2013 21:52 |
Razor Задача была получить то, что написано в первом посте, без использования php. Во-вторых твой вариант нерабочий Потому что нам нужно получить первые 2 строки (в нашем случае по id) для каждого типа, у тебя же выводятся не первые. Чтобы в любом случае выводились первые, нужен подзапрос, и выглядеть будет так: SET SESSION group_concat_max_len = 2; SELECT type1, group_concat(id) FROM ( SELECT t1.type AS type1, id FROM t1 ORDER BY id ) temp_table GROUP BY type1 ORDER BY type1 Во вторых: group_concat_max_len задает максимальную длину строки ты пробовал менять group_concat_max_len = 2 ? что выводит? полную чушь в третьих максимальная длина этой получено строки не может быть длиннее 1024 символа Изменил(а) grungestranger, 08.10.2014 16:08 |
|
|
Razor |
Опубликовано 08.10.2014 16:03
|
![]() Администратор ![]() Группа поддержки ![]() Сообщений: 508 Зарегистрирован: 20.08.2010 15:55 |
Почему не рабочий то? Давай на пальцах.. Смотри без использования php.. структура таблицы запрос Внимательно посмотри на структуру таблицы, на айдишники и на порядок их вывода на 2 сриншоте(1,2,4,5,8,9). Выводятся по порядку и как раз первые два. Получаю я их без php, как видишь.. меняю max_len... смотрим... вуаля, не полная чушь.. пруф Изменил(а) Razor, 08.10.2014 16:11 Sr. Software developer
plesk.com |
|
|
grungestranger |
Опубликовано 08.10.2014 16:11
|
![]() Пользователь ![]() Сообщений: 83 Зарегистрирован: 25.02.2013 21:52 |
Ты получаешь только id-шники, да и то, ты не сможешь получать уже ничего когда id станут двухзначными или трехзначными, в конце остаются запятые. А надо получать строки, а не только id. Внимательно посмотри на структуру таблицы, на айдишники и на порядок их вывода на 2 сриншоте(1,2,4,5,8,9). Выводятся по порядку и как раз первые два. если таблица будет перемешена, то ты будешь получать не первые значения)) меняю max_len... смотрим... вуаля, не полная чушь.. пруф ну и что это дало, ты поставил 1000, а ты поставь 3, и чтобы было по 3 значения, и учитывая, что значения могут быть и двухзначными и трехзначными. |
|
Поделиться этой темой | |
Социальные закладки: |
![]() ![]() ![]() ![]() ![]() ![]() |
URL: | |
BBcode: | |
HTML: |
Страница 1 из 2: 12
Перейти на форум: |