for flooders
:: Главная :: Решения :: Статьи :: Сайт М. Дроздова :: Файловый архив :: Книга по VFP 9 :: Русский Help Online :: OFF-LINE Форум
   Лисоводы   всех   стран,  объединяйтесь !!!  

Список Форумов  :: Не фоксом единым
  

SQL Server Узнать существует ли хотя бы одна запись
GotFocus
Автор

Сообщений: 1187
Откуда: Из-за угла
Дата: 27.01.13 00:15:31
Раньше узнавал скалярным запросом
1.
SELECT COUNT(*) FROM table   
  WHERE ...
проверяя возвращаемое значение на неравенство 0

Теперь хочу ускорить -
2.IF EXISTS (SELECT COUNT(*) FROM table WHERE ...)   
  2.IF EXISTS (SELECT * FROM table WHERE ...)   
      Print 'Yes'
в SSMS работает. А как это вызвать в виде скалярного запроса ? Если подставить вместо 1. строку
EXISTS (SELECT * FROM table WHERE ...)
возвращающую bool, то возникает ошибка.

А может есть по-лучше способ определения наличия записи в таблице ?



Исправлено: GotFocus, 27.01.13 17:44
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
PaulWist

Сообщений: 13344
Дата: 27.01.13 09:51:12
GotFocus
Раньше узнавал скалярным запросом
1.
SELECT COUNT(*) FROM table   
  WHERE ...
проверяя возвращаемое значение на неравенство 0

Теперь хочу ускорить -
2.
IF EXISTS (SELECT COUNT(*) FROM table WHERE ...)   
      Print 'Yes'
в SSMS работает. А как это вызвать в виде скалярного запроса ? Если подставить вместо 1. строку
EXISTS (SELECT COUNT(*) FROM table WHERE ...)
возвращающую bool, то возникает ошибка.

А может есть по-лучше способ определения наличия записи в таблице ?

1. Из прямого запроса никак только через select:

IF EXISTS (SELECT COUNT(*) FROM table WHERE ...)     
       select cast(1 as bit) Exists

2. из ХП через output параметр, см ФАК.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
ssa

Сообщений: 12561
Откуда: Москва
Дата: 27.01.13 12:32:52
1. Зачем тут count(*)?
2. В МЫ SQL нет булевого типа данных и вернуть его невозможно.
3. Как вариант возможного решения:
select case when exists(select * from spt_values) then '1' else '2' end


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
Penner

Сообщений: 4096
Откуда: Muenster
Дата: 27.01.13 12:36:02
  
  select 1 as nn where EXISTS (SELECT * from Table)


------------------
Никогда не откладывайте на завтра, то, о чем можно забыть навсегда
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
GotFocus
Автор

Сообщений: 1187
Откуда: Из-за угла
Дата: 27.01.13 17:41:13
ssa
1. Зачем тут count(*)?
Опечатка - исправил в 1-ом сообщении

Обязуюсь до конца следующей недели сравнить по скорости все 3 предложенных варианта(проверил - все работают) + вариант с ХП
  
  1. select cast(1 as bit) where Exists(SELECT * FROM table WHERE ...)  
    
  2. select case when exists(select * from table WHERE ...) then '1' else '2' end    
    
  3. select 1 as nn where EXISTS (SELECT * from table WHERE ...)
и сообщить

Всем спасибо ! Если есть ещё варианты - предлагайте.
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
Igor Korolyov

Сообщений: 33513
Дата: 28.01.13 16:10:54
select top 1 * from ...
В зависимости от запроса это может оказаться не менее эффективно чем EXISTS.

Хотя, как всегда, встаёт вопрос - на кой нужно такое "знание". Если тебе нужны данные - ты и запрашивай САМИ данные (возможно принудительно ограничивая размер выборки, чтобы не тянуть 100500 записей) - а просто сам факт "ну там что-то есть"... Обычно он бесполезен "сам по себе" - т.е. всё равно последует запрос данных - а раз так, то зачем "лишний" запрос "а есть ли там данные"...


------------------
WBR, Igor
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
PaulWist

Сообщений: 13344
Дата: 28.01.13 16:34:12
Igor Korolyov
select top 1 * from ...
В зависимости от запроса это может оказаться не менее эффективно чем EXISTS.

