SQL-запрос (Страница 1) / Программирование / Форум StopLinux

Объявление

Kwork.ru - услуги фрилансеров от 500 руб.

#1 05-11-10 12:15:27

Maddoc
Участник
Из культурной столицы 2011
Зарегистрирован: 10-03-10
Сообщений: 1,120
Сайт

SQL-запрос

Дано: таблица. Количество полей не важно, важно то, что в ней есть одно поле (пусть будет id, integer). Оно же ключевое, без автоприращения.
Необходимо: SQL-запрос, который находит первое пустое значение.
Пример: в поле содержатся значения 2, 3, 4, 7. Запрос должен выдать 1. В поле содержатся значения 1, 2, 3, 4, 7. Запрос должен выдать 5.


1431.png
Шéстьдесят прóцентов дóцентов лóжат в пóртфели докýменты.
И тóлько сóрок процéнтов доцéнтов кладýт в портфéли докумéнты.

Неактивен

#2 05-11-10 19:21:46

Tiphon
Участник
Зарегистрирован: 08-07-10
Сообщений: 2,354

Re: SQL-запрос

Ты еще SQL сервер забыл сказал, тк.к. SQL-и заметно различаются.


Квантовая механика - "малопонятный математический курьёз" (с) msAVA - современный учитель.

Неактивен

#3 05-11-10 23:23:54

Maddoc
Участник
Из культурной столицы 2011
Зарегистрирован: 10-03-10
Сообщений: 1,120
Сайт

Re: SQL-запрос

Tiphon пишет:

Ты еще SQL сервер забыл сказал, тк.к. SQL-и заметно различаются.

MSD SQL Server 2008, хотя это и неважно :-) Хотелось посмотреть различные варианты.


1431.png
Шéстьдесят прóцентов дóцентов лóжат в пóртфели докýменты.
И тóлько сóрок процéнтов доцéнтов кладýт в портфéли докумéнты.

Неактивен

#4 06-11-10 00:30:48

Tiphon
Участник
Зарегистрирован: 08-07-10
Сообщений: 2,354

Re: SQL-запрос

Maddoc пишет:

хотя это и неважно :-)

важно, и синтаксис запросов и, особенно, написание сторед процедур различаются.

Различные варианты  поставленной задачи для MS SQL:
https://stackoverflow.com/questions/6841 … -in-ms-sql

Хотелось бы обратить внимание на один из комментов:

However, the policy you're describing is really not a good idea. ID values should be unique, but should not be required to be consecutive.

What happens if you email someone with a link to document #42, and then subsequently delete the document? Later, you re-use the id #42 for a new document. Now the recipient of the email will follow the link to the wrong document!

Я сильно поддерживаю того, кто это написал. Хотя, может, именно такое поведение тебе и нужно. Фиг знает.


Квантовая механика - "малопонятный математический курьёз" (с) msAVA - современный учитель.

Неактивен

#5 06-11-10 01:38:43

Maddoc
Участник
Из культурной столицы 2011
Зарегистрирован: 10-03-10
Сообщений: 1,120
Сайт

Re: SQL-запрос

Tiphon пишет:

Хотя, может, именно такое поведение тебе и нужно. Фиг знает.

Мне было интересно, представит ли кто-нибудь 1 (один) запрос хоть под какой-нибудь сервер. Супер-мега-кул-программеров с миллиоами пользователей их творений на форуме хватает, а на простой вопрос ответа нету :-(


1431.png
Шéстьдесят прóцентов дóцентов лóжат в пóртфели докýменты.
И тóлько сóрок процéнтов доцéнтов кладýт в портфéли докумéнты.

Неактивен

#6 06-11-10 01:51:55

Tiphon
Участник
Зарегистрирован: 08-07-10
Сообщений: 2,354

Re: SQL-запрос

Maddoc пишет:

Мне было интересно, представит ли кто-нибудь 1

Мой ответ считается или нет?)))


Квантовая механика - "малопонятный математический курьёз" (с) msAVA - современный учитель.

Неактивен

#7 06-11-10 02:03:13

Maddoc
Участник
Из культурной столицы 2011
Зарегистрирован: 10-03-10
Сообщений: 1,120
Сайт

Re: SQL-запрос

Tiphon пишет:

Мой ответ считается или нет?)))

Что-то в ответе я не вижу даже SELECT'a :-)


1431.png
Шéстьдесят прóцентов дóцентов лóжат в пóртфели докýменты.
И тóлько сóрок процéнтов доцéнтов кладýт в портфéли докумéнты.

Неактивен

#8 06-11-10 02:15:54

Tiphon
Участник
Зарегистрирован: 08-07-10
Сообщений: 2,354

Re: SQL-запрос

Maddoc пишет:

Что-то в ответе я не вижу даже SELECT'a :-)

Там их 16.


Квантовая механика - "малопонятный математический курьёз" (с) msAVA - современный учитель.

Неактивен

#9 06-11-10 02:30:42

Maddoc
Участник
Из культурной столицы 2011
Зарегистрирован: 10-03-10
Сообщений: 1,120
Сайт

Re: SQL-запрос

Tiphon пишет:

Там их 16.

Именно что там. В MSDN их ещё больше. :-)

Maddoc пишет:

Необходимо: SQL-запрос, который находит первое пустое значение.

И, кстати, как отреагируют те запросы при

Maddoc пишет:

в поле содержатся значения 2, 3, 4, 7. Запрос должен выдать 1

А если 2, 7, 3, 4? Или 7, 2, 3,4.
Кстати, условие написал не совсем верно. Не первое, а минимальное значение.

Редактировался Maddoc (06-11-10 02:34:28)


1431.png
Шéстьдесят прóцентов дóцентов лóжат в пóртфели докýменты.
И тóлько сóрок процéнтов доцéнтов кладýт в портфéли докумéнты.

Неактивен

#10 06-11-10 02:46:31

Tiphon
Участник
Зарегистрирован: 08-07-10
Сообщений: 2,354

Re: SQL-запрос

Maddoc пишет:

Именно что там. В MSDN их ещё больше. :-)

Ну тогда это глупо, как и что ты написал тут. Сам поймешь или объяснить?

Maddoc пишет:

А если 2, 7, 3, 4? Или 7, 2, 3,4.

Первый же вариант решения с MS SQL подходит и под этот случай

Maddoc пишет:

Не первое, а минимальное значение.

Это тебе задачку в институт что ле решить надо?
А то с каждой допиской она становится более и более бредовой.

Добавлено спустя 8 ч 21 мин 01 с:
Maddoc, см лс


Квантовая механика - "малопонятный математический курьёз" (с) msAVA - современный учитель.

Неактивен

#11 06-11-10 15:07:11

Tiphon
Участник
Зарегистрирован: 08-07-10
Сообщений: 2,354

Re: SQL-запрос

select rnum as "пропущенное зн-е" from (select rownum as rnum, id from testid order by id) where rnum != id;

Не вернет 4, если у тебя ид будут 1 2 3 тк.к. всегда ровнам будет равен ид. Как я понял в задаче надо, чтобы в таком случае возвращалось 4.

В принципе мы еще один вариант подробно разобрали в ЛС. Если мэдок одобрит, сюда выложу.


Квантовая механика - "малопонятный математический курьёз" (с) msAVA - современный учитель.

Неактивен

#12 06-11-10 15:36:32

Tiphon
Участник
Зарегистрирован: 08-07-10
Сообщений: 2,354

Re: SQL-запрос

первое пустое значение ... Кстати, условие написал не совсем верно. Не первое, а минимальное значение.

если индекс больше нуля и записаны 1 2 3  - следующее пустое значение будет 4. Ну и в личке мне мэддок чуть больше объяснил зачем это. Как я понял должно быть 4.


Квантовая механика - "малопонятный математический курьёз" (с) msAVA - современный учитель.

Неактивен

#13 06-11-10 16:30:42

Tiphon
Участник
Зарегистрирован: 08-07-10
Сообщений: 2,354

Re: SQL-запрос

Я поздравляю тебя с тем, что ты знаешь из математики N in Z! Дальнейшее развитие офтопа и срача в этой теме повлечет предупреждение.


Квантовая механика - "малопонятный математический курьёз" (с) msAVA - современный учитель.

Неактивен

#14 08-11-10 15:44:25

DonDublon3
Участник
Из Уфа
Зарегистрирован: 06-05-10
Сообщений: 641

Re: SQL-запрос

чесгря, удивительно, что так никто и не придумал такой запрос smile
а я придумал, хотя спецом по sql себя совершенно не считаю.

вот:
SELECT MIN(maxprev+1) FROM
(
SELECT mainid, MAX(previd) as maxprev, mainid-maxprev as diff FROM
(SELECT table1.id as mainid , table2.id as previd
FROM Table1, table1 as table2)
WHERE mainid > previd GROUP BY mainid
)
WHERE diff > 1

за быстродействие и вообще оптимальность, впрочем, не поручусь.


"Фу бля, крохобор вонючий" (с) Svart Testare

Неактивен

#15 08-11-10 19:02:00

Tiphon
Участник
Зарегистрирован: 08-07-10
Сообщений: 2,354

Re: SQL-запрос

DonDublon3 пишет:

за быстродействие и вообще оптимальность, впрочем, не поручусь.

А если цифры 5 6 7, то какое значение запрос выдаст?
В ссылке, которая приведена во втором сообщении, первый запрос как раз, по сути, этот. Только скан делает по i+1

DonDublon3 пишет:

чесгря, удивительно, что так никто и не придумал такой запрос

Tiphon пишет:

06-11-10 14:07:11
В принципе мы еще один вариант подробно разобрали в ЛС. Если мэдок одобрит, сюда выложу.

Просто мэдок бухает, поэтому не опубликовано.


Квантовая механика - "малопонятный математический курьёз" (с) msAVA - современный учитель.

Неактивен

#16 08-11-10 22:03:57

DonDublon3
Участник
Из Уфа
Зарегистрирован: 06-05-10
Сообщений: 641

Re: SQL-запрос

Tiphon пишет:

А если цифры 5 6 7, то какое значение запрос выдаст?

ыыыы. это не учитывается, да.


"Фу бля, крохобор вонючий" (с) Svart Testare

Неактивен

#17 08-11-10 23:10:34

Tiphon
Участник
Зарегистрирован: 08-07-10
Сообщений: 2,354

Re: SQL-запрос

Ну, вобщем, раз меддок бухает, то выложу что ле.

Решение без дурацких запросов: Дефрагментация индексов.
https://msdn.microsoft.com/en-us/library/ff650692.aspx

Решение с дурацким запросом:
Идея в том же поиске по ид+1. Фишка в чем, поиск с ид+1 катит, но не учитывает первые пустые поля (если числа. например 567). Для этого можно делать одну проверку на занятость ячейки с с ид=1. Если такая ячейка не занята, то сначала надо занять ее (минимальный, да). Если занята от нее уже само отсчитывается.

SELECT  TOP (1) CASE 
  WHEN (NOT EXISTS (SELECT id FROM  test AS t2 WHERE (t2.id = 1))) THEN 1 
  WHEN (NOT EXISTS (SELECT id FROM  test AS t2 WHERE (id = t1.id + 1))) THEN id + 1 
  END AS 'freeId'
FROM test AS t1
ORDER BY id

С точки зрения быстродействия, если есть ордер бай, МС БД может в любом случае перебирать  таблицу от начала до конца (до поиска дырок). Чтобы этого избежать можно использовать кластеред индексы. Тогда ордер бай идет по ним и, по идее, перебор будет идти только до дырки (топ(1) остаовит).
https://technet.microsoft.com/en-us/libr … 90639.aspx
Если верить описанию оптимайзера МС ДБ, NOT EXISTS (SELECT id FROM  test AS t2 WHERE (t2.id = 1)) будет проверена 1 раз.
Таким образом первый кейс  проверяет только первый же индекс. Второй кейс перебирает до первой дырки. Поэтому это, наверное, оптимально с точки зрения быстродействия. Но это в теории. На практике - я не специалист по МС БД. Профайлер в руки и смотреть))
Можно эту логику - проверить 1-й, искать с ид+1 реализовать просто с помощью IF, ELSE в запросе и не надеяться на правильную оптимизацию. Можно записать в виде 2-х запросов с юнион. 1-й из которых возвращает 1 или нуль. Будет ли быстрее работать на практике? - без понятия, не специалист.
Решение с ров набмером:
ROW_NUMBER()  не возвращает 4, если у тебя числа 1 2 3. Значит можно добавлять такой же(как в прошлом примере) проверочный запрос, только проверять последнее поле, а отсчитывать последнее поле по логике больнее, чем первое. К тому же МС СКЛ ROW_NUMBER() идет со своим сорт бай и, возможно, будет перелопачивать таблицу даже с кластеред индексами
Ссылка на проблему медленного ROW_NUMBER
https://weblogs.asp.net/eporter/archive/ … t-Set.aspx

Более дурацкие решения, которые рождались в процессе:

SELECT   TOP (1) id - 1 AS freeId FROM test AS t1
WHERE    (NOT EXISTS
                  (SELECT   id
                   FROM      test AS t2
                   WHERE    (id = t1.id - 1))) AND (id - 1 > 0)
UNION
SELECT   id + 1 AS freeId FROM test AS t1
WHERE   NOT EXISTS
                  (SELECT   id
                   FROM      test AS t2
                   WHERE    (id = t1.id + 1))
ORDER BY freeId

Например, если у тебя числа 5 6 8, этим запросом ты получишь 4 7 9. Т.е. если ты будешь брать первое значение этого запроса, ты будешь сначала заселять пустые места "к началу", а только потом все остальные. Будет ли такой запрос хорошо оптимизироваться по TOP(1) - не имею понятия, но предполагаю, что первое решение - лучше)))

Более громоздкие решения
Можно делать карты дырок, например, но к чему этот гемор?
Прицепить триггеры на инсерт и делет, которые будут вписывать и убирать "карту".


Квантовая механика - "малопонятный математический курьёз" (с) msAVA - современный учитель.

Неактивен

Kwork.ru - услуги фрилансеров от 500 руб.
Мой VPS с 2016 года !
✅ Виртуальные от 300 ₽/месяц, RAM 1-10GB, DISK 20-360 GB;
✅ Выделенные от 3000 ₽/месяц. RAM 4-64GB, DISK до 4TB;
✅ Intel Xeon, SSD, XEN, iLO/KVM, Windows/Linux, Администрирование;
✅ Бесплатно Full Backup и Anti-DDoS.





Подвал форума

Под управлением FluxBB
Модифицировал Visman

Яндекс.Метрика