VirtualIreland.ru - Виртуальная Ирландия
Вернуться   VirtualIreland.ru - Виртуальная Ирландия > Живем в Ирландии > IT и Связь

IT и Связь Обсуждение "айтишных" вопросов и средств связи

Ответ
 
Опции темы Опции просмотра
Старый 09.10.2006, 15:23   #1
Заслуженный Участник
 
Аватар для Zindur
 
Откуда: из роддома
Сообщений: 1,929
Благодарности: 1,861 в 509 сообщениях Поиск благодарностей Zindur
По умолчанию SQL - Not In Range

Вопрос на засыпку
Есть Таблица с полем наприер Field1 данными: 1,2,3,5,9,10

Задача (тута самое интересное) :D :
получить результат: 4,6,7,8 - тоесть то что нету в базе

Извращения:
1. выборку зделать по определёным параметрам: тоесть чАво нету между 2 и 5
2. поле может быть разного типа

пока вижу ответ только как, создать временную таблицу(со всеми данными) и сравнить эти таблицы.
База Данных Пока : MS SQL, Interbase, Access,.....
Варианты
Zindur вне форума   Ответить с цитированием

Зарегистрируйтесь или войдите под своим именем, чтобы спрятать этот рекламный блок
Старый 09.10.2006, 16:35   #2
Редкий собеседник
 
Сообщений: 2,663
Благодарности: 906 в 585 сообщениях Поиск благодарностей TYA
По умолчанию Re: SQL - Not In Range

Цитата:
Сообщение от Zindur
Вопрос на засыпку
Есть Таблица с полем наприер Field1 данными: 1,2,3,5,9,10

Задача (тута самое интересное) :D :
получить результат: 4,6,7,8 - тоесть то что нету в базе

Извращения:
1. выборку зделать по определёным параметрам: тоесть чАво нету между 2 и 5
2. поле может быть разного типа

пока не вижу ответа как создавать временную таблицу и сравнить эти таблицы.
База Данных Пока : MS SQL, Interbase, Access,.....
Варианты
Как написать, не знаю, но могу предложить один из возможных путей решения.

Если тип данных неизвестен (число, строка...) и правило порядка/последовательности может быть описан разными способомами, то есть предложение хранить правильный порядок/последовательность определенного типа данных в отдельной таблице А, ну или написать фунцию/процедуру, которая знает как генерить этот порядок, пусть будет тоже A. С числами видимо все упрощается за счет встроенных средств.
И когда надо найти отсутсвующие данные, то сделать выборку из таблицы/функции А in range [a,b] во временную таблицу B (для простоты, тип поля B должен соответствовать типу поля Field1 "рабочей" таблицы) и затем исключить все записи из B, которым соответствуют записям в "рабочей" таблице по значению в поле Field1. Остаток в таблице B и есть ответ. Я думаю тип поля можно найти at runtime.
Если нет, то можно написать несколько функций/процедур для разных типов данных, и вызывать нужную при работе с определенной таблицой. Можно написать и функцию-конвертор, но по-идее работа с однотипными данными в базе будет быстрее, чем конвертить каждый раз.
__________________
Steve Jobs:"It's better to be a pirate than to join the Navy."
-- Odyssey: Pepsi to Apple
TYA вне форума   Ответить с цитированием
Старый 09.10.2006, 17:06   #3
My name is Exaybachay
 
Аватар для KaraNagai
 
Откуда: Дублин, Ирландия
Сообщений: 21,481
Благодарности: 12,152 в 4,948 сообщениях Поиск благодарностей KaraNagai
По умолчанию

афтар, ты должен получше определить что значит "чего нету в базе".
__________________
митьки никого не хотят победить
KaraNagai вне форума   Ответить с цитированием
Старый 09.10.2006, 17:28   #4
Пенсионер всея Ирландея
 
Аватар для magician
 
Откуда: StormWind city
Сообщений: 15,195
Благодарности: 9,619 в 3,376 сообщениях Поиск благодарностей magician
По умолчанию Re: SQL - Not In Range

Цитата:
Сообщение от Zindur
Есть Таблица с полем наприер Field1 данными: 1,2,3,5,9,10

Задача (тута самое интересное) :D :
получить результат: 4,6,7,8 - тоесть то что нету в базе

Извращения:
1. выборку зделать по определёным параметрам: тоесть чАво нету между 2 и 5
2. поле может быть разного типа
Ответ на лету - в базе нет всего, кроме того что там есть ..

поле разного типа ...например varchar2
в нем есть "заяц", "волк" и "лиса" ... чего там нет и что там должно быть ?

если серьезно - то какими средствами разработки нужно это определить ?
__________________
невозможно испугать санкциями того, кому похер, так,что санкции против меня на этом форуме, мне феерически похер
magician вне форума   Ответить с цитированием
Старый 10.10.2006, 07:54   #5
Просто Зануда
 
Аватар для tadpole
 
