Имя: Пароль:
1C
1С v8
Что-то с запросом непонятное.
,
0 Полька
 
29.01.15
10:47
Запрос.Текст="ВЫБРАТЬ
                 |    СпецТовары.Номенклатура КАК Номенклатура,
                 |    СпецТовары.ЕдиницаИзмерения,
                 |    СпецТовары.Количество КАК КоличествоСпец,
                 |    ЗаявкаТовары.Количество КАК КоличествоЗаказано
                 |ИЗ
                 |    Документ.Спец.Товары КАК СпецТовары
                 |        ПОЛНОЕ СОЕДИНЕНИЕ Документ.Заявка.Товары КАК ЗаявкаТовары
                 |        ПО СпецТовары.Номенклатура = ЗаявкаТовары.Номенклатура
                 |ГДЕ
                 |    СпецТовары.Ссылка.Проведен = ИСТИНА
                 |    И ЗаявкаТовары.Ссылка.Проведен = ИСТИНА";
В Документе "Спец" 6 позиций номенклатуры. В нескольких документах "Заявка" отражены 5 позиций номенклатуры.
Я так понимаю, что при полном соединении должно попасть ВСЕ.
А вот та позиция, что есть в "Спец", но нет в "Заявке" - не попадает.
1 Любопытная
 
29.01.15
10:50
Так выбираются только СпецТовары, а потом на них еще условие накладывается. Все лишнее и убирается
2 ShoGUN
 
29.01.15
10:50
(0) Строка условием отфильтрована. При полном соединении либо  СпецТовары.Ссылка.Проведен, либо ЗаявкаТовары.Ссылка.Проведен будет NULL. Условие убери и убедись.
3 Полька
 
29.01.15
10:52
Как раз СпецТовары и не выбираются все.
4 Любопытная
 
29.01.15
10:54
(3) убери условие и посмотри, что получается
5 ShoGUN
 
29.01.15
10:54
(3) Прочитай (2)
6 ktvladimir
 
29.01.15
10:56
убери условия и посмотри результирующую таблицу... и добавь в поля ЗаявкаТовары.Номенклатура... увидишь какая картинка. потом понакладываю ограничения и думай
7 Полька
 
29.01.15
10:58
Если уберу условие- полезут непроведенные доки "Спец", которые совсем не нужны
8 ShoGUN
 
29.01.15
10:59
(7) Ну так думать надо, прежде чем запросы к документам делать.
9 Полька
 
29.01.15
10:59
(8) А какие варианты?
10 ShoGUN
 
29.01.15
10:59
А условие предлагается убрать, чтобы понятнее стало.
11 ShoGUN
 
29.01.15
11:00
(9) Вариант "подумать" не предлагать?
12 Полька
 
29.01.15
11:01
(11) нАД ЧЕМ ДУМАТЬ, ЕСЛИ ЭТУ ИНФУ БОЛЬШЕ, КАК В ДОКЕ ВЗТЬ НЕГДЕ
13 ShoGUN
 
29.01.15
11:01
Я понятия не имею, почему нужно выбирать данные из ТЧ документа, при этом объединять его с другим документом, да ещё таким странным способом(все со всеми).
14 Любопытная
 
29.01.15
11:02
(12) убери проверку хотя бы на заявку. Т.к. в результирующей  таблице она упоминается только в тех строках, где ее нет, а значит это условие не выполнится
15 ShoGUN
 
29.01.15
11:03
(12) Регистры не для настоящих Полек. И выбрать два КОНКРЕТНЫХ документа - тоже не для настоящих Полек... Надо мучать себя и нас.
16 Полька
 
29.01.15
11:05
(15) Нет данных в регистрах! Есть 2 вида самописных доков.
17 ShoGUN
 
29.01.15
11:05
(16) Я оченно опечален. По счастью, это твоя проблема, а не моя.
18 deniseek
 
29.01.15
11:06
(0) Разбей на 2 таблицы по отдельности, с условием проведен, каждую помести в Вт, а потом выбирай их полным соединением.
19 ShoGUN
 
