[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: auto_increment поля при определенном id
testr
всем привет. прошу вас помочь в решение данной задачи.

есть таблица, в которой например 4 поля

id | idm | text | count

Мне нужно сделать следующее. Выбрать все строки где idm равен например 5 и, отсортировав записи по возрастанию id, увеличивать count от 1 на единицу, то есть как бы auto_increment, но для каждого idm он начинается с начала. Можете пожалуйста подсказать как сделать это с наименьшими затратами ресурсов?



Спустя 5 минут, 26 секунд (3.04.2012 - 23:15) Placido написал(а):
Цитата (testr @ 3.04.2012 - 22:09)
Выбрать все строки где id (первичный ключ) равен например 5...

В смысле, "все строки"? Если id - первичный ключ, то каждому id будет соответствовать ровно одна запись (строка).

Спустя 46 секунд (3.04.2012 - 23:15) testr написал(а):
Ой, заработался, id тут не при чем, кроме него еще одно поле, не первичный ключ, так вот, по нему необходимо ориентироваться. Исправил первый пост.

Спустя 1 минута, 36 секунд (3.04.2012 - 23:17) I++ написал(а):
Цитата
Выбрать все строки где id (первичный ключ) равен например 5.

Первичный ключ должен быть уникальным.

Цитата
увеличивать count от 1 на единицу


1 ляля 1
3 руру 2
6 няня 3
7 ляля 4

Если требуется так, то это не правильно. Нужно будет перестраивать значение count. Если база вырастет, это будет жутко тормозить.

Спустя 1 минута, 56 секунд (3.04.2012 - 23:19) testr написал(а):
Операция будет производиться по крону, не при каждом запросе.

Спустя 6 минут, 3 секунды (3.04.2012 - 23:25) I++ написал(а):
Было бы не плохо расписать логику работы, возможно логика не правильная.

Спустя 1 минута, 19 секунд (3.04.2012 - 23:26) testr написал(а):
Мне просто нужно определить на какой странице находится комментарий при запросе на его айди и айди материала, дело в том что при удалении комментарии смещаются со страницы... а каждый раз селектить кол-во комментариев ДО запрашиваемого это думаю слишком накладно...

Спустя 8 минут, 6 секунд (3.04.2012 - 23:34) Placido написал(а):
Если я правильно понял, то
SELECT `table`.`id`, `table`.`text`, `table`.`idm`, @i := @i + 1 AS `count` 
FROM `table`, (SELECT @i:=0) AS `var` WHERE `table`.`idm` = 5
ORDER BY `table`.`id`;
где `table` - имя таблицы.

Спустя 4 минуты, 37 секунд (3.04.2012 - 23:39) testr написал(а):
Такс, это мы тут типа селектим записи где в каждой новой увеличивается count на единицу? Неплохо, но это поле в таблице уже должно быть под инкрементом, то есть с селектом жонглировать не надо. Можете переделать этот запрос чтобы был не селект, а апдейт одним запросом поля count всех записей с idm 5 ? А то вариант с селектом и последующим апдейтом не особо предпочтителен...

Спустя 14 минут, 58 секунд (3.04.2012 - 23:54) I++ написал(а):
Цитата (testr @ 4.04.2012 - 00:26)
Мне просто нужно определить на какой странице находится комментарий при запросе на его айди и айди материала, дело в том что при удалении комментарии смещаются со страницы... а каждый раз селектить кол-во комментариев ДО запрашиваемого это думаю слишком накладно...

таблица будет состоять из `id` (первичный ключ) `text`, `page_id`

Когда пользователь захочет получить 1,2,3,4,5 страницу с коментами, он жмет на ссылку:

example.com?page_id=3&page=2

Шаг страниц произвольный, в данном примере будет 10

SELECT `id`, `text` FROM `comments` WHERE `page_id` = 3 LIMIT 11,21

Выведет все комментарии для 2 страницы

example.com?page_id=3&page=6

SELECT `id`, `text` FROM `comments` WHERE `page_id` = 3 LIMIT 61,71

Выведет все комментарии для 6 страницы

Это требовалось?


Спустя 2 минуты, 29 секунд (3.04.2012 - 23:56) Placido написал(а):
UPDATE `table` 
INNER JOIN
(SELECT `table`.`id`, @i := @i + 1 AS `count`
FROM `table`, (SELECT @i:=0) AS `var`
WHERE `table`.`idm` = 5
ORDER BY `table`.`id`) AS `temp`
USING(`id`)
SET `table`.`count` = `temp`.`count`;

----
UPD
Убрал лишнее (`table`.`text`, `table`.`idm` - они здесь роли не играют).

Спустя 4 минуты, 43 секунды (4.04.2012 - 00:01) testr написал(а):
I++, это конечно "гениально", но что если с 3 страницы будут удалены все комментарии, тогда что? И не думаю что это будет красиво смотреться, на одной странице 1 комментарий, на другой 10, а на третьей вообще ноль. И зачем еще LIMIT делать для page_id? О_о

Placido, нда уж, ну разве что с иннер джоин, типа одним запросом xD

ну все равно спасибо большое, это всетаки решение, и думаю не самое худшее smile.gif
в общем весьма благодарен. Жаль что нельзя апдейтом без селекта конечно...

Спустя 14 минут, 36 секунд (4.04.2012 - 00:16) I++ написал(а):
Цитата (testr @ 4.04.2012 - 01:01)
I++, это конечно "гениально", но что если с 3 страницы будут удалены все комментарии, тогда что? И не думаю что это будет красиво смотреться, на одной странице 1 комментарий, на другой 10, а на третьей вообще ноль. И зачем еще LIMIT делать для page_id? О_о

Placido, нда уж, ну разве что с иннер джоин, типа одним запросом xD

ну все равно спасибо большое, это всетаки решение, и думаю не самое худшее smile.gif
в общем весьма благодарен. Жаль что нельзя апдейтом без селекта конечно...


Чтобы узнать какое количество делать 1,2,3,4,5 страниц с коментами используй:



SELECT SQL_CALC_FOUND_ROWS `id`, `text` FROM `comments` WHERE `page_id` = 3 LIMIT 61,71

Потом смотришь чему равен SQL_CALC_FOUND_ROWS например 70 и выводишь количество страниц 1,2,3,4,5,6,7

Если комменты удалятся все например на 4 странице, то станет значение SQL_CALC_FOUND_ROWS 60, а коменты сместятся вот так:

1,2,3,4,5,6,7 удаляем 4

1,2,3,5,6,7

т.е будут идти коменты с 3 страницы, а потом с 5, но выводится будет так:

1,2,3,4,5,6

Потому что мы формируем числа отталкиваясь от числа SQL_CALC_FOUND_ROWS

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

Спустя 14 минут, 59 секунд (4.04.2012 - 00:31) testr написал(а):
SQL_CALC_FOUND_ROWS это как раз то о чем я сказал

>а каждый раз селектить кол-во комментариев ДО запрашиваемого это думаю слишком накладно...

ресурсов при селекте необходимо затрачивать меньше.

Спустя 6 минут, 2 секунды (4.04.2012 - 00:37) I++ написал(а):
Если коментов будет по 60 тысяч для 1 страницы, тогда да.

Но, можно по другому:

Table: comments_count
Rows: page_id count

Вот и счетчик, через inner join объединишь заместо SQL_CALC_FOUND_ROWS

При добавлении комента увеличиваешь число count для страницы, при удалении уменьшаешь соответственно

Спустя 11 часов, 15 минут, 11 секунд (4.04.2012 - 11:52) testr написал(а):
Ну опять же, что если на странице будет 0 комментариев, тогда снова придется жонглировать с id страниц, некоторые удалять и снова выстраивать все четко в порядке возрастания. Не, это еще больше жонглирований. Схему для себя я уже в общем то выработал.

Спустя 25 минут, 18 секунд (4.04.2012 - 12:17) I++ написал(а):
Цитата (testr @ 4.04.2012 - 12:52)
Ну опять же, что если на странице будет 0 комментариев, тогда снова придется жонглировать с id страниц, некоторые удалять и снова выстраивать все четко в порядке возрастания. Не, это еще больше жонглирований. Схему для себя я уже в общем то выработал.

Цитата
тогда снова придется жонглировать с id страниц


Эта фраза не несет смысловой нагрузки иными словами, это не объясняет почему придется:
Цитата

некоторые удалять и снова выстраивать все четко в порядке возрастания


Ты объясни, чего сделать хочешь. С комментами есть 2 варианта, которые я уже описал.

Спустя 6 минут, 55 секунд (4.04.2012 - 12:24) testr написал(а):
Ну если на странице с пэйдж айди окажется 0 комментариев, что ты будешь делать? Необходимо будет удалять эту страницу, а все последующие перестраивать (айди страницы - 1).

Placido, можешь пожалуйста модифицировать запрос? Для сохранения ресурсов мне необходимо при апдейте указывать что mid такой-то но id больше чем данное значение (например, 123), при этом нужно отталкиваться от count, полученном в первой строке - 1, а потом уже спокойно делать инкремент и апдейт. Это просто необходимо для того чтобы если комментарий был удален где-то на предпоследней странице не пересобирать все комментарии, а только те, которые следуют после удаленного.

Спустя 23 минуты, 33 секунды (4.04.2012 - 12:48) I++ написал(а):
Цитата
Ну если на странице с пэйдж айди окажется 0 комментариев, что ты будешь делать?


Не буду выводить комментарии, напишу, что комментариев нет, но контент страницы покажу.

Спустя 5 минут, 33 секунды (4.04.2012 - 12:53) Placido написал(а):
Не совсем понимаю вопрос. Если комментарий с id = 123 удаляется, и нужно изменить count только для комментариев, которые идут после id = 123, где idm = 5, то почему бы его не сделать обычный апдейт
UPDATE `table` SET `count` = `count` - 1 
WHERE `id` > 123 AND `idm` = 5;

Извини, вникать глубже сейчас времени нет.

Спустя 3 часа, 44 минуты, 13 секунд (4.04.2012 - 16:37) testr написал(а):
Placido, дело в том что удаленных комментариев может быть много и они могут быть везде разбросаны, поэтому я сначала выбираю удаленный комментарий с наименьшим idm, и затем просто пересобираю все что идет дальше для этого idm.

Подскажи пожалуйста еще одну вещь. Как проинсертить новую строку таблицу чтобы новое значение count было на единицу больше предыдущего? Сначала селектить а потом инсертить - этот вариант мне не нравится, вдруг будут "коллизии" когда будет добавляться 2 комментария с одинаковым count. Может как-то в один запрос это объединить так чтоб точно не совпадали count при инсерте.

Спустя 26 минут, 9 секунд (4.04.2012 - 17:04) Placido написал(а):
INSERT INTO `table` (`поле1`, `поле2`, `count`) 
SELECT 'значение поля1', 'значение поля2', MAX(`count`) + 1
FROM `table`
WHERE `idm` = 'чему оно там равно';


Извини, вникать времени нет - я занят.

Спустя 6 часов, 22 минуты, 30 секунд (4.04.2012 - 23:26) testr написал(а):
хм, ну хотя бы как освободишься посмотришь, что там сделать можно?

p.s. насчет инсерта, уточни пожалуйста, как там свои поля добавлять, а то получается что только с селекта идет инсерт всех предыдущих значений...

Спустя 9 минут, 9 секунд (4.04.2012 - 23:35) Placido написал(а):
С селекта идет только MAX(`count`) + 1 - чтобы получить максимальный `count` + 1, а в 'значение поля1', 'значение поля2' подставляй то, что хочешь внести в `поле1`, `поле2`.

Спустя 14 часов, 13 минут, 39 секунд (5.04.2012 - 13:49) testr написал(а):
слушай а в этом твое запросе можно ведь вместо @i:=0 подставить свое число и после апдейта дописать условие, что, мол where id > 123

и в селекте дописать WHERE id > 123
тогда я так полагаю можно вначале выполнить селект, получить этот самый id ну и потом просто подставить числа в запрос. нужно будет испробовать.

Спустя 1 час, 17 минут, 11 секунд (5.04.2012 - 15:06) Placido написал(а):
Условие прописать можно, я просто не совсем понимаю смысл задачи, а времени у меня вникать сейчас нет. А вообще, что-то здесь не так. Если идет речь о постраничном выводе, то есть стандартные подходы. I++ уже описывал логику.

Спустя 4 дня, 7 часов, 20 минут, 32 секунды (9.04.2012 - 22:27) testr написал(а):
Placido, а можешь пожалуйста переделать под запрос вида

INSERT INTO table SET field1 = '$field', field2 = '$field2'

и еще запрос на count может вернуть 0 строк для данного idm, тогда мне нужно записать число 1, как посоветуешь это решить?

Спустя 1 час, 19 минут, 37 секунд (9.04.2012 - 23:46) Placido написал(а):
SET - это если делаешь UPDATE, а не INSERT (как минимум INSERT ... ON DUPLICATE KEY UPDATE ...).

Если запрос может вернуть 0, а нужно минимум 1, можно воспользоваться функцией (да-да, это функция) IF, например:
SELECT IF(COUNT(`idm`) > 0, COUNT(`idm`), 1) AS `count`
FROM `table`
WHERE `что-то` = `чему-то` AND ... OR ... и т.д.;

Спустя 4 дня, 17 часов, 52 минуты, 11 секунд (14.04.2012 - 17:38) testr написал(а):
нет, я имел в виду при инсерте проверить...

если я пробую if добавить в селект при инсерте, если при селекте нет данных, оно чего-то не вставляет строку

интересно, что при запросе такого вида:

INSERT INTO table (id,somefield,count) 
SELECT NULL, '$somefieldvar',IF(MAX(`count`), MAX(`count`)+1, 1)
FROM table
WHERE
idm = '123'


если по данному idm нету строк, оно вставляет 1

а если запрос следующего вида:

INSERT INTO table (id,somefield,count)
SELECT NULL, '$somefieldvar',IF(`count`, `count`+1, 1)
FROM table
WHERE
idm = '123' ORDER BY idm desc LIMIT 1


если 0 строк возвращается то инсерт не выполняется... но второй запрос менее затратный в плане производительности? как посоветуете его переделать чтоб заработал?
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.