Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Правильный запрос! Пытаемся составить грамотно запрос! 
V
    Опции темы
Volter
  Дата 16.4.2007, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 16.4.2007

Репутация: нет
Всего: нет



Добрый день,

Задача:

Есть таблица с данными:

tbNum
+----+
| id  |
+----+
|  1  |
|  2  |
|  4  |
|  5  |
|  6  |
|  7  |
+----+

id - ПЕРВИЧНЫЙ КЛЮЧ (т.е. Циферки которые лежат в данной таблице неповторяющиеся ) Уникальные)

Как видим в таблице есть числа, НО эти числа идут не по-порядку, ПРОПУЩЕНО ЧИСЛО 3 !!!

Другими словами число 3 в данной таблице есть минимальное свободное число!

ТЕПЕРЬ ВОПРОС!

Как сформировать правильно запрос в MySQL чтобы получить такое минимальное свободное число?

Заранее, всех благодарю!

PM MAIL   Вверх
skyboy
Дата 16.4.2007, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(Volter @  16.4.2007,  14:35 Найти цитируемый пост)
Как видим в таблице есть числа, НО эти числа идут не по-порядку, ПРОПУЩЕНО ЧИСЛО 3 !!!

и что? если id - первичный ключ, то это вполне нормально. зачем тебе туда чего-то вставлять?

Добавлено через 5 минут и 59 секунд
так уж и быть, вот запрос:
Код

SELECT `t0`.`id`,(`temp`.`min_id`- `t0`.`id`)  `difference`
FROM  `tbNum` `t0`
INNER JOIN 
                  (
                   SELECT `t1`.`id` as `id`,min(`t2`.`id`) as `min_id`
                   FROM `tbNum` `t1`
                   CROSS JOIN `tbNum` `t2`
                   WHERE `t2`.`id`> `t1`.`id` + 1
                   GROUP BY `t1`.`id`
                  ) `temp`
ON `temp`.`id` = `t0`.`id`
WHERE `temp`.`min_id`- `t0`.`id`> 0


Добавлено через 7 минут и 4 секунды
но если ты планируешь после удаления записей забивать вновь добавляемые с коррекцией значения id, то я хочу тебе сказать: так делать нельзя. заимеешь проблем.
PM MAIL   Вверх
Volter
Дата 16.4.2007, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 16.4.2007

Репутация: нет
Всего: нет



К сожалению, пример не работает smile
PM MAIL   Вверх
skyboy
Дата 16.4.2007, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



да. "+1" было лишним.
Код

SELECT `t0`.`id`,(`temp`.`min_id`- `t0`.`id`)  `difference`
FROM  `tbNum` `t0`
INNER JOIN 
                  (
                   SELECT `t1`.`id` as `id`,min(`t2`.`id`) as `min_id`
                   FROM `tbNum` `t1`
                   CROSS JOIN `tbNum` `t2`
                   WHERE `t2`.`id`> `t1`.`id`
                   GROUP BY `t1`.`id`
                  ) `temp`
ON `temp`.`id` = `t0`.`id`
WHERE `temp`.`min_id`- `t0`.`id`> 0


Добавлено через 31 секунду
Цитата(Volter @  16.4.2007,  15:13 Найти цитируемый пост)
пример не работает

работает. но неверно.
PM MAIL   Вверх
Volter
  Дата 16.4.2007, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 16.4.2007

Репутация: нет
Всего: нет



Мой дорогой друг, вы для какой версии MySQL пишете этот код?
PM MAIL   Вверх
muzer
Дата 16.4.2007, 21:27 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Код

SELECT t1.id+1 FROM tbNum t1 LEFT JOIN tbNum t2 ON t2.id = t1.id+1 WHERE t2.id IS NULL ORDER BY t1.id LIMIT 1

В случае когда пропусков нет вернётся максимальный id + 1.
PM WWW   Вверх
skyboy
Дата 16.4.2007, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Volter, версия 5.1.19 или 5.2, вроде бы как(посмотрю завтра - код писал на работе)
А что, разве существуют другие версии?  smile Тогда почему о них ни слова не было?  smile