29.01.15
11:07
+(17) Проблем у этого запроса в действительности, намного больше, в (0) - наименьшая из них.
20 Полька
 
29.01.15
11:16
т.е. лучше создать регистры для этих доков?
21 ShoGUN
 
29.01.15
11:17
(20) Зависит от того, что ты хочешь получить. При нормальном проектировании не требуется соединять табличные части двух документов друг с другом.
22 GANR
 
29.01.15
11:18
(0) Условиями в секции ГДЕ на обе таблицы полное соединение превращается во внутреннее - NULL-ы режутся.
23 salvator
 
29.01.15
11:21
(0)
ГДЕ
   ВЫБОР КОГДА СпецТовары.Ссылка ЕСТЬ NULL ТОГДА ЗаявкаТовары.Ссылка.Проведен
   ИНАЧЕ СпецТовары.Ссылка.Проведен
   КОНЕЦ
24 ShoGUN
 
29.01.15
11:24
(23) Правильно, надо решать вопрос костылями!
Как решать проблему того, что в базе может быть больше двух проведённых документов, и номенклатура может быть одинаковая где-то?
25 ktvladimir
 
29.01.15
12:02
и единицы измерения могу быть разными.. с разными коэффициентами
26 ktvladimir
 
29.01.15
12:10
"ВЫБРАТЬ
|    СпецТовары.Номенклатура КАК Номенклатура,
|    СУММА(СпецТовары.Количество * СпецТовары.ЕдиницаИзмерения.Коэффициент /
СпецТовары.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент) КАК КоличествоСпец
|Поместить СпецТовары
|ИЗ
|    Документ.Спец.Товары КАК СпецТовары
|ГДЕ
|   СпецТовары.Ссылка.Проведен
|СГРУППИРОВАТЬ ПО
|    СпецТовары.Номенклатура
|;
|ВЫБРАТЬ
|    ЗаявкаТовары.Номенклатура КАК Номенклатура,
|    СУММА(ЗаявкаТовары.Количество * ЗаявкаТовары.ЕдиницаИзмерения.Коэффициент /
ЗаявкаТовары.Номенклатура.ЕдиницаХраненияОстатков.Коэффициент) КАК КоличествоЗаказано
|Поместить ЗаявкаТовары
|ИЗ
|    Документ.Заявка.Товары КАК ЗаявкаТовары
|ГДЕ
|   ЗаявкаТовары.Ссылка.Проведен
|СГРУППИРОВАТЬ ПО
|    ЗаявкаТовары.Номенклатура
|;
|ВЫБРАТЬ
|    ЕстьNULL(СпецТовары.Номенклатура, ЗаявкаТовары.Номенклатура) КАК Номенклатура,
|    ЕстьNULL(СпецТовары.КоличествоСпец,0) КАК КоличествоСпец,
|    ЕстьNULL(ЗаявкаТовары.КоличествоЗаказано,0) КАК КоличествоЗаказано
|ИЗ
|    ЗаявкаТовары
|        ПОЛНОЕ СОЕДИНЕНИЕ СпецТовары
|    ПО СпецТовары.Номенклатура = ЗаявкаТовары.Номенклатура"



как то так.. синтаксис если что это уж сами. я запрос руками писал
27 ShoGUN
 
29.01.15
12:13
(26) Тебя на смущает, что это всё равно "все со всеми"?
28 ktvladimir
 
29.01.15
12:17
(27) неа не смущает, ей и нужно чтоб попало ВСЕ
29 Timon1405
 
29.01.15
12:22
ВЫБРАТЬ
   СпецТовары.Номенклатура КАК Номенклатура,
   СпецТовары.ЕдиницаИзмерения,
   СпецТовары.Количество КАК КоличествоСпец,
   ЗаявкаТовары.Количество КАК КоличествоЗаказано
   ИЗ
   Документ.Спец.Товары КАК СпецТовары
   ПОЛНОЕ СОЕДИНЕНИЕ Документ.Заявка.Товары КАК ЗаявкаТовары
   ПО (СпецТовары.Номенклатура = ЗаявкаТовары.Номенклатура  И
   СпецТовары.Ссылка.Проведен = ИСТИНА
   И ЗаявкаТовары.Ссылка.Проведен = ИСТИНА)