Сообщений: 7,099
Благодарности: 4,110 в 1,743 сообщениях Поиск благодарностей tadpole
По умолчанию

Zindur, SQL - это, по сути, язык для работы с множествами. В твоём примере, если я правильно понимаю, есть некое множество всех возможных чисел и некое подмножество оного, представленное таблицей. Тебе необходимо найти разность полного множества и подмножества, содержащегося в таблице. Если предположить, что всё множество состоит из целых чисел от 1 до 100 включительно, то следующий запрос выдаст искомое:
Код:
SELECT level AS field1
  FROM dual
CONNECT BY level <= 100
MINUS
SELECT field1
  FROM t
где t - твоя таблица-подмножество. Ключевое слово в данном запросе -- MINUS. Ключевой момент -- как определить полное множество. В данном примере я использовал иерархический запрос.

Теперь, если тебе надо найти "чАво нету между 2 и 5", достаточно применить WHERE-clause к вышеприведённой выборке:

Код:
SELECT *
  FROM (
          SELECT level AS field1
            FROM dual
          CONNECT BY level <= 100
          MINUS
          SELECT field1
            FROM t
       )
 WHERE field1 BETWEEN 2 AND 5
Очевидно, что в случае, когда множество является не просто набором целых чисел от X до X + n, тебе надо будет его как-то определить, о чём уже писали другие авторы выше.

P.S. Вышеприведённый примеры написаны на Oracle SQL. Я не знаю, есть ли в "MS SQL, Interbase, Access,....." иерархические запросы и inline views, но уверен, что то же самое можно выразить используя "родной" синтаксис.
tadpole вне форума   Ответить с цитированием
Старый 10.10.2006, 09:19   #6
Спам-робот
 
Аватар для YellowMan
 
Откуда: Dublin<->Брянск
Сообщений: 21,268
Благодарности: 11,080 в 5,139 сообщениях Поиск благодарностей YellowMan
По умолчанию

Мой вариант - работает везде на ANSI-SQL базах. Пример от 0 до 99 - но расширить дальше легко.Синтаксис - TSQL.

Код:
create table #tmp (int integer)

insert into #tmp
select 1 union select 2 union select 3 union select 5 union select 9 union select 10 

select f.seq from
(
Select [09].int  + [1090].int*10
           as seq
  from 
(select 1 as int union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 0) as [09] ,
(select 1 as int union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 0) as [1090]
) f left join #tmp t on t.int=f.seq
where 
t.int is null and f.seq <11

drop table #tmp

Но Zindur, наиболее правильный ответ ты уже выдал сам
Цитата:
пока вижу ответ только как, создать временную таблицу(со всеми данными) и сравнить эти таблицы.
Причем таблицу лучше создать не временную а постоянную - пригодиться во многих случаях. Заодно имеет смысл в базе всегда держать таблицу с датами на каждый день.
Только этот вариант даст 100% гарантию что код будет работать в любой ANSI-SQL совместимой базе.

Варианты с вычитанием и рекурсией тоже имеют место быть - но ИМХО это не правильно, не дело сервера баз данных заниматься вычитаниями.
Да и тормозить будет на больших объемах.
__________________
My Church is Black...
YellowMan вне форума   Ответить с цитированием
Старый 10.10.2006, 09:42   #7
Редкий собеседник
 
Сообщений: 2,663
Благодарности: 906 в 585 сообщениях Поиск благодарностей TYA
По умолчанию Re: SQL - Not In Range

Цитата:
Сообщение от TYA
...и затем исключить все записи из B, которым соответствуют записям в "рабочей" таблице по значению в поле Field1.
На самом деле, "исключить все записи из B" лучше заменить на "сделать выборку всех записей из B, которые не встречаются в "рабочей" таблице", эта выборка и будет представлять собой искомое, но это уже имплементация.
__________________
Steve Jobs:"It's better to be a pirate than to join the Navy."
-- Odyssey: Pepsi to Apple
TYA вне форума   Ответить с цитированием
Старый 10.10.2006, 09:56   #8
My name is Exaybachay
 
Аватар для KaraNagai
 
Откуда: Дублин, Ирландия
Сообщений: 21,481
Благодарности: 12,152 в 4,948 сообщениях Поиск благодарностей KaraNagai
По умолчанию

в порядке стеба:

Код:
select 
distinct (select count(1) from tblTable where field > s1.field) * (select count(1) from tblTable) + (select count(1) from tblTable where field > s2.field) 
from tblTable s1 inner join tblTable s2 on 1 = 1 where 
(select count(1) from tblTable where field > s1.field) * (select count(1) from tblTable) + (select count(1) from tblTable where field > s2.field) < 1000 and
not (select count(1) from tblTable where field > s1.field) * (select count(1) from tblTable) + (select count(1) from tblTable where field > s2.field) in
(select field from tblTable)
показывает все значения поля до 1000, которые не присутствуют в этом поле в данной таблице, при условии, что в таблице присутствует хотя бы 34 записи ;)
__________________
митьки никого не хотят победить
KaraNagai вне форума   Ответить с цитированием
Старый 10.10.2006, 11:36   #9
Заслуженный Участник
 