Хотя, как всегда, встаёт вопрос - на кой нужно такое "знание". Если тебе нужны данные - ты и запрашивай САМИ данные (возможно принудительно ограничивая размер выборки, чтобы не тянуть 100500 записей) - а просто сам факт "ну там что-то есть"... Обычно он бесполезен "сам по себе" - т.е. всё равно последует запрос данных - а раз так, то зачем "лишний" запрос "а есть ли там данные"...

Ну, это ты зря, в триггерах для ссылочной целостности такое сплошь и рядом.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
Igor Korolyov

Сообщений: 33513
Дата: 28.01.13 18:00:16
А при чём тут триггера? Триггера это T-SQL, и там нет проблем написать IF EXISTS (...) Речь то шла о том как из клиентского кода "это" получить
Впрочем, как часто нужно писать триггера для проверки RI, учитывая что MSSQL поддерживает декларативный RI, и даже с "каскадными" расширениями типа ON DELETE CASCADE...
IMHO это либо очень редкие исключения для сложных/нетривиальных структур данных, либо проектировщик БД которого нужно немедленно увольнять


------------------
WBR, Igor
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
GotFocus
Автор

Сообщений: 1187
Откуда: Из-за угла
Дата: 28.01.13 19:18:56
Результаты тестирования по скорости
Использовал таблицу BigTable - около 8 млн записей - 4 столбца, один из них - column1 - float без ключей. В нём значения от 1 до 7500000. При создании таблицы в каждой добавляемой записи его значение увеличивалось на 1.

Думал, что буду сравнивать предложенные варианты. Да не тут-то было. Пришлось сравнивать 4 варианта(все они примерно одинаковые по скорости) с COUNT(*)

1. Рассматриваем записи начиная с 333. Как видим COUNT(*) отдыхает, потому что до искомых записей рукой подать
[attachment 15385 ÑíèìîêBB1.PNG]

2. Рассматриваем записи начиная с 4444444. Конечно COUNT(*) нашёл всего 86224 записей против 7835246 в 1. и поэтому быстрее(но всего лишь в два раза). Но что случилось с вариантами с EXISTS и с 4-ым ? Понятно, что скорость поиска записи должна была уменьшиться - ведь далеко от начала таблицы. Но почему выиграл COUNT(*) в 3 раза - непонятно
[attachment 15386 ÑíèìîêBB2.PNG]

Подумал, что может быть не использовать SELECT ... EXISTS, а использовать ХП, в которой будет что-то вроде if EXISTS (SELECT * FROM BigTable WHERE column1>4444444) - но в SSMS - те же 3 сек

Так что моя мечта, увидеть этакую COUNT_X, которая встретив первую удовлетворяющую условию запись бросает подсчёт и возвращает 1, пока не осуществилась

Неужели нет ничего, что будет всегда находить 1 запись быстрее COUNT(*) ?



Исправлено: GotFocus, 29.01.13 22:54
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
ssa

Сообщений: 12561
Откуда: Москва
Дата: 29.01.13 00:30:47
Оптимизация запросов - отдлельная большая тема. У запросов нет жестко зафиксированного вермени исполнения, план выполнения запроса может меняться в любое время в зависимости от кучи условий и потому твои попытки сравнить сферических коней, как и попытки найти абсолют, совершенно бессмыселенны.


------------------
Лень - это неосознанная мудрость.
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
Аспид

Сообщений: 3378
Откуда: Москва
Дата: 29.01.13 08:40:10
GotFocus
[b]...
Неужели нет ничего, что будет всегда находить 1 запись быстрее COUNT(*) ?

select  top 1 column1 from table where ...

Ну и если EXISTS, то именно покажет просто есть или нет.
  
  IF EXISTS (SELECT top 1 column1 FROM table WHERE ...)     
        Print 'Yes'
Мне кажется, в общем случае, самый быстрый вариант. Т.к. ищется первая же подходящая запись, и все.
Может и ошибаюсь.


------------------




Исправлено: Аспид, 29.01.13 08:41
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
PaulWist

Сообщений: 13344
Дата: 29.01.13 09:12:29
Igor Korolyov
...
Впрочем, как часто нужно писать триггера для проверки RI, учитывая что MSSQL поддерживает декларативный RI, и даже с "каскадными" расширениями типа ON DELETE CASCADE...
IMHO это либо очень редкие исключения для сложных/нетривиальных структур данных, либо проектировщик БД которого нужно немедленно увольнять

Хорошо, Игорь.

Теперь скажи какой "стандарный" RI (FK) навесить на пару "таблица" - "справочник", если надо создать запись в "таблице", PK справочника занести потом:

create table Dictionary (f1 int  PRIMARY KEY )  
    
  create table [table] (f1 int  FOREIGN KEY REFERENCES Dictionary (f1) )


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
Igor Korolyov

Сообщений: 33513
Дата: 29.01.13 15:31:05
PaulWist
Теперь скажи какой "стандарный" RI (FK) навесить на пару "таблица" - "справочник", если надо создать запись в "таблице", PK справочника занести потом:
Такой же как и в случае если сразу заполняется FK - только это поле должно дополнительно допускать NULL-ы (оно как раз и будет содержать NULL до момента заполнения). При этом я совершенно не вижу чем тут поможет самописный триггер - он точно так же должен проверять запись в момент её создания, а не "потом, когда будет заполняться поле FK, если оно вообще будет заполняться..." И куда как логичнее использовать в качестве "незаполненного значения" NULL - который корректно обрабатывается декларативным RI констрейном, чем какое-то "волшебное значение" осгобым образом обрабатываемое самописным RI триггером.
create table Ref (RefID int PRIMARY KEY, Name varchar(100));  
  create table Main (MainID int PRIMARY KEY, RefID int REFERENCES Ref(RefID), SomeData varchar(100));  
  insert into Main (MainID, SomeData) VALUES (1, 'пустой');  
  insert into Ref (RefID, Name) VALUES (100, 'справочная 100');  
  update Main set RefID = 100, SomeData = 'непустой' where MainID = 1;  
  insert into Main (MainID, RefId, SomeData) VALUES (2, 100, 'изначально непустой');  
  --Нижеуказанные команды не пройдут из-за ограничений RI  
  insert into Main (MainID, RefId, SomeData) VALUES (3, 101, 'некорректный');  
  update Main set RefID = 101 where MainID = 1;

2 GotFocus
Делать для огромной таблицы запрос с условием вида column1 op значение и НЕ делать при этом индекса по данному полю, конечно же можно... Но вот делать на основе этого какие либо далеко идущие выводы - совершенно бессмысленно. Точно так же не следует думать:
- что "физически" записи хранятся в том порядке в котором они создавались.
- что при выборке (без использования индексов) записи просматриваются в каком то определённом порядке (физическом, или логическом).
- что запрос SELECT TOP 1 * FROM table WHERE column1 > 123 вернёт запись у которой column1 будет минимальным из всех тех у которых значение > 123. Вообще с точки зрения формальной логики SQL-я запрос с TOP нуждается в опции ORDER BY - иначе его результат абсолютно непредсказуем.
А вот на что следовало бы обратить внимание, так это на планы исполнения соответствующих запросов - вероятнее всего все 4 "кандидата" имеют в своей основе один и тот же план (точнее самая "тяжелая" часть запроса - сканирование этой большой таблицы БЕЗ индекса НО до первого "нахождения" - будет идентичной, а вот мелочи связанные с "обвеской" каждого конкретного запроса будут различаться). Для COUNT(*), естественно, никакой "остановки при первом же нахождении" быть не может.
P.S. 1 и 3 варианты в принципе ничем не различаются.


------------------
WBR, Igor
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
PaulWist

Сообщений: 13344
Дата: 29.01.13 16:10:06
Igor Korolyov
PaulWist
Теперь скажи какой "стандарный" RI (FK) навесить на пару "таблица" - "справочник", если надо создать запись в "таблице", PK справочника занести потом:
Такой же как и в случае если сразу заполняется FK - только это поле должно дополнительно допускать NULL-ы .

Точно, совсем забыл с этими триггерами

Тем не менее, триггер RI тоже нужен, например когда надо выдать "человеческое" сообщение на клиента, минуя обработчик ошибок клиента.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
Igor Korolyov

Сообщений: 33513
Дата: 29.01.13 17:45:00
PaulWist
Тем не менее, триггер RI тоже нужен, например когда надо выдать "человеческое" сообщение на клиента, минуя обработчик ошибок клиента.
Сомневаюсь. Это уж скорее нужен набор CRUD процедур который "прячет" прямую работу с таблицей - и это совсем другая "тема". А триггере не должен, да и не может адекватно "озвучивать" ошибки (какую, кстати из "множества возникших" он должен озвучить для команды update Main set RefID = RefId+1 ?)... При том декларативный RI наверняка и работает быстрее чем сходный RI триггер.


------------------
WBR, Igor
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
PaulWist

Сообщений: 13344
Дата: 31.01.13 09:11:02
Igor Korolyov
PaulWist
Тем не менее, триггер RI тоже нужен, например когда надо выдать "человеческое" сообщение на клиента, минуя обработчик ошибок клиента.
Сомневаюсь. Это уж скорее нужен набор CRUD процедур который "прячет" прямую работу с таблицей - и это совсем другая "тема". А триггере не должен, да и не может адекватно "озвучивать" ошибки (какую, кстати из "множества возникших" он должен озвучить для команды update Main set RefID = RefId+1 ?)... При том декларативный RI наверняка и работает быстрее чем сходный RI триггер.

Если триггер написан для проверки RI конкретного PK (понятно, что триггер должен быть FOR DELETE-UPDATE-INSERT), то именно эту ошибку он должен вернуть, другие PK проверяются другими триггерами, исключением может быть только ошибки среды выполнения, но их должены ловить либо ХП сервера, либо клиент.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
LED

Сообщений: 198
Дата: 27.10.16 00:20:24
Подскажите как решить вот такую как бы можно сказать задачу...

Dtp – дата
okID - номер

Ищем наименьшую и наибольшую дату получения товара по его номеру
SELECT Min(dtp),Max(dtp) FROM _nfile WHERE okID=okID1



Получаем 2 поля:
Min_dtp и Max_dtp

Если товара в базе нет получаем .ISNULL. в этих полях



Чтобы избавиться от .ISNULL.
Создал вот такую конструкцию:
SELECT Min(dtp),Max(dtp) WHERE NOT EXISTS (SELECT * FROM _nfile WHERE okID=okID1)
Не получается, появляется окно с предупреждением, что неправильное выражение.
Подскажите как избавиться от .ISNULL.
Т.е. надо создать такой запрос, чтобы при получении .ISNULL. можно было
Вывести, что нет такого номера товара в базе (нет такого товара)
Применил EXISTS для обнаружения .ISNULL. но почему то не получается.

Как составить запрос?
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
ВладимирС

Сообщений: 1360
Дата: 27.10.16 06:19:10
LED
Подскажите как решить вот такую как бы можно сказать задачу...
Dtp – дата
okID - номер

Ищем наименьшую и наибольшую дату получения товара по его номеру
SELECT Min(dtp),Max(dtp) FROM _nfile WHERE okID=okID1



Получаем 2 поля:
Min_dtp и Max_dtp

Если товара в базе нет получаем .ISNULL. в этих полях



Чтобы избавиться от .ISNULL.
Создал вот такую конструкцию:
SELECT Min(dtp),Max(dtp) WHERE NOT EXISTS (SELECT * FROM _nfile WHERE okID=okID1)
Не получается, появляется окно с предупреждением, что неправильное выражение.
Подскажите как избавиться от .ISNULL.
Т.е. надо создать такой запрос, чтобы при получении .ISNULL. можно было
Вывести, что нет такого номера товара в базе (нет такого товара)
Применил EXISTS для обнаружения .ISNULL. но почему то не получается.

Как составить запрос?
Так подойдет ?
SELECT ISNULL(Min(dtp),0),ISNULL(Max(dtp),0) FROM _nfile WHERE okID=okID1
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
LED

Сообщений: 198
Дата: 27.10.16 09:23:29
SELECT ISNULL(Min(dtp),0),ISNULL(Max(dtp),0) FROM _nfile WHERE okID=okID1
Не работает. Пишет ошибку



Исправлено: LED, 27.10.16 09:23
Ratings: 0 negative/0 positive

Re: SQL Server Узнать существует ли хотя бы одна запись
Аспид

Сообщений: 3378
Откуда: Москва
Дата: 27.10.16 09:48:01
Человек синтаксис MS привел.
В фоксе NVL
  
  SELECT NVL(Min(dtp),0),NVL(Max(dtp),0) FROM _nfile WHERE okID=okID1
И не плохо б приводить текст ошибки. А заодно и читать.
Из нее все понятно будет.

Но не думаю что сама идея такого запроса верна.
Потому как вернет запись все равно, просто вместо поля date будет int

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


------------------




Исправлено: Аспид, 27.10.16 09:51
Ratings: 0 negative/0 positive



Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 14 Taran  (Гостей: 13)

05.07.2020 06:17:12 exec: 0.23
Mem: 1.537 Mb

© 2000-2020 Fox Club 
Яндекс.Метрика