Имя: Пароль:
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) Это условие равносильно замене ПОЛНОГО соединения на ЛЕВОЕ, ПРАВОЕ или ВНУТРЕННЕЕ, смотря какие поля проверять))
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший