Имя: Пароль:
1C
1С v8
Можно ли оптимизировать запрос
0 a2a4
 
18.06.13
14:34
Сделал запрос, данные выдает, но есть подозрения что можно сделать чуть проще и оптимальнее. Если так - покажите.

Исходные упрощенно.
Периодический регистр сведений. Измерение - "Шина", ресурс - "Состояние" (принимает значения - УстановленоНаАвто, УстановленоВЗапас, Снято). Необходимо получить последние даты установки (любой) и снятия. Если самое последнее значение это установка (любая), то дата снятия = NULL.

Сделал следующее

ВЫБРАТЬ
   ПоследниеДаты.Шина,
   МАКСИМУМ(ПоследниеДаты.ДатаПоследнегоСнятия) КАК ДатаСнятия,
   МАКСИМУМ(ВЫБОР
        КОГДА ЕСТЬNULL(ПоследниеДаты.ДатаПоследнейУстановки, ДАТАВРЕМЯ(1, 1, 1)) > ЕСТЬNULL(ПоследниеДаты.ДатаПоследнегоСнятия, ДАТАВРЕМЯ(1, 1, 1))
       ТОГДА ПоследниеДаты.ДатаПоследнейУстановки
            ИНАЧЕ NULL
       КОНЕЦ) КАК ДатаУстановки
ИЗ
   (ВЫБРАТЬ
       уатАгрегатыТССрезПоследних.Шина КАК Шина,
   уатАгрегатыТССрезПоследних.Период КАК ДатаПоследнейУстановки,
       NULL КАК ДатаПоследнегоСнятия
   ИЗ
       РегистрСведений.уатАгрегатыТС.СрезПоследних(СостояниеАгрегата <> ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.Снято)) КАК уатАгрегатыТССрезПоследних
   
   ОБЪЕДИНИТЬ
   
   ВЫБРАТЬ
       уатАгрегатыТССрезПоследних.Шина,
       NULL,
       уатАгрегатыТССрезПоследних.Период
   ИЗ
       РегистрСведений.уатАгрегатыТС.СрезПоследних(СостояниеАгрегата = ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.Снято)) КАК уатАгрегатыТССрезПоследних) КАК ПоследниеДаты

СГРУППИРОВАТЬ ПО
   ПоследниеДаты.Шина
1 DEVIce
 
18.06.13
14:37
Вместо ОБЪЕДИНИТЬ используй ОБЪЕДИНИТЬ ВСЕ
2 a2a4
 
18.06.13
14:49
(1) насколько помню, это не принципиально. Или есть грабли?
3 kosts
 
18.06.13
14:59
Виртуальная таблица срез предоставляет реквизит период.
По этому думаю МАКС уже не нужен.
Тогда может быть так?...


ВЫБРАТЬ
   ВЫБОР
       КОГДА СостояниеРаботниковОрганизацийСрезПоследних.Состояние = ЗНАЧЕНИЕ(Перечисление.СостоянияРаботникаОрганизации.НеРаботает)
           ТОГДА СостояниеРаботниковОрганизацийСрезПоследних.Период
       ИНАЧЕ ДАТАВРЕМЯ(1, 1, 1)
   КОНЕЦ КАК Период,
   СостояниеРаботниковОрганизацийСрезПоследних.Сотрудник,
   СостояниеРаботниковОрганизацийСрезПоследних.Состояние
ИЗ
   РегистрСведений.СостояниеРаботниковОрганизаций.СрезПоследних КАК СостояниеРаботниковОрганизацийСрезПоследних
4 Hmster
 
18.06.13
15:09
забавный период
СостояниеАгрегата = ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.Снято)
5 kosts
 
18.06.13
15:09
(3) Хотя, может не допонял, если нужно в одной строке иметь дату установки и снятия, то другому конечно нужно...
6 thargon
 
18.06.13
15:19
(2) Использование простого union вместо union all в этом запросе ошибкой не является (результат этого запроса не изменится), но на большой выборке использование union all в этом случае даст некоторый прирост производительности. Впрочем, скорее всего абсолютно незаметный глазу :)
7 kosts
 
18.06.13
15:26
Оптимизировать внешний вид (за ускорение не знаю).
Вместо внутреннего объединения, можно сделать левое соединение, с условием ДатаУстановик < ДатаСнятия.
Внешний запрос вообще не нужен будет.
К тому же ДатаСнятия автоматически станет NULL, если шина еще не снята.


Хотя я предпочитаю экранировать все NULL, что бы из запроса никогда не возвращалось NULL.
Лучше пустое значение соответствующего типа...
8 kosts
 
18.06.13
15:29
Вместо условия СостояниеАгрегата <> ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.Снято)
лучше конкретно перечислить нужные значения
СостояниеАгрегата в (ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.Установлено), ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.УстановленоВЗапас))
9 a2a4
 
