powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / MySQL "Cook Room"
19 сообщений из 19, страница 1 из 1
MySQL "Cook Room"
    #33103705
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предлагаю открыть новую ветку " MySQL Cook Room " на форуме MySQL.

Цель - собрать сборник "рецептов" для решения конкретных задач, связанных именно с особенностями СУБД MySQL.

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

Надеюсь, что это действительно станет полезным топиком для всех. :)
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33103706
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как получить следующее значение автоинкремента?
1. Средствами MySQL
Код: plaintext
1.
SELECT last_insert_id(); 

2. Функция PHP API - mysql_insert_id();

Полезные ссылки:

How to Get the Value of an AUTO_INCREMENT Column

PHP mysql_insert_id()
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33103707
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где взять документацию по MySQL?
On-line документация: MySQL Manual

Off-line документация (в формате *.chm): manual.chm
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33104799
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как сделать дамп MySQL базы с помощью PHP

Site Keeper Dumper LE 1.0.6
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33106410
я
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
я
Гость
а на русском нет случайно доков или мануалов
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33106432
Welly
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
яа на русском нет случайно доков или мануалов

Online

Offline (CHM)
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33106824
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как найти предыдущую и последующие записи в таблице для заданной при условии что последовательность идентификаторов (ID записей) не является непрерывной?

Допустим нам требуется по номеру записи вытащить 2 записи, которые будут предшествовать данной, а другая - следовать. Причем в "цепочке" могут быть разрывы.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
-- создаем тестовую табличку
create table test (
 id int not null auto_increment,
 info char not null,
 primary key(id));

-- наполняем ее тестовыми данными
insert into test (info)
 select 'A' union all
 select 'B' union all
 select 'C' union all
 select 'D' union all
 select 'E' union all
 select 'F' union all
 select 'G' union all
 select 'H' union all
 select 'X' union all
 select 'Y' union all
 select 'Z';

-- удалим некоторые записи, чтобы появились "разрывы"
delete from test 
 where id in ( 2 , 3 , 7 , 8 , 10 )

-- после удаления
select * from test

+----+------+
| id | info |
+----+------+
|   1  | A    |
|   4  | D    |
|   5  | E    |
|   6  | F    |
|   9  | X    |
|  11  | Z    |
+----+------+

-- теперь мы хотим определить предшествующую и предыдущую запись 
-- для id с номером 4

select 
 id current,
 IfNULL((select id from test where id=(select max(id) from test where id< 4 ) limit  0 , 1 ),  0 ) prev,
 IfNULL((select id from test where id=(select min(id) from test where id> 4 ) limit  0 , 1 ),  0 ) next
from test
where id= 4 

+---------+------+------+
| current | prev | next |
+---------+------+------+
|        4  |     1  |     5  |
+---------+------+------+

-- теперь сделаем тоже самое для граничной точки (например id=1)

select 
 id current,
 IfNULL((select id from test where id=(select max(id) from test where id< 1 ) limit  0 , 1 ),  0 ) prev,
 IfNULL((select id from test where id=(select min(id) from test where id> 1 ) limit  0 , 1 ),  0 ) next
from test
where id= 1 

+---------+------+------+
| current | prev | next |
+---------+------+------+
|        1  |     0  |     4  |
+---------+------+------+


Примечание:

 возможно это конечно не самый оптимальный вариант, но рабочий :);
 к сожалению не было возможности протестировать его на "больших" таблицах

Где это может быть применимо:

Многие наверное видели на сайтах ссылки типа "Предыдущая страница" и "Последующая страница", с помощью которых можно "листать" страницы какого-то раздела на сайте. Например, это может быть фотогалерея.

Полезные ссылки:

Control Flow Functions (IFNULL)

P.S. Версия СУБД MySQL - 4.1.
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33107827
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предисловие: данная задачка и ее решение лежат тут

Задача:

Таблица Т. Два поля D и P.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
+----------------+-------+
| D              | P     |
+----------------+-------+
| 01.01.2004     | 0     |
| 02.01.2004     | 0     |
| 03.01.2004     | 1     |
| 04.01.2004     | 1     |
| 06.01.2004     | 0     |
| 07.01.2004     | 1     |
| 08.01.2004     | 0     |
| 09.01.2004     | 1     |
| 11.01.2004     | 1     |
| 14.01.2004     | 0     |
+----------------+-------+

