Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

задачка оптимальный запрос

задачка оптимальный запрос
Я
   andryscha1c
 
09.10.21 - 21:08
Есть Таблица1
Иванов
Петров
Сидоров
Бикмамбетов

Таблица2
Иванов
Петров

Можно ли получить только те записи из первой таблицы, которых нет во второй? то есть Сидоров, Бикмамбетов, использую запрос и ТОЛЬКО закладку связи соеденения без закладки условия? и как на ваш взгляд оптимальнее было бы построить запрос?
   pechkin
 
1 - 09.10.21 - 21:13
Не в (...)
   andryscha1c
 
2 - 09.10.21 - 21:25
(1) это же условие получается, сейчас речь только про связи, можно ли на том уровне отсечь записи
   Asmody
 
3 - 09.10.21 - 21:26
что оптимальнее - тебе расскажет только профайлер
   Asmody
 
4 - 09.10.21 - 21:27
(2) отсечь записи, которых нет? да вы, батенька, затейник
   andryscha1c
 
5 - 09.10.21 - 21:29
(4) отсечь записи с первой таблицы, как же нет то сынок
   RomanYS
 
6 - 09.10.21 - 21:30
(2) левое соединение и условие есть null на вторую таблицу. Без условий совсем не получится
   andryscha1c
 
7 - 09.10.21 - 21:33
(6) ну да, так и сделал. если совсем ни как без условий то вопросов нет.
это же оптимальнее будет если не использовать связи, а все сделать на уровне условий c Не в (...)?
   exwill
 
8 - 09.10.21 - 21:51
(0) В любом случае решается задача "найти все соответствия таблицы1 и таблицы2". Она может решаться быстрее или медленнее в зависимости от того есть ли подходящие индексы или их нет. Но это всегда "под капотом". Повлиять на это можно только путем создания индексов, если их нет. В вашем случае они, как видно, есть. Поэтому выбросьте из головы. Пустое это
   pechkin
 
9 - 09.10.21 - 21:54
(7) в некоторых случаях не работает быстрее чем соединение
   exwill
 
10 - 09.10.21 - 21:55
Если делать нечего. Можете попробовать объединить и сгруппировать. Результат тот же. Но вряд ли быстрее
   серый КТУЛХУ
 
11 - 09.10.21 - 21:59
ВЫБРАТЬ "Иванов" КАК Фио ПОМЕСТИТЬ втФио1
ОБЪЕДИНИТЬ ВЫБРАТЬ "Петров"
ОБЪЕДИНИТЬ ВЫБРАТЬ "Сидоров"
ОБЪЕДИНИТЬ ВЫБРАТЬ "Бекмамбетов"
;

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ "Иванов" КАК Фио ПОМЕСТИТЬ втФио2
ОБЪЕДИНИТЬ ВЫБРАТЬ "Петров"
;

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ втФио1.Фио, ВЫБОР КОГДА втФио2.Фио ЕСТЬ NULL ТОГДА 1 ИНАЧЕ 0 КОНЕЦ КАК ПрФио2
ПОМЕСТИТЬ ФиоПр
ИЗ втФио1 КАК втФио1 ЛЕВОЕ СОЕДИНЕНИЕ втФио2 КАК втФио2 ПО втФио1.Фио = втФио2.Фио
;

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ
    ФиоПр.Фио
ИЗ
    ФиоПр КАК ФиоПр
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ФиоПр КАК ФиоПр1
        ПО (ФиоПр.Фио = ФиоПр1.Фио
                И ФиоПр1.ПрФио2 = 1)
   серый КТУЛХУ
 
12 - 09.10.21 - 22:18
//или совсем короче

