Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];

Вниз

Найти дырки в таблице   Найти похожие ветки 

 
Drakosha ©   (2005-09-06 18:19) [0]

Имеется таблица с уникальным полем, значения в нём должны быть
от 1 до 100.
пример
2
3
4
89
90
Необходимо получить отсутствующие номера (т.е. 1,5,6,...88,91..100)
Можно ли это сделать не привлекая дополнительную таблицу со всеми значениями от 1 до 100?


 
Shopot ©   (2005-09-06 18:42) [1]

Можно!


var
 Numbers: array [1..100] of Byte;
 IsEntry: array [1..100] of Boolean;

procedure InitArrays;
var
 i: Integer;
begin
 for i := 1 to 100 do
 begin
   Numbers [i] := i;
   IsEntry [i] := False;
 end;
end;

procedure LookIntoTable;
var
 i, RecordCount: Integer;
begin
 RecordCount := Table.RecordCount;

 if RecordCount > 100 Exit;

 for i := 0 to RecordCount - 1 do
 begin
   if Table["_ID"] = Numbers [i] then
     IsEntry [i] := True
   else
     IsEntry [i] := False;
 end;
end;


Таким образом знаем какие числа входят и каких нет.
Наример:


 ...
 if IsEntry [10] then
   ShowMessage ("Number = " + IntToStr (Number [10]) + " exists!");
 ...


Кроме того Numbers массив байт, но может быть и строк и записей и т.п.


 
Lexer ©   (2005-09-06 19:57) [2]

Как вариант, - можно написать простенькую процедурку:
create procedure get_dyrki
returns (order_number smallint)
begin
 last_order_number = 0;
 while order_number < 100 do
 begin
   order_number = order_number + 1;
   if (not(exists(select order_number from table_1 where order_number = :order_number))) then suspend;
  end
end


 
Desdechado ©   (2005-09-06 20:26) [3]

ХП написать :)


 
Desdechado ©   (2005-09-06 21:06) [4]

хм, отвлекся, не запостив, и на тебе - опередили


 
Zacho ©   (2005-09-07 08:37) [5]

Да можно и одним запросом:

SELECT T1.ID+1
FROM MY_TABLE T1
LEFT JOIN MY_TABLE T2
 ON T1.ID+1=T2.ID
WHERE T2.ID IS NULL


По крайней мере на IB/FB такой запрос работает, на других СУБД - не знаю :)


 
Val ©   (2005-09-07 10:40) [6]

>[5] Zacho ©   (07.09.05 08:37)
в данном примере, он не покажет номера с 5 по 88, а только 5-й. т.е. он находит "первый пустой" за текущим id.


 
Anatoly Podgoretsky ©   (2005-09-07 11:28) [7]

Почему 5, а не 1


 
Zacho ©   (2005-09-07 11:41) [8]

Val ©   (07.09.05 10:40) [6]

Да, ты прав. Если "дырки" идут подряд, то такой запрос покажет только первую в диапазоне.
Сожалею, был не внимателен.
Так что для нахождения всех дырок мой запрос не подходит. А вот для нахождения первой или последней - вполне, правда автору вопроса нужно не это :)

2 Drakosha ©  : укажи СУБД, возможно что для твоей СУБД существует решение именно одним запросом.


 
Val ©   (2005-09-07 11:55) [9]

>[7] Anatoly Podgoretsky ©   (07.09.05 11:28)
я про промежуток с "дырками" более одной.


 
Sergey13 ©   (2005-09-07 12:02) [10]

Вариант для Оракла
select rownum from all_objects where rownum<101
minus
select uniq_Field from My_Table

Вместо all_objects можно использовать любую таблицу/вьюху с гарантировано бОльшим 100 количеством записей.


 
Val ©   (2005-09-07 12:08) [11]

>Sergey13 ©   (07.09.05 12:02)
Интересное решение. Думаю, можно применить к любому серверу, заменив минус на not in/not exists и константу на select max. Дело за нужной таблицей.


 
Desdechado ©   (2005-09-07 12:10) [12]

Sergey13 ©   (07.09.05 12:02) [10]
элегантно, но не удовлетворяет условию "не привлекая другую таблицу со всеми 1..100"


 
Val ©   (2005-09-07 12:14) [13]

мда. в [11] я прогнал. rownuma-то не найти в других серверах :( сорри.


 
Sergey13 ©   (2005-09-07 12:15) [14]

2[12] Desdechado ©   (07.09.05 12:10)
Я так думаю ограничение касалось специально созданой таблицы.
Хотя - автору, которого не видно, виднее. 8-)


 
Drakosha ©   (2005-09-07 12:26) [15]

Вопрос задавал вечером и только сейчас глянул ответы.
Что ж начнём по порядку:

2Shopot ©
2Lexer ©  
Имелось ввиду не использование никаких языков программирования или хранимых процедур.


 
Drakosha ©   (2005-09-07 12:27) [16]


> Zacho ©   (07.09.05 11:41) [8]