Добавлено через 1 минуту и 59 секунд
muzer, лаконичнее и без подзапросов smile  smile 
PM MAIL   Вверх
Volter
  Дата 16.4.2007, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 16.4.2007

Репутация: нет
Всего: нет



БЛАГОДАРЮ muzer и skyboy за содействия!  smile 

Это сообщение отредактировал(а) Volter - 17.4.2007, 01:39
PM MAIL   Вверх
Volter
  Дата 17.4.2007, 01:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 16.4.2007

Репутация: нет
Всего: нет



Товарищи!

Вопрос не до конца вообщето решили мы  smile 

Допустим, у нас есть таже таблица, но с другой последовательностью данных:

tbNum
+----+
| id  |
+----+
|  3  |
|  5  |
+----+

По сути, запрос должен вернуть число 0, а не число 4, как возвращает данный код:

Код

SELECT t1.id+1 FROM tbNum t1 LEFT JOIN tbNum t2 ON t2.id = t1.id+1 WHERE t2.id IS NULL ORDER BY t1.id LIMIT 1


Что нужно приписать еще в SQL-запросе чтобы полностью удовлетворять данную проблемку?   smile 
PM MAIL   Вверх
skyboy
Дата 17.4.2007, 07:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Код

UNION 
SELECT 0
FROM `tbNum` `temp1`
GROUP BY `temp1`.`id`
HAVING min(`temp1`.`id`)> 0


Добавлено через 1 минуту и 46 секунд
мой запрос должен идти после первого запроса(оператор union используется).
Вместо UNION лучше даже использовать UNION ALL

Добавлено через 2 минуты и 30 секунд
Volter, открой страную тайну: на кой ляд тебе шаманство с  primary key?
PM MAIL   Вверх
Volter
  Дата 17.4.2007, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 16.4.2007

Репутация: нет
Всего: нет



Цитата(skyboy @  17.4.2007,  07:10 Найти цитируемый пост)
Volter, открой страную тайну: на кой ляд тебе шаманство с  primary key? 


SkyBoy,

Я вот рылся рылся в книге Полья Дюбуа "MySQL The definitive guide to using, programming, and administering MySQL databases", и не нашел грамотного AUTO_INCREMENT.

В том смысле что этот AUTO_INCREMENT при добавлении строки просто в тупую увеличивает число не анализируя содержимое того атрибута к которому оно было присвоено.

Т.е.

Будет набор такой:

tbNum
+----+
| id  |
+----+
|  3  |
|  5  |
+----+

При добавлении новой записи в таблицу, параметр AUTO_INCREMENT создаст число 6, но разве это рационально, в том смысле что есть пустующие строки 0,1,2,4?

И еще один небольшой вопрос, можно ли при создании таблицы прописать какой либо код в атрибут?
т.е. создать код который автоматически при добавлении записи в таблицу, находит минимальное свободное число в данном атрибуте и присваивает его.


Заранее благодарю, skyboy
PM MAIL   Вверх
Volter
  Дата 17.4.2007, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 16.4.2007

Репутация: нет
Всего: нет



Да и вот еще кое чего:


Вот запрос на существовании данных в табличке.

mysql> SELECT * FROM tbNum;
+----+
| id |
+----+
|  3 |
|  5 |
+----+
2 rows in set (0.00 sec)


А вот тот самый запрос, который непашет почемуто. smile 

mysql> SELECT t0.id,(temp.min_id-t0.id)  difference
    -> FROM  tbNum t0
    -> INNER JOIN
    ->                   (
    ->                    SELECT t1.id as id,min(t2.id) as min_id
    ->                    FROM tbNum t1
    ->                    CROSS JOIN tbNum t2
    ->                    WHERE t2.id> t1.id
    ->                    GROUP BY t1.id
    ->                   ) temp
    -> ON temp.id = t0.id
    -> WHERE temp.min_id- t0.id>0;
ERROR 1064: You have an error in your SQL syntax.  Check the manual that corresp
onds to your MySQL server version for the right syntax to use near 'SELECT t1.id
 as id,min(t2.id) as min_id
                   FROM
PM MAIL   Вверх
skyboy
Дата 17.4.2007, 16:45 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(Volter @  17.4.2007,  15:16 Найти цитируемый пост)
А вот тот самый запрос, который непашет почемуто.

а потому что подзапросы появились не сразу. Далеко не сразу. А версию используемого сервера ты так и не назвал, так что выводы не из чего делать. Надеюсь - пока что.
Цитата(Volter @  17.4.2007,  14:52 Найти цитируемый пост)
При добавлении новой записи в таблицу, параметр AUTO_INCREMENT создаст число 6, но разве это рационально, в том смысле что есть пустующие строки 0,1,2,4?

Но ведь строки сами по себе никуда не ушли?! Их удалили. А если на них(на записи в этих "строках") ссылались другие таблицы, то что лучше - пусть ссылаются на несуществующие данные и, скажем, inner join такие ситуации скроет, а left join отобразит, или лучше создать "в том месте" записи, никакого отношения к связанным данным не имеющие? Именно в виду такой политики безопасности, фраза
Цитата(Volter @  17.4.2007,  14:52 Найти цитируемый пост)
В том смысле что этот AUTO_INCREMENT при добавлении строки просто в тупую увеличивает число 

с приведенным примером не совсем верна. AUTO_INC отталкивается не от последнего значения в поле таблицы, а от "внутренного" счетчика, связанного с таблицей - благодаря этому после любого добавления/удаления строк, на вновь добавляемую строку(как на значение ключа) друие таблицы в принципе ссылаться не могут, потому как значение автоинкрементного поля во вновь создаваемой записи уникально. И мой тебе совет: не надо "переть" против этого механизма. Заимеешь скрытых граблей, а выиграть - и в чем не выиграешь. Ни в скорости(ключам на собственно значения плевать), ни в объеме(тип данных тот же - места занимают столько же).
Цитата(Volter @  17.4.2007,  14:52 Найти цитируемый пост)
И еще один небольшой вопрос, можно ли при создании таблицы прописать какой либо код в атрибут?
т.е. создать код который автоматически при добавлении записи в таблицу, находит минимальное свободное число в данном атрибуте и присваивает его.

Есть такая вещь, как триггеры. В MySQL появились только в 5-й версии.
PM MAIL   Вверх
Volter
  Дата 17.4.2007, 22:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 16.4.2007

Репутация: нет
Всего: нет



НебесномуМальчику мои особые благодарности, сразу видно начитанный в данной области человек, не то что некоторые на форумах!

SkyBoy, у меня к тебе несколько вопросов, ты уж извини я только начал изучение, а ты я гляжу уже давно знаком с SQL, если не откажеш, ответь:
  • Тип int имеет предел в положительной зоне до числа 2147483647, т.е. фактически атрибут с типом INT может содержать 2147483647 записей, теперь вопрос, - что будет если мы добавим новую 214748364 запись, что сделает AUTO_INCREMENT в таком случае?
  • Как в итоге, все таки, должен выглядеть SQL-запрос к вопросу по данной теме?
  • Почему ты имена таблиц в SQL запросах пишеш в кавычках?
  • Не подскажеш литературку для MySQL v5?





Это сообщение отредактировал(а) Volter - 17.4.2007, 22:54
PM MAIL   Вверх
skyboy
Дата 17.4.2007, 23:03 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



Цитата(Volter @  17.4.2007,  21:38 Найти цитируемый пост)
НебесномуМальчику

не надо искажать мой ник. и переводить не надо. всю поэзию убил переводом  smile 
Цитата(Volter @  17.4.2007,  21:38 Найти цитируемый пост)
видно начитанный в данной области человек

доводилось плотно работать и рассматривать вблизи.
"Жить захочешь - не так раскорячишься"(С) "Особенности национальной охоты"
Цитата(Volter @  17.4.2007,  21:38 Найти цитируемый пост)
SkyBoy, не подскажеш литературку для MySQL v5 ? 

К твоему сожалению, я вполне обходился в работе английской версией мануала на dev.mysql.com: MySQL 5.0 Reference Manual и локальной версией справки, идущей в комплекте в дистрибутиве mysql(если только не заимел "обрезку" какую вроде как в Денвере)
вот полный список манов для разных версий(заметь, что для <5 версий есть  и русская версия)
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.1101 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.