ВЫБРАТЬ "Иванов" КАК Фио ПОМЕСТИТЬ Фио1 ОБЪЕДИНИТЬ ВЫБРАТЬ "Петров"
ОБЪЕДИНИТЬ ВЫБРАТЬ "Сидоров" ОБЪЕДИНИТЬ ВЫБРАТЬ "Бекмамбетов" ;
ВЫБРАТЬ "Иванов" КАК Фио ПОМЕСТИТЬ Фио2 ОБЪЕДИНИТЬ ВЫБРАТЬ "Петров" ;
////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ Фио1.Фио КАК Фио, Фио2.Фио ЕСТЬ NULL КАК ПрФио ПОМЕСТИТЬ втФио
ИЗ Фио1 ЛЕВОЕ СОЕДИНЕНИЕ Фио2 ПО Фио1.Фио = Фио2.Фио ;
////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ втФио1.Фио, втФио2.Фио ЕСТЬ NULL КАК ПрФио
ИЗ втФио КАК втФио1 ВНУТРЕННЕЕ СОЕДИНЕНИЕ втФио КАК втФио2 ПО (втФио1.Фио = втФио2.Фио И втФио1.ПрФио)
   Ненавижу 1С
 
13 - 09.10.21 - 22:21
(11) ну да.
С таким же успехом я могу создавать временную таблицу с единственной записью единственного поля (это неважно) и делать внутреннее соединение исходных данных с этой таблицей. При этом всю секцию Где загонять условие связи.
Профит: без условий в секции где
   Garykom
 
14 - 09.10.21 - 22:23
(0) если ты хочешь https://oracleplsql.ru/except-sql.html

то в 1С стандартно
https://its.1c.ru/db/metod8dev/content/2499/hdoc
   acht
 
15 - 09.10.21 - 22:25
(12) Все проще

ВЫБРАТЬ
    Таблица1.ФИО
ИЗ
    Таблица1
ЛЕВОЕ СОЕДИНЕНИЕ
    Таблица2
ПО    
    Таблица1.ФИО = Таблица2.ФИО
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
(
    ВЫБРАТЬ 1
) КАК Фильтр
ПО 
    Таблица2.ФИО ЕСТЬ NULL
   acht
 
16 - 09.10.21 - 22:28
(13) Ну да, оно и есть
   Garykom
 
17 - 09.10.21 - 22:30
итого я насчитал 3 способа
интересно какой шустрей
   acht
 
18 - 09.10.21 - 22:31
(17) > какой шустрей
Зависит от исходных данных, как всегда
   серый КТУЛХУ
 
19 - 09.10.21 - 22:52
(15): (короче - но не проще) спасибо! не знал такого приема...
   GANR
 
20 - 10.10.21 - 00:18
(0) а чего глядеть то? генерируешь данные по миллиону строк, открываешь профайлер и пробуешь
   pechkin
 
21 - 10.10.21 - 14:25
давеча была задача:
Найти все элементы справочника, что не встречаются в регистре (блоками по 10000 штук)
Сначала сделал все через соединение и ЕСТЬ NULL. Тормозило. Потом переделал на НЕ В (...) залетало
   серый КТУЛХУ
 
22 - 10.10.21 - 14:33
(21): попал в индекс?..
   acht
 
23 - 10.10.21 - 15:59
(22) Операцией "НЕ" ? =)
   Dmitry77
 
24 - 10.10.21 - 16:10
Обеденить
Таблица.Фио
1 как колво

Обеденить
Таблица2. Фио
1

В вт1

Вт1.фио
Сумма(вт1.колво) 
В вт2
Группировка вт1.фио

Выбрать различные
1 как контроль
В вт3

Вт2.фио 
Внутренне соединение вт2.количество = вт3.контроль

Как то так без условий.
   acht
 
25 - 10.10.21 - 16:32
(24) Надо доработать:

ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 1 ИСТИНА КАК Контроль
В вт3

И потом
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
...
ПО
    вт3.контроль = вт2.количество = 1
   NurSagen
 
26 - 10.10.21 - 19:24
1 таблица
   Внутреннее с 1 же таблицей
    , Которая "лево" соединена со второй где фамилии не равны
   Said_We
 
27 - 15.10.21 - 14:45
(0) Как мне кажется, то на 1С оптимальнее вообще без соединения, но с условием.
Если не на 1С, то в SQL есть разность множеств - EXCEPT и соответственно есть NOT EXCEPT.
   Said_We
 