Извиняюся ... показалося что ставил птичку на оракле


 
Drakosha ©   (2005-09-07 12:28) [17]


> Sergey13 ©   (07.09.05 12:02) [10]

Вроде то что надо!!! сейчас опробую


 
Drakosha ©   (2005-09-07 12:33) [18]


> Sergey13 ©   (07.09.05 12:02) [10]


Во!! То что надо! Огромное спасибо!


 
Lexer ©   (2005-09-07 12:34) [19]

Без таблиц, без процедур :)
SELECT 1
 FROM EMPLOYEE WHERE NOT EXISTS (SELECT id_employee FROM EMPLOYEE WHERE id_employee = 1)
UNION
SELECT 2
 FROM EMPLOYEE WHERE NOT EXISTS (SELECT id_employee FROM EMPLOYEE WHERE id_employee = 2)
UNION
SELECT 3
 FROM EMPLOYEE WHERE NOT EXISTS (SELECT id_employee FROM EMPLOYEE WHERE id_employee = 3)
UNION
SELECT 4
 FROM EMPLOYEE WHERE NOT EXISTS (SELECT id_employee FROM EMPLOYEE WHERE id_employee = 4)
UNION
SELECT 5
 FROM EMPLOYEE WHERE NOT EXISTS (SELECT id_employee FROM EMPLOYEE WHERE id_employee = 5)
UNION
SELECT 6
 FROM EMPLOYEE WHERE NOT EXISTS (SELECT id_employee FROM EMPLOYEE WHERE id_employee = 6)
UNION
.....
.....
SELECT 100
 FROM EMPLOYEE WHERE NOT EXISTS (SELECT id_employee FROM EMPLOYEE WHERE id_employee = 100)


 
Drakosha ©   (2005-09-07 12:41) [20]


> Lexer ©   (07.09.05 12:34) [19]
>
> Без таблиц, без процедур :)


:)
ню-ню
без таблиц имелось ввиду что я не создаю лишних или временных а юзаю какие нить уже существующие....
зы от 1 до 100 это я написал для примера...на самом деле там речь о четырёх разрядных значениях...вот я б попарился с твоим вариантом :)


 
Val ©   (2005-09-07 13:16) [21]

>[20] Drakosha ©   (07.09.05 12:41)
Не факт что в all_objects будет нужное вам количество строк. А выставлять для себя ограничение "без процедур, без таблиц", без видимых на то причин, является глупостью по-моему. Что называется - "Хотите гемора - нате!".


 
SvetaK   (2005-09-07 14:06) [22]

Для 3-ёх разрядных значений можно так попробовать...

select nn.nn from (
select  (n2.num*10+n1.num)+1 as nn from
(select 0 as num union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) n1,
(select 0 as num union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) n2
) nn
left join (SELECT * FROM MY_TABLE) t2 on nn.nn=t2.id
where t2.id is null order by 1

,а для четырёх разрядных нужно еще полторы строки напарить - успехов!


 
SvetaK   (2005-09-07 14:23) [23]

В предпоследней строчке уточняю: вместо * надо  id
left join (SELECT id FROM MY_TABLE) t2 on nn.nn=t2.id


 
Drakosha ©   (2005-09-07 14:45) [24]


> >[20] Drakosha ©   (07.09.05 12:41)
> Не факт что в all_objects будет нужное вам количество строк.
> А выставлять для себя ограничение "без процедур, без таблиц",
> без видимых на то причин, является глупостью по-моему. Что
> называется - "Хотите гемора - нате!".

В нашем проекте в all_objects находится свыше 30 000 записей тобишь    всё нармуль.

Всем спасибо за участие и помощь.


 
Val ©   (2005-09-07 14:51) [25]

...понадобились "дырки" с 30 003 по 30 010... :)
кстати, на этот обзор нужны права дба, как я понимаю.


 
Sergey13 ©   (2005-09-07 14:54) [26]

2[25] Val ©   (07.09.05 14:51)
>кстати, на этот обзор нужны права дба, как я понимаю.
Нет. Но для ДБА записей гораздо больше чем для простого узера. 8-)


 
Val ©   (2005-09-07 15:02) [27]

ок. но тогда простой юзер вообще получит пустую выборку, так как он не owner ни одного объекта?


 
Sergey13 ©   (2005-09-07 15:15) [28]

2[27] Val ©   (07.09.05 15:02)
Наверное. Лень проверять.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2005.10.23;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.055 c
3-1126175918
ХиМ
2005-09-08 14:38
2005.10.23
Внешняя база данных не имеет предполагаемого формата


11-1109010924
deniss
2005-02-21 21:35
2005.10.23
не могу найти стрелочный индикатор , сам пока не напишу :(


2-1128239239
elysee
2005-10-02 11:47
2005.10.23
CSV(MS-DOS)


9-1118324957
Novouralsk
2005-06-09 17:49
2005.10.23
Помогите плиз!!!


11-1109243001
Uli
2005-02-24 14:03
2005.10.23
переход между контролами по Enter





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский