K>Так вот, Id текущей записи я знаю, а как SQL запросом получить id следующей/предыдущей записей? K>таблица довольно большая — ~900000 записей.
Ничего страшного (fetch какой то.. ) тут нет, стандартная вещь,
лежащая в основе всех смотрелок..
Достаточно хорошо знать select http://www.mysql.com/doc/ru/SELECT.html
В таких случаях принято использовать
SELECT * from <your_fucking_table>
ORDER BY Id
LIMIT 1 OFFSET <your_offset>
При переходе на следующую запись просто увеличиваешь
<your_offset> на 1 и читаешь следующую запись..
Конечно, правильнее знать не текущий id, а именно номер записи в том порядке, в кортором его смотрит пользователь.. (<your_offset>)
это и ему удобнее..
Если же вы всё таки настаиваете на Id, то вам поможет
SELECT * from <your_fucking_table>
WHERE Id > <your_fucking_id>
ORDER BY Id
LIMIT 1
K>Так вот, Id текущей записи я знаю, а как SQL запросом получить id следующей/предыдущей записей? K>таблица довольно большая — ~900000 записей.
ssm>Помоему корректней делать просто fetch
Чего-то я с утра туплю. Не подскажете как это корректно сделать в связке PHP+mySQL?
--- Если при помощи LIMIT выбираются только несколько строк, MySQL будет использовать индексы в тех некоторых случаях, когда он обычно предпочел бы делать полное сканирование таблицы.
--- Если LIMIT # используется с ORDER BY, MySQL закончит сортировку, как только найдет первые # строк, вместо того, чтобы сортировать всю таблицу.
Прошу заметить, что mySQL самая популярная база для WEB приложений, и подобные вопросы в ней давно уже апробированы и отработаны!
Здравствуйте, ssm, Вы писали:
V>Ничего страшного (fetch какой то.. ) тут нет, стандартная вещь, ssm>И что в нем страшного то?
Наверно я отвечу, уогда пойму, что именно вы имеете в виду под fetch
(т.е. для меня страшно то , что я не понимаю )
Так что был бы признателен за расширение своих горизонтов..
Здравствуйте, vvaizh, Вы писали:
V>Наверно я отвечу, уогда пойму, что именно вы имеете в виду под fetch
Получение слудующей(предыдущей — зависит от поддержки сервером bidirectional курсоров) записи из набора данных. Форма записи зависит от SQL сервера и языка(средства разработки) клиента
Лимит тут имхо не поможет. Речь идет о выборке записе согласно значениям колонки Id, как я понял. Лимит же выбирает опред. кол-во записей, к-е нужно выбрать. Поэтому при переходе на следующую запись можно просто указывать какой ид (а он, как я понял, уникален) нужен
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, vvaizh, Вы писали:
ВВ>Лимит тут имхо не поможет. Речь идет о выборке записе согласно значениям колонки Id, как я понял. Лимит же выбирает опред. кол-во записей, к-е нужно выбрать. Поэтому при переходе на следующую запись можно просто указывать какой ид (а он, как я понял, уникален) нужен
ВВ>
ВВ>SELECT * FROM fucking_table WHERE Id = 3
ВВ>
так то оно так, но вот что ты будешь делать, если запись с id=3 уже удалена, и следующий id=4?
вот для этого и нужен лимит, и условие >
Хотя как я уже говорил, правильнее ИМХО работать именно с offset..
так как тогда пользователю можно честно сказать: вы смотрите (n)-ю запись из
(select count(*) from fucking_table) что большинство смотрелок и делают
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, vvaizh, Вы писали:
ВВ>Лимит тут имхо не поможет. Речь идет о выборке записе согласно значениям колонки Id, как я понял. Лимит же выбирает опред. кол-во записей, к-е нужно выбрать.
Да, наверно я понял, вы опять не заметили offset... который как раз и даёт с какой записи по порядку выдавать результат..
Или наоборот заметили, и считаете, что offset не оптимизируется.. (хотя мог бы..)
Действительно в manual ничего не написано, как он оптимизируется.. Нужно проверять, может действительно второй мой вариант будет работать быстрее первого (там где явно написано Id>.. точно будет использоваться индекс..)
Хотя первый вариант я дейтствительно видел в стандартных смотрелках на php..
Здравствуйте, kastet, Вы писали:
K>Здравствуйте, vvaizh, Вы писали:
V>Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, vvaizh, Вы писали:
K>[skipped]
K>Спасибо за помощь. По документации все вроде сходится, но при выполнении
K>
K>SELECT * FROM `readers` ORDER BY READER_ID LIMIT 1 OFFSET 1
K>
K>MySQL выдает "You have an error in your SQL syntax near 'OFFSET 1' at line 1"
K>версия mysql 3.23.38, это проблема в руках или как?
Наверно в версии.. Вот что у меня на 4.0:
mysql> use test
Database changed
mysql> create table a(b int);
Query OK, 0 rows affected (0.02 sec)
mysql> insert into a (b) values (1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into a (b) values (2);
Query OK, 1 row affected (0.00 sec)
mysql> insert into a (b) values (3);
Query OK, 1 row affected (0.01 sec)
mysql> insert into a (b) values (4);
Query OK, 1 row affected (0.00 sec)
mysql> select * from a order by b limit 1,1;
+------+
| b |
+------+
| 2 |
+------+
1 row in set (0.01 sec)
mysql> select * from a order by b limit 0,1;
+------+
| b |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
mysql> select * from a order by b limit 3,1;
+------+
| b |
+------+
| 4 |
+------+
1 row in set (0.00 sec)
mysql> select * from a order by b limit 1 offset 1;
+------+
| b |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
mysql> select * from a order by b limit 1 offset 2;
+------+
| b |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
Для очистки совечти попробуй вариант сзапятой (раз ему offset не нравится..)
И на всякий случай добавь ';' в конце..
Здравствуйте, vvaizh, Вы писали:
V>Здравствуйте, kastet, Вы писали:
K>Здравствуйте, vvaizh, Вы писали:
V>Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, vvaizh, Вы писали:
K>[skipped]
V>Для очистки совечти попробуй вариант сзапятой (раз ему offset не нравится..) V>И на всякий случай добавь ';' в конце..
Здравствуйте, vvaizh, Вы писали:
V>Да, наверно я понял, вы опять не заметили offset... который как раз и даёт с какой записи по порядку выдавать результат.. V>Или наоборот заметили, и считаете, что offset не оптимизируется.. (хотя мог бы..) V>Действительно в manual ничего не написано, как он оптимизируется.. Нужно проверять, может действительно второй мой вариант будет работать быстрее первого (там где явно написано Id>.. точно будет использоваться индекс..)
Мне кажется, что второй твой вариант действительно будет быстрее. К тому же лимит там совершенно не нужен, так как лимитацию уже совершает WHERE. Ведь ID должен быть уникальным (в противном случае теряется самый смысл идентификации) и соответственно будет совершена выборка не более одной записи.
Впрочем, по поводу быстроты — это имхо, основанное на собственном опыте применения.
А вообще мне кажется, что все разногласия из-за того, что автора первого поста не совсем ясно сформулировал что ему надо. Совершать последовательную выборку это одно, а делать выборку по значению полей — совсем другое.
ВВ>Мне кажется, что второй твой вариант действительно будет быстрее. К тому же лимит там совершенно не нужен, так как лимитацию уже совершает WHERE. Ведь ID должен быть уникальным (в противном случае теряется самый смысл
Да но условию скажем ID>4
Могут удовлетворять __уникальные__ id 5,6,7..
А нам нужен именно первый из них..
Здравствуйте, vvaizh, Вы писали:
V>Да но условию скажем ID>4 V>Могут удовлетворять __уникальные__ id 5,6,7.. V>А нам нужен именно первый из них..
Че-то я уже не въезжаю. Мне нужна запись с ИД>4 и притом одна. Так почему сразу ее явно не запросить, т.е. запись с ИД=5. Ты сам посуди какое у тебя условие.
Ид должно быть больше 4, запись с Ид должна быть только одна, из всех записей с Ид больше четырех, должна быть выбрана та, Ид которой максимально приближено к 4.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Здравствуйте, vvaizh, Вы писали:
V>Да но условию скажем ID>4 V>Могут удовлетворять __уникальные__ id 5,6,7.. V>А нам нужен именно первый из них..
ВВ>Че-то я уже не въезжаю. Мне нужна запись с ИД>4 и притом одна. Так почему сразу ее явно не запросить, т.е. запись с ИД=5. Ты сам посуди какое у тебя условие.
ВВ>Ид должно быть больше 4, запись с Ид должна быть только одна, из всех записей с Ид больше четырех, должна быть выбрана та, Ид которой максимально приближено к 4.
ВВ>Не проще ли заменить все это на:
ВВ>Ид должно быть равно 5.
Т.е. когда то в ней и был id==5, но потом кто-то эту запись удалил..
Одну из 900000 ....
НЕ перенумеровывать же из-за этого все id..
В существующих базах данных это не принято..
Так работают всякие auto-increment поля и sequence..
Поэтому нужно именно то что я написал..
Это только он в своём примере написал что у него id по порядку идут, в реальности это не так!