18.06.13
15:33
упс, надо еще надстраивать.
Группировкой загоняем даты в одну строку, затем из получившегося выбираем с выбором того, какие даты выводить/не выводить. Да и конструкция ВЫБОР не корректна.
10 a2a4
 
18.06.13
15:34
(8) тоже связано с скоростью обработки?
11 kosts
 
18.06.13
18:06
(10) Что будет если будет добавлено еще одно состояние, например "списан", то что станет с запросом...
12 kosts
 
18.06.13
18:40
(7) Вот примерно такой запрос имел ввиду.


ВЫБРАТЬ
   уатАгрегатыТСУстановка.Шина КАК Шина,
   уатАгрегатыТСУстановка.Период КАК ДатаПоследнейУстановки,
   уатАгрегатыТСУстановка.Состояние,
   уатАгрегатыТССнятие.Период КАК ДатаСнятия
ИЗ
   РегистрСведений.уатАгрегатыТС.СрезПоследних(&ДатаАктуальности, Состояние В (ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.УстановленоВЗапас), ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.УстановленоНаАвто))) КАК уатАгрегатыТСУстановка
       ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.уатАгрегатыТС.СрезПоследних(&ДатаАктуальности, Состояние = ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.Снято)) КАК уатАгрегатыТССнятие
       ПО уатАгрегатыТСУстановка.Шина = уатАгрегатыТССнятие.Шина
           И уатАгрегатыТСУстановка.Период < уатАгрегатыТССнятие.Период
13 Jaap Vduul
 
18.06.13
18:53
ВЫБРАТЬ
   уатАгрегатыТСУстановка.Шина КАК Шина,
   МАКСИМУМ(ВЫБОР КОГДА Состояние = ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.Снято)
   ТОГДА NULL
   ИНАЧЕ уатАгрегатыТСУстановка.Период
   КОНЕЦ) КАК ДатаПоследнейУстановки,
   МАКСИМУМ(ВЫБОР КОГДА Состояние = ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.Снято)
   ТОГДА уатАгрегатыТСУстановка.Период
   ИНАЧЕ NULL
   КОНЕЦ) КАК ДатаПоследнегоСнятия
ИЗ
   РегистрСведений.уатАгрегатыТС
СГРУППИРОВАТЬ ПО
   уатАгрегатыТСУстановка.Шина
14 a2a4
 
19.06.13
11:08
(12) я в 1С сталкивался с такими несуразностями, что волосы вставали дыбом. Поэтому при возможности предусматриваю "невероятное". По Вашему варианту не будет выведено данных если "вдруг" есть информация о снятии, а вот информация об установке отсутствует.
15 a2a4
 
19.06.13
11:33
(13) не сработает. СрезПоследних даст единственную запись по шине, так как Состояние это ресурс
16 zak555
 
19.06.13
11:40
> Необходимо получить последние даты установки (любой) и снятия


ВЫБРАТЬ
  уатАгрегатыТССрезПоследних.Период КАК ДатаПоследнейУстановки

ИЗ РегистрСведений.уатАгрегатыТС.СрезПоследних() КАК уатАгрегатыТССрезПоследних

ГДЕ (уатАгрегатыТССрезПоследних.Состояние <> = ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.Снято))
17 zak555
 
19.06.13
11:43
ВЫБРАТЬ
  уатАгрегатыТССрезПоследних.Период КАК ДатаПоследнейУстановки,
  уатАгрегатыТССрезПоследних.Шина

ИЗ РегистрСведений.уатАгрегатыТС.СрезПоследних() КАК уатАгрегатыТССрезПоследних

ГДЕ (уатАгрегатыТССрезПоследних.Состояние <> ЗНАЧЕНИЕ(Перечисление.уатСостоянияАгрегатов.Снято))
18 kosts
 
19.06.13
12:08
(14) > если "вдруг" есть информация о снятии, а вот информация об установке отсутствует.

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


ВЫБРАТЬ
ЕстьNull(уатАгрегатыТСУстановка.Шина, уатАгрегатыТССнятие.Шина) КАК Шина,
...
19 kosts
 
19.06.13
12:16
(14) > > если "вдруг" есть информация о снятии, а вот информация об установке отсутствует.

Да и с другой стороны, отчеты не должны бороться с косяками целостности и непротиворечивости данных. Всё равно всех корявых случаев не предусмотреть... Это отдельная песня...
20 a2a4
 
19.06.13
13:23
(18) спасибо, то что нужно
21 a2a4
 
19.06.13
13:49
(18) только без
ПО ...  И уатАгрегатыТСУстановка.Период < уатАгрегатыТССнятие.Период

так как некорректно при ситуации установили-сняли-установили.
вынес на более верхний уровень. а так вроде все.
22 Ненавижу 1С
 
гуру
19.06.13
13:51
не надо тут подзапросов и объединений вообще, все решаемо через ВЫБОР