30 Зеленый пень
 
29.01.15
12:29
(29) Наконец кто-то заметил, что условие должно быть в "ПО", а не в "ГДЕ"
31 Крошка Ру
 
29.01.15
12:48
(0)Даже отвлекаясь от таких изысков как в (29)...

Собственно. Условие накладывается на обе таблицы одновременно.
Почему туда должны попадать строки которые не удовлетворяют одному из условий? Строка, которая отсутствует в "Заявках" явно не удовлетворяет условию "ЗаявкаТовары.Ссылка.Проведен = ИСТИНА"(без разницы Null там или другое какое значение). И не важно где при этом накладывается условие. В запрос из (29) строка без заявки так же не попадет.
32 ShoGUN
 
29.01.15
12:51
(31) Попадет. И с ней еще куча всякой фигни попадет. Например, строки из непроведенных документов.
33 Крошка Ру
 
29.01.15
12:55
(32) Расшифруй.

Как туда попадет непроведенный(или тем более Null), если условие на соединение подразумевает только проведенные документы?
34 ShoGUN
 
29.01.15
13:00
(33) Это ПОЛНОЕ соединение. А условие на соединение, а не на выборку из каждой таблицы. Строки, которые условию не соответствуют - попадут в результат запроса с данными только из одной таблицы, не соответствующими условию.
35 ktvladimir
 
29.01.15
13:13
(34) заинтересовало. сделал у себя пример... но что то долго выполняется такой запрос..... ушел думать)
36 Крошка Ру
 
29.01.15
13:15
(34) Хмм... верно...

В принципе - да, условие которое накладывается только на одну таблицу, на другую никак не влияет, т.к. связи между строками до соединения нет.
Не задумывался раньше об этом.
Все-таки на мисту иногда полезно вылазить))
37 ShoGUN
 
29.01.15
13:31
(35)(36) В принципе в (26) нормальное решение, по крайней мере мысль правильная - условия на проведенность применять к каждой выборке в отдельности. Но я бы сделал вложенными запросами, т.к. здесь нет многократного использования таблиц, а на создание временных таблиц время тратится.
38 ShoGUN
 
29.01.15
13:33
И это не отменяет того, что тут ошибка проектирования, и подобного гемора будет еще много с такими входными данными.
39 ktvladimir
 
29.01.15
13:36
по (29) лажово получается сделал тест


ВЫБРАТЬ
    Док1.Ссылка,
    Док1.Проведен
ПОМЕСТИТЬ Врем
ИЗ
    Документ.Док1 КАК Док1
ГДЕ
    Док1.Дата МЕЖДУ &Дата И &Дата2
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Док2.Ссылка,
    Док2.Проведен
ПОМЕСТИТЬ Врем2
ИЗ
    Документ.Док2 КАК Док2
ГДЕ
    Док2.Дата МЕЖДУ &Дата3 И &Дата4
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Врем.Ссылка,
    Врем.Проведен,
    Врем2.Ссылка КАК Ссылка1,
    Врем2.Проведен КАК Проведен1
ИЗ
    Врем КАК Врем
        ПОЛНОЕ СОЕДИНЕНИЕ Врем2 КАК Врем2
        ПО (НЕ Врем.Проведен)
            И (не Врем2.Проведен)



получаем результат
Ссылка    Проведен    Ссылка1    Проведен1
NULL    NULL    Док2  0000502 от 09.12.2014 12:31:57    Да
NULL    NULL    Док2  0001969 от 09.12.2014 14:00:11    Да
NULL    NULL    Док2  0001116 от 09.12.2014 14:07:58    Да
NULL    NULL    Док2  0001970 от 09.12.2014 15:01:02    Да
NULL    NULL    Док2  0000503 от 09.12.2014 17:27:47    Да
Док1 000863973 от 09.12.2014 17:28:45    Нет    Док2  0001971 от 09.12.2014 17:57:04    Нет
Док1  000863657 от 09.12.2014 17:30:05    Нет    Док2  0001971 от 09.12.2014 17:57:04    Нет
NULL    NULL    Док2  0001972 от 09.12.2014 18:24:13    Да
NULL    NULL    Док2 000504 от 10.12.2014 10:09:54    Да
Док1  000863925 от 09.12.2014 17:00:08    Да    NULL    NULL
Док1  000863926 от 09.12.2014 17:00:22    Да    NULL    NULL
40 ShoGUN
 
29.01.15
13:38
(39) Любитель временных таблиц, полюби уже вложенные запросы, и различай, когда одно лучше, а когда другое :)
41 ktvladimir
 
29.01.15
13:42
я делаю временные чтоб посмотреть на каждом этапе весь ход действий. смысл сейчас не в использовании вт а в некорректных данных которые получить пользователь при выссталении таких ограничений
42 ktvladimir
 
29.01.15
13:43
p/s/ я люблю ВТ за их наглядность. Да когда нужна оптимизация ищем баланс между ВТ и ВЗ, а на этапе тестирования мне удобнее ВТ использовать
43 ShoGUN
 
29.01.15
13:45
(41) С этим согласен. Условия надо применять к выборкам по отдельности. Но ещё раз говорю - каждый раз, когда надо анализировать флаг "проведён" на постоянной основе и делать объединения табличных частей двух объектов - надо отдавать себе отчет "что-то я тут налажал".
44 Крошка Ру
 
29.01.15
14:00
(40) Использовать вложенные запросы для последующего их соединения не есть хорошо, может быть выбран неоптимальный алгоритм соединения, т.к. заранее размер выборки неизвестен, а у ВТшек он определяется.
45 ktvladimir
 
29.01.15
14:02
что то я уже сам не вкуриваю

ВЫБРАТЬ
    Врем.Ссылка,
    Врем.Проведен,
    Врем2.Ссылка КАК Ссылка1,
    Врем2.Проведен КАК Проведен1
ИЗ
    (ВЫБРАТЬ
        Док1.Ссылка КАК Ссылка,
        Док1.Проведен КАК Проведен
    ИЗ
        Документ.Док1 КАК Док1
    ГДЕ
        Док1.Дата МЕЖДУ &Дата И &Дата2) КАК Врем
        ПОЛНОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
            Док2.Ссылка КАК Ссылка,
            Док2.Проведен КАК Проведен
        ИЗ
            Документ.Док2 КАК Док2
        ГДЕ
            Док2.Дата МЕЖДУ &Дата3 И &Дата4) КАК Врем2
        ПО (НЕ Врем.Проведен)


смотрим результата

Док1 1 от 09.12.2014 Не проведен    Док2 1 от 10.12.2014    Проведен
Док1 2 от 09.12.2014 Проведен    NULL    NULL


как попадает вторая запись?
46 Крошка Ру
 
29.01.15
14:15
(45) Это не условие отбора, а условие соединения. Те строки, которые не подходят, не соединяются, но в выборку попадают
47 ShoGUN
 
29.01.15
14:26
(45) ВТ везде использовать тоже не есть хорошо, т.к. это выборка-запись-выборка. И неизвестно, что быстрее будет.
48 ShoGUN
 
29.01.15
14:32
(47) к (46)
(45) Не используй полное соединение, если не уверен, что тебе нужно именно оно. Внутреннее и Левое гораздо более предсказуемые :) В полном соединении ошибка в условии фатальна.
49 Timon1405
 
29.01.15
14:35
(46) Короче, "Где НЕ МоеПоле ЕСТЬ NULL" надо писать в конце, чтобы их убрать, так?
50 Крошка Ру
 
29.01.15
14:46
(49) Это условие равносильно замене ПОЛНОГО соединения на ЛЕВОЕ, ПРАВОЕ или ВНУТРЕННЕЕ, смотря какие поля проверять))
Есть два вида языков, одни постоянно ругают, а вторыми никто не пользуется.