Требуется вывести записи значения в которых P=1 и предыдущее (по полю D) значение P=0, т.е. должны быть выведены записи за 3.01, 7.01, 9.01
ИМХО, пожалуй самое оригинальное решение данного теста:
Код: plaintext
select distinct\\n min(t2.d),\\n t2.p\\nfrom ttt t1, ttt t2\\nwhere t1.p= 0 \\n and t2.p= 1 \\n and t1.d<t2.d\\ngroup by t1.d



P.S. Решение предложил "Владимир Бегун".
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33108439
Фотография Хрен
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Berkut
Как найти предыдущую и последующие записи в таблице для заданной при условии что последовательность идентификаторов (ID записей) не является непрерывной?

Допустим нам требуется по номеру записи вытащить 2 записи, которые будут предшествовать данной, а другая - следовать. Причем в "цепочке" могут быть разрывы.


Существует более простое решение. См. команду HANDLER в мануале mysql
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33111467
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Начальная задача

Выгладываю другой вариант решения, предложенный "sanek842". :)

Код: plaintext
\nset @vid =  4 ;\nselect\n(select id from test where id<@vid order by id desc limit  1  ) as min_id,\n(select id from test where id>@vid order by id asc limit  1  ) as max_id;\n
Этот "рецепт" уже решает проблему вложенных селектов. :)
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33111480
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Извиняюсь, ссылка неверная. Начальная задача
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33115354
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где взять визуальную утилиту для работы с MySQL (ПО для MySQL)?

MySQL Administrator

MySQL Query Browser

Toad® for MySQL – Preview Release

EMS

MySQL Control Center

:: Partner Solutions Page ::

+
http://www.google.ru
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33120559
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как определить рейтинг пяти "лучших" записей в таблице?
Иными словами требуется составить список ТОП 5.

Цифра 5 в данном случае условна, и вы можете выбирать столько записей сколько душа пожелает. :)

Исходные данные: (Предисловие)
Код: plaintext
\\ndrop table if exists t_1\\n\\n( 0  row(s) affected)\\n\\n-- создаем тестовую табличку\\ncreate table t_1 (\\n uid int not null auto_increment primary key,\\n uname varchar( 20 ),\\n vote int not null default  0 )\\n\\n-- заливаем инфу\\ninsert into t_1 \\n(uname, vote) \\nvalues \\n(\\\'Smith\\\',  1 ), (\\\'Joe\\\',  1 ), (\\\'Peter\\\',  4 ), (\\\'Kate\\\',  3 ), (\\\'Mike\\\',  10 ), (\\\'BOSS\\\',  8 ), (\\\'John\\\',  0 );\\n\\n( 7  row(s) affected)\\n

Теперь мы хотим определить 5 "лучших" пользователей (по полю vote) в таблице t_1.
Если сделать прямо в лоб следующим запросом:
Код: plaintext
\\nselect uid, uname "Best users", vote  \\nfrom t_1\\norder by vote desc\\nlimit  5 \\n\\n-- то получим\\n\\n   uid  Best users  vote  \\n------  ----------  ------\\n      5   Mike             10 \\n      6   BOSS              8 \\n      3   Peter             4 \\n      4   Kate              3 \\n      1   Smith             1 \\n

Вроде бы все верно, но есть еще один юзер, у которого vote =1.
Код: plaintext
\\nselect * from t_1 where vote= 1 \\n\\n   uid  uname   vote  \\n------  ------  ------\\n      1   Smith         1 \\n      2   Joe           1 \\n

Как мне кажется, было бы более правильным включить Joe тоже в список ТОП 5.
Потому что, на самом деле, не понятно кто "круче" Joe или Smith (при одинаковых значениях поля vote).

Решение:
Код: plaintext
\\nselect *\\nfrom t_1\\nwhere vote>=(select vote \\n\\t     from t_1\\n\\t     order by vote desc\\n\\t     limit  4 , 1 )\\norder by vote desc\\n\\n   uid  uname   vote  \\n------  ------  ------\\n      5   Mike         10 \\n      6   BOSS          8 \\n      3   Peter         4 \\n      4   Kate          3 \\n      1   Smith         1 \\n      2   Joe           1 \\n

Таким образом мы включили 6 юзеров, у которых рейтинг выше, чем у других.

Примечание: данный запрос должен корректно работать, начиная с версии 4.1.

P.S. Алгоритм решения предложил "Sarin" ;)
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33120687
Sarin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Berkut
Как определить рейтинг пяти "лучших" записей в таблице?
Иными словами требуется составить список ТОП 5.


Примечание: данный запрос должен корректно работать, начиная с версии 4.1.


В более ранних версиях целесообразно воспользоваться средствами клиента (запомнить значени пятой записи данного поля в переменную) и выполнить второй запрос. Пример на делфи с использованием Zeos access:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
 var 
s:  string ;  //сохраним в s промежуточное значение. 
 begin 
ZMySqlQuerry1.Sql.Clear;
ZMySqlQuery1.Sql.Add('select vote from t_1 order by vote desc limit 4,1');  {Это вложенный запрос из примера Berkut'а} 
ZMySqlQuery1.Activ := TRUE;
ZMySqlQuery1.First;
 while   NOT  ZMySqlQuery1.Eof  do   {Не стоит прыгать сразу на пятую запись. Ведь если их окажется три произойдёт ошибка. Пролистаем все с начала до последней.} 
 begin 
s := ZMySqlQuery1.Fields[ 0 ].AsString;
ZMySqlQuery1.Next;
 end ;  //Минимальное значение полученно. 

ZMySqlQuerry1.Sql.Clear;
ZMySqlQuery1.Sql.Add('select * from t_1 where vote >= ' + s);  { А этот запрос выдернет нам таблицу как у Berkut'а} 
ZMySqlQuery1.Activ := TRUE;
Отсутствие ошибок не гарантирую. Писано на коленке.

ЗЫ: можно попробовать пользовательские переменные. Но запросов в любом случае будет 2.
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33122929
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что делать если не работают вложенные селекты?
Данная проблема достаточно хорошо рассмотрена на сайте mysql.com , и предлагаемые решения подходят для большинства случаев в ранних версиях MySQL (ниже 4.1).

Поэтому не будем изобретать ничего нового, а просто выложим часть параграфа 1.9.4.1.
Единственное, что пожалуй, следует отметить, это то, что под id понимается уникальный ключ (или первичный) таблицы.
MySQL manual
Вложенные операции выборки реализованы в версии 4.1 .

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

SELECT * FROM table1 WHERE id IN (SELECT id FROM table2);

можно переписать следующим образом:

SELECT table1.* FROM table1,table2 WHERE table1.id=table2.id;

Запросы:

SELECT * FROM table1 WHERE id NOT IN (SELECT id FROM table2);
SELECT * FROM table1 WHERE NOT EXISTS (SELECT id FROM table2
WHERE table1.id=table2.id);

эквивалентны следующему:

SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id
WHERE table2.id IS NULL;

Для более сложных подзапросов часто можно создать временные таблицы, содержащие данный подзапрос. Иногда, однако, этот способ не годится, чаще всего для команд DELETE, для которых в стандарте SQL не поддерживаются объединения (за исключением вложенных выборок). В этой ситуации возможны два временных (пока вложенные запросы не поддерживаются сервером MySQL) варианта решения проблемы.

...


Полезные ссылки: обязательно прочтите MySQL Manual. Вложенные SELECTы .
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33131902
.-.-.-.-.-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
поклонникам этого треда советую почитать Поля Дюбуа "MySQL Cookbook"
Там куча рецептов на все случаи жизни.
Англоязычный вариант можно найти online
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33132275
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
.-.-.-.-.-поклонникам этого треда советую почитать Поля Дюбуа "MySQL Cookbook"
Там куча рецептов на все случаи жизни.
Англоязычный вариант можно найти online

Англоязычный вариант можно скачать с ftp://custik.org/incoming/books/O'reilly - Mysql Cookbook.chm
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33137396
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как сгенерировать список дат за месяц, которых нет в таблице?
Задача:

Требуется создать отчет, который будет определять дни месяца, которые не вошли в таблицу.
Допустим ваш БОСС, говорит вам: "Я хочу знать как там обстоят дела с продажами товаров за месяц? Определи пожалуйста те дни, в которые мы ничего не продали".

Итак Вы понимаете, что вы можете это проделать как-то вручную. Но вдруг так просят делать каждый месяц? Что тогда?

Решение: (возможно не самое оптимальное)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
-- установливаем новый формат даты для удобства
set global date_format='%d.%m.%Y'

-- создаем тестовую табличку
create table t ( d date)

( 0  row(s) affected)
( 0  ms taken)

-- заливаем даты
insert into t (d) values (str_to_date('12.06.2005', '%d.%m.%Y'));
insert into t (d) values (str_to_date('13.06.2005', '%d.%m.%Y'));
insert into t (d) values (str_to_date('14.06.2005', '%d.%m.%Y'));
insert into t (d) values (str_to_date('20.06.2005', '%d.%m.%Y'));
insert into t (d) values (str_to_date('21.06.2005', '%d.%m.%Y'));

( 5  row(s) affected)

Находим те дни, в которые были продажи за месяц.
Ясно, что если у нас в таблице содержатся данные по нескольким месяцам, то необходимо добавить условие where ...

Рассмотрим простейший случай, когда в таблице содержатся данные за один месяц:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select date_format(d, '%d.%m.%Y') dates from t

dates     
----------
 12 . 06 . 2005 
 13 . 06 . 2005 
 14 . 06 . 2005 
 20 . 06 . 2005 
 21 . 06 . 2005 


Теперь сгенерим "множество дней месяца".

Примечание: 30 - это последний день месяца в данном примере, который можно определить с помощью MySQL.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
select x1.ones+x2.tens mdays
from (
    select  0  ones union all
    select  1  ones union all
    select  2  ones union all
    select  3  ones union all
    select  4  ones union all
    select  5  ones union all
    select  6  ones union all
    select  7  ones union all
    select  8  ones union all
    select  9  ones) x1,
    (select  0  tens union all
    select  10  tens union all
    select  20  tens union all
    select  30  tens) x2
where x1.ones+x2.tens between  1  and  30 

-- в итоге получим числа
mdays
---------
         1 
         2 
...
        30 
	   
-- сохраним это множество во временной таблице
create temporary table t_1
as
select x1.ones+x2.tens mday
from (
    select  0  ones union all
    select  1  ones union all
    select  2  ones union all
    select  3  ones union all
    select  4  ones union all
    select  5  ones union all
    select  6  ones union all
    select  7  ones union all
    select  8  ones union all
    select  9  ones) x1,
    (select  0  tens union all
    select  10  tens union all
    select  20  tens union all
    select  30  tens) x2
where x1.ones+x2.tens between  1  and  30 

( 30  row(s) affected)

-- теперь все готово, чтобы создать отчет

select concat(t_1.mday, '.', Month('2005-06-00'), '.', YEAR('2005-06-00')) as dates
from t_1 left join t
on t_1.mday=DAYOFMONTH(t.d)
where t.d is null

dates    
---------
 1 . 6 . 2005  
 2 . 6 . 2005  
 3 . 6 . 2005  
 4 . 6 . 2005  
 5 . 6 . 2005  
 6 . 6 . 2005  
 7 . 6 . 2005  
 8 . 6 . 2005  
 9 . 6 . 2005  
 10 . 6 . 2005 
 11 . 6 . 2005 
 15 . 6 . 2005 
 16 . 6 . 2005 
 17 . 6 . 2005 
 18 . 6 . 2005 
 19 . 6 . 2005 
 22 . 6 . 2005 
 23 . 6 . 2005 
 24 . 6 . 2005 
 25 . 6 . 2005 
 26 . 6 . 2005 
 27 . 6 . 2005 
 28 . 6 . 2005 
 29 . 6 . 2005 
 30 . 6 . 2005 

Примечание: работает в версии MySQL 4.1.

Полезные ссылки: Функции даты и времени в MySQL
...
Рейтинг: 0 / 0
MySQL "Cook Room"
    #33145281
Фотография Berkut
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как програмно подключится к MySQL из C++?
Как програмно подключится к MySQL из Java?
Как програмно подключится к MySQL из Perl?


Глава 8. Интерфейсы для MySQL

P.S. Конечно данный пост не относится к MySQL "Cook Room", а скорее тянет на FAQ. Но все же решил кинуть линк на мануал, т.к. эти вопросы задаются слишком часто. :)
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / MySQL "Cook Room"
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]