[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Узнать id до и после записи
seine
Есть таблица. Как бы ее показать?.. Хм, тут нельзя таблицу построить? Ну ладно, сделаю наглядной подручныйми средствами


photo_id name pos

13 chair 2
8
hrust 3
11
shckrum 4
1
ballerun 5
22
holoe 6


По-моему неплохо :-) Записи упорядоченны по значению поля pos (позиция), для наглядности и понятия сложности задачи.
Итак, меня интересует фотография с именем shckrum (я думаю вас тоже, особенно если он голый ;-) , а точнее я не знаю названия, у меня есть просто ее id, т.е. в данном случае 11.
Возможно ли зная лишь photo_id получить название этой фотографии (поле name) и значения photo_id, которые находятся до и после (упорядоченно все по полю pos, как в примере)?

В данном случае зная, что photo_id = 11, я мечтаю получить таблицу

name prev_id next_id

shckrum 8 1


Это вообще возможно при такой структуре таблицы?

Просто я посчитал, что одним запросом это делать оптимальней. Или все же лучше делать 3 (или 2, это как получится), чтобы узнать сначала название фотографии, потом photo_id предыдущей, а потом следующей?



Спустя 17 минут, 37 секунд (13.01.2010 - 20:00) VolCh написал(а):
По-моему, возможно, но запрос будет трех или более этажным. А "почему-то" часто такие запросы выполняются намного медленнее трех обычных

Спустя 7 минут, 40 секунд (13.01.2010 - 20:07) seine написал(а):
Ясн. Просто в книжке Кузнецова Максима прочитал, что все, что может делать средствами БД, должно делаться средствами БД. И что чем меньше запросов, тем лучше. Вот и решил :-)

Спустя 2 минуты, 58 секунд (13.01.2010 - 20:10) VolCh написал(а):
Это тема холиваров, всё или не всё smile.gif

Спустя 21 минута, 27 секунд (13.01.2010 - 20:32) glock18 написал(а):
DIII
ты не пробовал случаем в sql генерировать html или переложить на него рендеринг страницы? С высказыванием я, пожалуй, соглашусь, но не надо понимать его превратно.

Спустя 1 час, 30 минут, 52 секунды (13.01.2010 - 22:03) sergeiss написал(а):
Цитата (DIII @ 13.01.2010 - 21:07)
Просто в книжке Кузнецова Максима прочитал, что все, что может делать средствами БД, должно делаться средствами БД.

Вобщем-то, он прав. Я тоже так стараюсь делать. По возможности smile.gif
Цитата (DIII @ 13.01.2010 - 20:42)
Возможно ли зная лишь photo_id получить название этой фотографии (поле name) и значения photo_id, которые находятся до и после (упорядоченно все по полю pos, как в примере)?

Это не просто... А очень просто smile.gif

1. Делаем выборку только 1-го значения, с позицией, большей указанной.
2. Делаем выборку только 1-го значения, с позицией, меньше указанной.
3. Объединяем эти 2 выборки в одной. Или в одной строке, или через union.

А теперь проделай это сам, и ты получишь искомый результат smile.gif Только не проси написать код. Не буду.
Запрос будет достаточно простой, хотя и 2-х этажный.

Спустя 10 часов, 52 минуты, 24 секунды (14.01.2010 - 08:55) sergeiss написал(а):
Цитата (Семён @ 14.01.2010 - 00:52)
Нука покажи, что-то сижу 1 запросом не могу сделать.

Сначала пусть автор вопроса подумает... Да и ты подумай smile.gif Алгоритм я описал.

Спустя 45 минут, 4 секунды (14.01.2010 - 09:40) sergeiss написал(а):
Цитата (Семён @ 14.01.2010 - 10:34)
Твой алгоритм неверен.

1) У тебя позиция заранее неизвестна. (известен лишь ID)
2) У тебя позиция заранее неизвестна. (известен лишь ID)
3) Очевидно.


3 - согласен smile.gif
1-2 - категорически не согласен! Позиция по заданному id вычисляется "на счет раз".
Поэтому - мой алгоритм верен smile.gif

Спустя 10 минут, 24 секунды (14.01.2010 - 09:50) sergeiss написал(а):
Цитата (Семён @ 14.01.2010 - 10:41)
Спорить не буду, пока не покажешь останусь при своём мнении ибо я упрям как осёл.

ОК, ждём, пока топик-стартер подумает и выдаст своё вариант решения....

А ты лучше не "упирайся", как маленькое благородное животное wink.gif, а подумай, как получить позицию, зная id.

Спустя 13 минут, 39 секунд (14.01.2010 - 10:04) sergeiss написал(а):
Цитата (Семён @ 14.01.2010 - 11:01)
Ты мну просто ответь на вопрос пожалуйста как из SQL1 передать значение через UNION в SQL2?

Никак. И зачем это делать???

Спустя 15 минут, 59 секунд (14.01.2010 - 10:20) sergeiss написал(а):
Еще раз повторяю: ничего никуда передавать не нужно! Надо просто выполнить эту процедуру дважды. Времени она займет ноль целых и хрен тысячных секунды.