Аватар для Zindur
 
Откуда: из роддома
Сообщений: 1,929
Благодарности: 1,861 в 509 сообщениях Поиск благодарностей Zindur
По умолчанию

Кароче решился всётаки на так называемую временую тавлицу(ы), производительность всётаки важнее да и лехче будет адаптировать под разные базы , хотя нечего тута адаптировать
Просто вчера меня глючило и всё не как не мог решится (искал чтото замудренное) покушал пивка, прочитал "Жёлтого" - отошло.
Да и ни всем клиентам нада ето возможность, (кому надо включитса генератор таблиц - один раз. потерпит один раз пару минут, + с возможностю увеличения - зато потом всё будет красиво и быстренько)
Спасиб всем
Zindur вне форума   Ответить с цитированием
Старый 10.10.2006, 11:43   #10
My name is Exaybachay
 
Аватар для KaraNagai
 
Откуда: Дублин, Ирландия
Сообщений: 21,481
Благодарности: 12,152 в 4,948 сообщениях Поиск благодарностей KaraNagai
По умолчанию

зиндур, а желтый мэн правильно говорит: талбичку надо не временную, а постоянную имхо.
__________________
митьки никого не хотят победить
KaraNagai вне форума   Ответить с цитированием
Старый 10.10.2006, 11:46   #11
Заслуженный Участник
 
Аватар для Zindur
 
Откуда: из роддома
Сообщений: 1,929
Благодарности: 1,861 в 509 сообщениях Поиск благодарностей Zindur
По умолчанию

Цитата:
Сообщение от KaraNagai
зиндур, а желтый мэн правильно говорит: талбичку надо не временную, а постоянную имхо.
так так оно и будет просто не знал как правильнее её навАть, поентому и сказал "так называемую временную" . извиняюсь если неправильно высказался. Удалить всегда успеется
Zindur вне форума   Ответить с цитированием
Старый 10.10.2006, 12:56   #12
Активный Участник
 
Сообщений: 381
Благодарности: 100 в 76 сообщениях Поиск благодарностей DY
По умолчанию

Вот здесь еще посмотреть можно (если, конечно, это то, что нужно):

Detecting gaps and ranges of gaps in incremental number fields

http://www.sqlserverfaq.com/controls.../CodeLib/9.htm
DY вне форума   Ответить с цитированием
Старый 10.10.2006, 13:00   #13
My name is Exaybachay
 
Аватар для KaraNagai
 
Откуда: Дублин, Ирландия
Сообщений: 21,481
Благодарности: 12,152 в 4,948 сообщениях Поиск благодарностей KaraNagai
По умолчанию

DY, поиск начал и концов гапов - гораздо проще задача по той простой причине, что каждому началу и каждому концу гапа соответствует запись в таблице 1:1.
__________________
митьки никого не хотят победить
KaraNagai вне форума   Ответить с цитированием

Зарегистрируйтесь или войдите под своим именем, чтобы спрятать этот рекламный блок
Старый 10.10.2006, 17:26   #14
Заслуженный Участник
 
Откуда: Дублин
Сообщений: 1,374
Благодарности: 423 в 223 сообщениях Поиск благодарностей ерёма
По умолчанию

тоже так можно сбацать табличку с ID (1, 2, 3 и т.д.), и каким нибудь calculated field :
Код:
CREATE TABLE [t1] (
	[id] [int] IDENTITY (1, 1) NOT NULL ,
	[val] [varchar] (50)  NULL ,
	CONSTRAINT [PK_t1] PRIMARY KEY  CLUSTERED 
	(
		[id]
	)  ON [PRIMARY] 
) ON [PRIMARY]
GO


WHILE 
	(SELECT COUNT(*)
	FROM t1)< 10
BEGIN
	INSERT INTO [dbo].[t1]([val])
	VALUES (NULL)
	CONTINUE
END
ерёма вне форума   Ответить с цитированием
Старый 11.10.2006, 13:44   #15
Активный Участник
 
Сообщений: 381
Благодарности: 100 в 76 сообщениях Поиск благодарностей DY
По умолчанию

Дык я и не утверждаю, что это и есть решение. Ссылку привел, скорее, как отправную точку.

Цитата:
Сообщение от KaraNagai
DY, поиск начал и концов гапов - гораздо проще задача по той простой причине, что каждому началу и каждому концу гапа соответствует запись в таблице 1:1.
DY вне форума   Ответить с цитированием
Ответ



Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать на сообщения
Вы не можете добавлять вложения
Вы не можете редактировать свои сообщения

BB код Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT, времени сейчас: 06:01.


vBulletin®, Copyright ©2000-2025, Jelsoft Enterprises Ltd., Русификация: zCarot, Vovan & Co
©2003-2025 VirtualIreland.ru - Виртуальная Ирландия