Форум: "Базы";
Текущий архив: 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.036 c