Спустя 25 минут, 12 секунд (14.01.2010 - 10:45) sergeiss написал(а):
Цитата (Семён @ 14.01.2010 - 11:21)
ну что за развод поцелуя как на первом свидании

Однако, образное у тебя мышление wink.gif Хрень в том, что если человек что-то находит сам, используя подсказки, то он это запоминает намного лучше, чем ему подскажут дадут прямой ответ. Ну, если ты так настаиваешь...

ОК, пусть имя таблицы table1, а поля photo_id, name, pos
Свернутый текст
select
(select name from table1 where photo_id=11) as name,
(
select pos from table1 where pos<(select pos from table1 where photo_id=11) order by pos desc limit 1 offset 0 ) as lt_pos,
(
select pos from table1 where pos>(select pos from table1 where photo_id=11) order by pos limit 1 offset 0 ) as gt_pos


Полученные результаты надо анализировать на "нулёвость" позиций (null), чтобы определить, что находимся в самом низу или в самом верху списка.

Спустя 9 минут, 11 секунд (14.01.2010 - 10:54) seine написал(а):
Ого вы тут и написали :-) Ок, алгоритм понял, щас буду думать, только вы тут не подсказывайте мне ничего.
Ждите.

Спустя 54 секунды (14.01.2010 - 10:55) seine написал(а):
Блин, sergeiss! Ты написал! Но один фиг, я не буду смотреть код :-) Хочу сам разобраться ;-)

Спустя 2 минуты, 56 секунд (14.01.2010 - 10:58) sergeiss написал(а):
Цитата (DIII @ 14.01.2010 - 11:55)
Блин, sergeiss! Ты написал!

А ты закрой глаза и отойди laugh.gif

Цитата (DIII @ 14.01.2010 - 11:55)
Хочу сам разобраться ;-)

Хорошее желание. Действуй, потом сравним.

PS. "Свой" вариант решения я свернул, чтобы он не "бросался в глаза".

Спустя 25 минут, 1 секунда (14.01.2010 - 11:23) sergeiss написал(а):
Семён - на Постгре можно сделать функцию, в которой можно всё это наоптимизировать; может быть, это можно и в MySQL, я не могу сказать.
Но всё равно будет селектов только на 1 меньше.
И, к тому же, реальных селектов (обращающихся к БД) тут только 5, а 6-й просто объединяет всё.

Спустя 2 минуты, 1 секунда (14.01.2010 - 11:25) glock18 написал(а):
хотите еще каплю дегтя? smile.gif я так понимаю, что проблема из разряда "найти след/пред фотку". а, случаем, не надо, чтобы для последней возвращалась первая в качестве следующей?

PS: да, в mysql можно написать "хранимку".

Спустя 7 минут, 38 секунд (14.01.2010 - 11:33) sergeiss написал(а):
Цитата (glock18 @ 14.01.2010 - 12:25)
а, случаем, не надо, чтобы для последней возвращалась первая в качестве следующей?

"Как два пальца об асфальт" biggrin.gif

Спустя 17 минут, 8 секунд (14.01.2010 - 11:50) glock18 написал(а):
Я в курсе, что это просто. Только получится уже запросов вложенных ой-ой-ой.

ТСу: еще раз "не понимай слова того дядьки превратно, они значит совсем иное".

Спустя 12 минут, 50 секунд (14.01.2010 - 12:03) sergeiss написал(а):
Семён - а теперь заходим в таблицу, видим там (например) позиции 1, 2, 4, 7, 9, 10 и пытаемся найти по твоем запросу "соседей" для позиции 7.
А так может получиться легко и просто, ежели удалять отдельные строки.

Спустя 21 секунда (14.01.2010 - 12:03) seine написал(а):
Не читая того, что было выше.

Ну вот, мой запрос (страшно видеть! может лучше было бы за три подхода все делать?)


(
SELECT `id_photo`, `name`, `pos`
FROM `photo`
WHERE `pos` < (SELECT `pos` FROM `photo` WHERE `id_photo` = 11) ORDER BY `pos` DESC LIMIT 1
)

UNION

(
SELECT `id_photo`, `name`, `pos`
FROM `photo`
WHERE `pos` > (SELECT `pos` FROM `photo` WHERE `id_photo` = 11) ORDER BY `pos` ASC LIMIT 1
)

UNION

(
SELECT `id_photo`, `name`, `pos`
FROM `photo`
WHERE `id_photo` = 11
)

ORDER BY `pos`



В итоге для данного примера получаю таблицу (эх... опять придется полчаса пробелами позиции значений подгонять...)



photo_id name pos

8 hrust 3
11
shckrum 4
1
ballerun 5



Это, конечно, хорошо, но
во-первых, я считаю что мой запрос далеко не оптимальный :-(
во-вторых, полчуенная таблица не так удобна (и содержит лишнии данные (имена соседних картинок и значения поля поз)), как



name prev_id next_id

shckrum 8 1



Ну вот, собсно, что я придумал :-)

