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 написал(а):
Это тема холиваров, всё или не всё
Спустя 21 минута, 27 секунд (13.01.2010 - 20:32) glock18 написал(а):
DIII
ты не пробовал случаем в sql генерировать html или переложить на него рендеринг страницы? С высказыванием я, пожалуй, соглашусь, но не надо понимать его превратно.
ты не пробовал случаем в sql генерировать html или переложить на него рендеринг страницы? С высказыванием я, пожалуй, соглашусь, но не надо понимать его превратно.
Спустя 1 час, 30 минут, 52 секунды (13.01.2010 - 22:03) sergeiss написал(а):
Цитата (DIII @ 13.01.2010 - 21:07) |
Просто в книжке Кузнецова Максима прочитал, что все, что может делать средствами БД, должно делаться средствами БД. |
Вобщем-то, он прав. Я тоже так стараюсь делать. По возможности
Цитата (DIII @ 13.01.2010 - 20:42) |
Возможно ли зная лишь photo_id получить название этой фотографии (поле name) и значения photo_id, которые находятся до и после (упорядоченно все по полю pos, как в примере)? |
Это не просто... А очень просто
1. Делаем выборку только 1-го значения, с позицией, большей указанной.
2. Делаем выборку только 1-го значения, с позицией, меньше указанной.
3. Объединяем эти 2 выборки в одной. Или в одной строке, или через union.
А теперь проделай это сам, и ты получишь искомый результат Только не проси написать код. Не буду.
Запрос будет достаточно простой, хотя и 2-х этажный.
Спустя 10 часов, 52 минуты, 24 секунды (14.01.2010 - 08:55) sergeiss написал(а):
Цитата (Семён @ 14.01.2010 - 00:52) |
Нука покажи, что-то сижу 1 запросом не могу сделать. |
Сначала пусть автор вопроса подумает... Да и ты подумай Алгоритм я описал.
Спустя 45 минут, 4 секунды (14.01.2010 - 09:40) sergeiss написал(а):
Цитата (Семён @ 14.01.2010 - 10:34) |
Твой алгоритм неверен. 1) У тебя позиция заранее неизвестна. (известен лишь ID) 2) У тебя позиция заранее неизвестна. (известен лишь ID) 3) Очевидно. |
3 - согласен
1-2 - категорически не согласен! Позиция по заданному id вычисляется "на счет раз".
Поэтому - мой алгоритм верен
Спустя 10 минут, 24 секунды (14.01.2010 - 09:50) sergeiss написал(а):
Цитата (Семён @ 14.01.2010 - 10:41) |
Спорить не буду, пока не покажешь останусь при своём мнении ибо я упрям как осёл. |
ОК, ждём, пока топик-стартер подумает и выдаст своё вариант решения....
А ты лучше не "упирайся", как маленькое благородное животное , а подумай, как получить позицию, зная 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) |
ну что за развод поцелуя как на первом свидании |
Однако, образное у тебя мышление Хрень в том, что если человек что-то находит сам, используя подсказки, то он это запоминает намного лучше, чем ему
ОК, пусть имя таблицы 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! Ты написал! |
А ты закрой глаза и отойди
Цитата (DIII @ 14.01.2010 - 11:55) |
Хочу сам разобраться ;-) |
Хорошее желание. Действуй, потом сравним.
PS. "Свой" вариант решения я свернул, чтобы он не "бросался в глаза".
Спустя 25 минут, 1 секунда (14.01.2010 - 11:23) sergeiss написал(а):
Семён - на Постгре можно сделать функцию, в которой можно всё это наоптимизировать; может быть, это можно и в MySQL, я не могу сказать.
Но всё равно будет селектов только на 1 меньше.
И, к тому же, реальных селектов (обращающихся к БД) тут только 5, а 6-й просто объединяет всё.
Но всё равно будет селектов только на 1 меньше.
И, к тому же, реальных селектов (обращающихся к БД) тут только 5, а 6-й просто объединяет всё.
Спустя 2 минуты, 1 секунда (14.01.2010 - 11:25) glock18 написал(а):
хотите еще каплю дегтя? я так понимаю, что проблема из разряда "найти след/пред фотку". а, случаем, не надо, чтобы для последней возвращалась первая в качестве следующей?
PS: да, в mysql можно написать "хранимку".
PS: да, в mysql можно написать "хранимку".
Спустя 7 минут, 38 секунд (14.01.2010 - 11:33) sergeiss написал(а):
Цитата (glock18 @ 14.01.2010 - 12:25) |
а, случаем, не надо, чтобы для последней возвращалась первая в качестве следующей? |
"Как два пальца об асфальт"
Спустя 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 - то, что сам - это очень хорошо!
А теперь сравни твой запрос и мой, и найди между ними разницу: почему у меня всё в одну строку выйдет, как ты и хотел, и почему у тебя 3 строки.
И в итоге ты получишь и знания, и результат.
Семён! Работаем с реальной таблицей, в которой никто не будет пересчитывать позиции после удаления строк
Но ты думай, думай! В любом случае это только на пользу.
А теперь сравни твой запрос и мой, и найди между ними разницу: почему у меня всё в одну строку выйдет, как ты и хотел, и почему у тебя 3 строки.
И в итоге ты получишь и знания, и результат.
Семён! Работаем с реальной таблицей, в которой никто не будет пересчитывать позиции после удаления строк
Но ты думай, думай! В любом случае это только на пользу.
Спустя 58 секунд (14.01.2010 - 12:10) seine написал(а):
Цитата (sergeiss @ 14.01.2010 - 07:45) |
select |
Ха! Всё гениальное просто! Блин, а я в дебри полез :-)
Спустя 3 минуты, 40 секунд (14.01.2010 - 12:13) sergeiss написал(а):
Цитата (Семён @ 14.01.2010 - 13:07) |
Выдаст тоже самое |
И насколько правильное?
Цитата (DIII @ 14.01.2010 - 13:10) |
Ха! Всё гениальное просто! Блин, а я в дебри полез :-) |
Да у тебя похожее решение, только ты выводишь в несколько строк.
Спустя 7 минут, 8 секунд (14.01.2010 - 12:20) sergeiss написал(а):
Семён - ну так сделай Кто же тебе мешает? И я не понял, хуже чего моё решение?
Существенно: правильность решения нужно определять не по количеству селектов (у меня их, кстати, 5, а не 6 - потому что только 5 обращаются к БД), а по правильности ответа и скорости выполнения.
Если сделаешь решение, которое требует меньше селектов, и будет еще и правильным - вэлкам! Это будет очень хорошо.
Существенно: правильность решения нужно определять не по количеству селектов (у меня их, кстати, 5, а не 6 - потому что только 5 обращаются к БД), а по правильности ответа и скорости выполнения.
Если сделаешь решение, которое требует меньше селектов, и будет еще и правильным - вэлкам! Это будет очень хорошо.
Спустя 17 минут, 36 секунд (14.01.2010 - 12:38) seine написал(а):
sergeiss, никогда не видел такой контрукции
А если в подзапросах будет не одно поле выбирать, то работать такая контрукция не будет? Например
Чтоб получить таблицу типа
И еще (просто интересно :-), как расшифровываются "lt" и "gt" в "lt_pos" и "gt_pos"?
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 |
ну-ну, давай, покажи
Спустя 18 минут, 20 секунд (14.01.2010 - 13:15) glock18 написал(а):
не канает, сказали же. за целостностью то следить тоже надо. это не такая уж проблема, но если тебе так охота - покажи update которым будешь это делать. я не говорю даже о том, что если он не будет выполнен (или выполнен неверно), то select будет выдавать лажу.
Спустя 10 минут, 17 секунд (14.01.2010 - 13:25) glock18 написал(а):
Семён
explain читал запроса? строк будет 5 - лучше, чем в предложенном выше, но не намного.
второй запрос вообще ахтунг - это надо знать количество строк до текущей.
кстати запрос будет работать неверно без order by pos в каждом из селектов.
вообще не понимаю, почему каждый из вас использует order by + limit. это намного медленнее, чем min, max. посмотри explain своего запроса, перепиши его нормально без limit 3 (это ужос) только с использованием min, max и сравни его explain с тем. получится, насколько я представляю, адекватный запрос. оба предложенные выше пока мало чем лучше трех простых.
explain читал запроса? строк будет 5 - лучше, чем в предложенном выше, но не намного.
второй запрос вообще ахтунг - это надо знать количество строк до текущей.
кстати запрос будет работать неверно без order by pos в каждом из селектов.
вообще не понимаю, почему каждый из вас использует order by + limit. это намного медленнее, чем min, max. посмотри explain своего запроса, перепиши его нормально без limit 3 (это ужос) только с использованием min, max и сравни его explain с тем. получится, насколько я представляю, адекватный запрос. оба предложенные выше пока мало чем лучше трех простых.
Спустя 2 минуты, 54 секунды (14.01.2010 - 13:28) Семён написал(а):
боше не отпишусь. это было дело принципа.
Спустя 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 |
Ну дык... А ты на что тут? Вот и подсказывай, как оптимизировать, коли видишь это