Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / MySQL "Cook Room" / 19 сообщений из 19, страница 1 из 1
07.06.2005, 00:28:54
    #33103705
Berkut
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
Предлагаю открыть новую ветку " MySQL Cook Room " на форуме MySQL.

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

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

Надеюсь, что это действительно станет полезным топиком для всех. :)
...
Рейтинг: 0 / 0
07.06.2005, 00:30:32
    #33103706
Berkut
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
Как получить следующее значение автоинкремента?
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
07.06.2005, 00:31:58
    #33103707
Berkut
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
Где взять документацию по MySQL?
On-line документация: MySQL Manual

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

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

Online

Offline (CHM)
...
Рейтинг: 0 / 0
08.06.2005, 12:01:02
    #33106824
Berkut
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
Как найти предыдущую и последующие записи в таблице для заданной при условии что последовательность идентификаторов (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
08.06.2005, 17:27:29
    #33107827
Berkut
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
Предисловие: данная задачка и ее решение лежат тут

Задача:

Таблица Т. Два поля 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
09.06.2005, 08:50:29
    #33108439
Хрен
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
Berkut
Как найти предыдущую и последующие записи в таблице для заданной при условии что последовательность идентификаторов (ID записей) не является непрерывной?

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


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

Выгладываю другой вариант решения, предложенный "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
10.06.2005, 12:00:15
    #33111480
Berkut
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
Извиняюсь, ссылка неверная. Начальная задача
...
Рейтинг: 0 / 0
14.06.2005, 12:19:01
    #33115354
Berkut
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
Где взять визуальную утилиту для работы с 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
16.06.2005, 21:24:02
    #33120559
Berkut
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
Как определить рейтинг пяти "лучших" записей в таблице?
Иными словами требуется составить список ТОП 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
17.06.2005, 00:30:18
    #33120687
Sarin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
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
18.06.2005, 00:22:46
    #33122929
Berkut
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
Что делать если не работают вложенные селекты?
Данная проблема достаточно хорошо рассмотрена на сайте 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
23.06.2005, 17:18:30
    #33131902
.-.-.-.-.-
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
поклонникам этого треда советую почитать Поля Дюбуа "MySQL Cookbook"
Там куча рецептов на все случаи жизни.
Англоязычный вариант можно найти online
...
Рейтинг: 0 / 0
23.06.2005, 21:50:27
    #33132275
Berkut
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
.-.-.-.-.-поклонникам этого треда советую почитать Поля Дюбуа "MySQL Cookbook"
Там куча рецептов на все случаи жизни.
Англоязычный вариант можно найти online

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

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

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

Решение: (возможно не самое оптимальное)
Код: 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
01.07.2005, 15:00:56
    #33145281
Berkut
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MySQL "Cook Room"
Как програмно подключится к MySQL из C++?
Как програмно подключится к MySQL из Java?
Как програмно подключится к MySQL из Perl?


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

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


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