Спустя 5 минут, 22 секунды (14.01.2010 - 12:09) sergeiss написал(а):
DIII - то, что сам - это очень хорошо! wink.gif

А теперь сравни твой запрос и мой, и найди между ними разницу: почему у меня всё в одну строку выйдет, как ты и хотел, и почему у тебя 3 строки.

И в итоге ты получишь и знания, и результат.

Семён! Работаем с реальной таблицей, в которой никто не будет пересчитывать позиции после удаления строк tongue.gif
Но ты думай, думай! В любом случае это только на пользу.

Спустя 58 секунд (14.01.2010 - 12:10) seine написал(а):
Цитата (sergeiss @ 14.01.2010 - 07:45)
select
(select name from table1 where photo_id=11) as name,
(
select pos from table1 where pos<(select pos from table1 where photo_id=11) order by pos desc limit 1 offset 0 ) as lt_pos,
(
select pos from table1 where pos>(select pos from table1 where photo_id=11) order by pos limit 1 offset 0 ) as gt_pos</span>

Ха! Всё гениальное просто! Блин, а я в дебри полез :-)

Спустя 3 минуты, 40 секунд (14.01.2010 - 12:13) sergeiss написал(а):
Цитата (Семён @ 14.01.2010 - 13:07)
Выдаст тоже самое

И насколько правильное? smile.gif

Цитата (DIII @ 14.01.2010 - 13:10)
Ха! Всё гениальное просто! Блин, а я в дебри полез :-)

Да у тебя похожее решение, только ты выводишь в несколько строк.

Спустя 7 минут, 8 секунд (14.01.2010 - 12:20) sergeiss написал(а):
Семён - ну так сделай smile.gif Кто же тебе мешает? И я не понял, хуже чего моё решение?
Существенно: правильность решения нужно определять не по количеству селектов (у меня их, кстати, 5, а не 6 - потому что только 5 обращаются к БД), а по правильности ответа и скорости выполнения.
Если сделаешь решение, которое требует меньше селектов, и будет еще и правильным - вэлкам! Это будет очень хорошо.

Спустя 17 минут, 36 секунд (14.01.2010 - 12:38) seine написал(а):
sergeiss, никогда не видел такой контрукции


select
(select name ...) as name
(select pos ...) as lt_pos
(select pos ...) as gt_pos


А если в подзапросах будет не одно поле выбирать, то работать такая контрукция не будет? Например



select
(select photo_id, name ...)
(
select pos ...) as lt_pos
(select pos ...) as gt_pos


Чтоб получить таблицу типа

photo_id name lt_pos gt_pos


И еще (просто интересно :-), как расшифровываются "lt" и "gt" в "lt_pos" и "gt_pos"?

Спустя 18 минут, 37 секунд (14.01.2010 - 12:57) glock18 написал(а):
Цитата (Семён @ 14.01.2010 - 09:16)
В данной ситуации 1 select

ну-ну, давай, покажи smile.gif

Спустя 18 минут, 20 секунд (14.01.2010 - 13:15) glock18 написал(а):
не канает, сказали же. за целостностью то следить тоже надо. это не такая уж проблема, но если тебе так охота - покажи update которым будешь это делать. я не говорю даже о том, что если он не будет выполнен (или выполнен неверно), то select будет выдавать лажу.

Спустя 10 минут, 17 секунд (14.01.2010 - 13:25) glock18 написал(а):
Семён
explain читал запроса? smile.gif строк будет 5 - лучше, чем в предложенном выше, но не намного.

второй запрос вообще ахтунг - это надо знать количество строк до текущей.

кстати запрос будет работать неверно без order by pos в каждом из селектов.
вообще не понимаю, почему каждый из вас использует order by + limit. это намного медленнее, чем min, max. посмотри explain своего запроса, перепиши его нормально без limit 3 (это ужос) только с использованием min, max и сравни его explain с тем. получится, насколько я представляю, адекватный запрос. оба предложенные выше пока мало чем лучше трех простых.

Спустя 2 минуты, 54 секунды (14.01.2010 - 13:28) Семён написал(а):
боше не отпишусь. это было дело принципа. ph34r.gif

Спустя 14 минут, 31 секунда (14.01.2010 - 13:43) seine написал(а):
Цитата (glock18 @ 14.01.2010 - 10:25)
вообще не понимаю, почему каждый из вас использует order by + limit. это намного медленнее, чем min, max.

Хм, действительно, спасибо за совет :-)

Спустя 19 минут, 10 секунд (14.01.2010 - 14:02) glock18 написал(а):
Семён
дело твое

Спустя 25 минут, 20 секунд (14.01.2010 - 14:27) sergeiss написал(а):
Цитата (glock18 @ 14.01.2010 - 14:25)
вообще не понимаю, почему каждый из вас использует order by + limit. это намного медленнее, чем min, max

Ну дык... А ты на что тут? Вот и подсказывай, как оптимизировать, коли видишь это smile.gif
Быстрый ответ:

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