Форум на Kuban.ru (http://forums.kuban.ru/)
-   Территория 1С (http://forums.kuban.ru/f1040/)
-   -   пытаюсь придумать хитрый запрос на вычленение части таблицы (http://forums.kuban.ru/f1040/pytayus-_pridumat-_hitryj_zapros_na_vychlenenie_chasti_tablicy-2184869.html)

bma1 10.02.2012 10:42

пытаюсь придумать хитрый запрос на вычленение части таблицы
 
Есть таблица Т1:
А Б
1 1
1 2
1 3
2 1
2 2
2 3
И есть таблица Т2:
А Б
1 1
2 3
Надо получить таблицу Т3 (Т1 БЕЗ строк Т2):
А Б
1 2
1 3
2 1
2 2

Решение методом добавления в Т2 нового поля С заполненного "1", левого соединения Т1 и Т2 с выводом этого поля, а где NULL - "0" и последующим фильтром на итог соединения через ГДЕ С = 0, мне кажется недостаточно изящным... Есть что-нибудь типа ВНУТРЕННЕГО СОЕДИНЕНИЯ только наизнанку?

Lexusss 10.02.2012 10:51

ВЫБРАТЬ Т1.А, Т1.Б
ИЗ Т1 КАК Т1
ЛЕВОЕ СОЕДИНЕНИЕ Т2 КАК Т2
ПО Т1.А = Т2.А И Т1.Б = Т2.Б
ГДЕ Т2.А ЕСТЬ NULL
При этом нужно гарантировать, что в самой таблице Т2 поле А никогда не является NULL'ом.

bma1 10.02.2012 11:07

2(2) Этого нельзя гарантировать... :(

roma n 10.02.2012 11:17

Если строки внутри одной таблицы уникальны, можно дополнить первую единичкой, вторую минус единичкой объединить, сгруппировать и выдрать все где не ноль в суммируемом поле...
Только вот изящнее ли это соединения?

Lexusss 10.02.2012 11:55

ВЫБРАТЬ Т1.А, Т1.Б
ИЗ Т1 КАК Т1
ГДЕ НЕ ИСТИНА В
(ВЫБРАТЬ ПЕРВЫЕ 1 ИСТИНА
ИЗ Т2 КАК Т2
ГДЕ Т1.А = Т2.А И Т1.Б = Т2.Б
)

Производительность такого запроса надо смотреть под профайлером SQL. Не будет ли он делать чего то странного в плане выполнения. Но всяко это будет производительнее варианта roma n'а с группировкой.

bma1 10.02.2012 12:20

2(5) Стоп! А откуда она во вложенном запросе у тебя узнает, что такое Т1.А и Т1.Б? Даже без профайлера этот запрос сомнителен...

Lexusss 10.02.2012 12:23

(6) Чукча - писатель, чукча не читатель! Не?

Billi 10.02.2012 12:26

INNER JOIN наоборот :)

Reaper 10.02.2012 12:35

А почему не
ВЫБРАТЬ Т1.А, Т1.Б
ИЗ Т1 КАК Т1
ГДЕ НЕ (Т1.А, Т1.Б) В
(ВЫБРАТЬ Т2.А, Т2.Б
ИЗ Т2 КАК Т2)
?

Не нравится Exist в плане выполнения?

Lexusss 10.02.2012 12:48

(9) Мой и твой вариант в плане выполнения, по идее, будут вообще неотличимыми )))
Я не знаю про индексы и наполненность по таблицам Т1 и Т2. Бывает оптимизатор такие фокусы с просмотром по двум-трем полям выкидывает - убиться можно. Статистика то коллектится только по первому полю индекса.
Может быть, вариант с сгруппировать (или различные) окажется даже производительнее.

Мымра 10.02.2012 13:02

запрос в (9) самый правильный.

bma1 10.02.2012 13:09

2(9) Любопытный вариант. Мне нравится...

Reaper 10.02.2012 13:11

(10) Я если честно не знаю, как на плане выполнения сказывается проверка наличия записей в результате подзапроса, поэтому и сомневался. Вообще я бы если не устроит сравнение кортежей по производительности сделал объединение первой таблицы и второй с доп колонкой, в которую для первой таблицы писал бы 1, для второй -1 и сгруппировал результаты отбросив нулевой результат.

Управление торговлей 11 10.02.2012 20:33

(0) напиши потом время выполнения для элегантного и для неэлегантного запроса

bma1 10.02.2012 21:35

2(14) Запрос обрабатывает не очень большие наборы данных - вручную набранную пользователями табличную часть документа - поэтому на таких небольших объемах погрешность выше самого измеряемого параметра... Как-нибудь на выходных погоняю на искуственно созданной базе с большими объемами...
P.S. запрос был нужен для модуля проведения хитропопого документа, который размещал паллеты на ячейках (причем один паллет может занять две и более ячеек, а на одну ячейку может влезть два и более паллет... т.е. документ должен как добавлять, так и замещать и очищать ячейки от паллет. И хотелось всю эту фигню засунуть в единый запрос, чтоб он в конце выдавал готовую тадлицу для засовывания в регистр. Получилось. :)
А изящное решение требовалось, чтоб этот запрос стал покороче и более читабельный (здесь скорость не критичный показатель - размеры документов небольшие (в сутки склад может принять максимум две фуры, в фуре, максимум сорок-пятьдесят паллет - значит максимум строк за раз надо обработать - примерно сотню - мизер)).


Текущее время: 08:44. Часовой пояс GMT +3.