28 - 15.10.21 - 14:52
"NOT EXCEPT" - только это прям так не пишется :-)
Ща прочитал и сам понял, что могу быть не понят.
   Жан Пердежон
 
29 - 15.10.21 - 14:55
У скуля даже спец.физическая операция для твоей задачи есть: Left Anti Semi Join
Как это в запросе реализовать из названия должно быть ясно.
   Kassern
 
30 - 15.10.21 - 15:19
какой то такой изврат получился))
    Запрос=Новый Запрос;
    Запрос.Текст="ВЫБРАТЬ
                 |    ТЗ1.Имя КАК Имя
                 |ПОМЕСТИТЬ ТЗ1
                 |ИЗ
                 |    &ТЗ1 КАК ТЗ1
                 |;
                 |
                 ////////////////////////////////////////////////////////////////////////////////

                 |ВЫБРАТЬ
                 |    ТЗ2.Имя КАК Имя
                 |ПОМЕСТИТЬ ТЗ2
                 |ИЗ
                 |    &ТЗ2 КАК ТЗ2
                 |;
                 |
                 ////////////////////////////////////////////////////////////////////////////////

                 |ВЫБРАТЬ
                 |    ТЗ1.Имя КАК Имя
                 |ИЗ
                 |    ТЗ1 КАК ТЗ1
                 |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТЗ2 КАК ТЗ2
                 |        ПО (НЕ ТЗ1.Имя В
                 |                    (ВЫБРАТЬ
                 |                        ТЗ2.Имя
                 |                    ИЗ
                 |                        ТЗ2))
                 |
                 |СГРУППИРОВАТЬ ПО
                 |    ТЗ1.Имя";
 
 
   Said_We
 
31 - 15.10.21 - 15:25
(0) Без закладки условие - это на собеседовании такие вещи спрашивают что ли? :-)
Выкопайте яму руками, хотя лопата тут есть и стоит, но пользоваться ей нельзя. Но можно палкой копалкой в виде условия в JOIN.
Т.е. условие в JOIN использовать можно, а в Where нельзя? :-)

А придумать другое тестовое задание по интереснее можно? ....
   Kassern
 
32 - 15.10.21 - 15:28
(30) потестил на 10тыс записях (в каждой таблице) в сравнении с обычным:
|ГДЕ ЕСТЬNULL(ТЗ2.Имя, """") = """"";
Быстрее отрабатывает с условием Где чем в связях.
   серый КТУЛХУ
 
33 - 15.10.21 - 15:33
(30): см.(15), "все уже украли до нас" (с)
|ВЫБРАТЬ ТЗ1.Имя КАК Имя
|ИЗ ТЗ1 КАК ТЗ1
|   ЛЕВОЕ СОЕДИНЕНИЕ ТЗ2 КАК ТЗ2 ПО ТЗ1.Имя = ТЗ2.Имя
|   ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ 1) КАК Фильтр ПО ТЗ2.Имя ЕСТЬ NULL
   Kassern
 
34 - 15.10.21 - 15:34
(33) не удивлен) прост лень было всю ветку читать
   Kassern
 
35 - 15.10.21 - 15:42
Может кто объяснить, в каком случае такой подход через соединения выгоден по сравнению с обычным условием отсекающим в ГДЕ?
   eTmy
 
36 - 15.10.21 - 15:46
(35) только когда надо потешить самооценку, что смог без блока где ¯\_(ツ)_/¯
   Said_We
 
37 - 16.10.21 - 02:34
(35) Внутреннее левое соединение с небольшой таблицей и с правильными индексами. Выгоден просто визуально читать кому-то. Как правило, по скорости будет примерно тоже самое, а читать некоторым удобнее через внутреннее соединение - как фильтр читают.
JOIN - убийца производительности. Если можно без JOIN решить задачу, то надо решать без JOIN.
   xXeNoNx
 
38 - 16.10.21 - 02:37
(0) покажи свое решение
   rphosts
 
39 - 16.10.21 - 04:53
(15) очень напоминает нутро РЛС


Список тем форума
 
AdBlock убивает бесплатный контент. 1Сергей
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.