|
1С:Предприятие
:: 1С:Предприятие 8 общая
|
|
| ||
Kozitsyn 23.11.20 - 16:46 | Приветствую, коллеги! )
Cкрин обычного периодического рег. сведений с одним измерением - https://yadi.sk/i/Qqv4qRyGDIQwfg Необходимо в рамках запроса выбрать только начальные даты по всем подряд записанным физ.лицам, чтобы получилось вот так: 03.11.2020 | Бельдыев 09.11.2020 | Лоханкина 22.11.2020 | Бельдыев Группировку и минимум по дате, а также срезы не предлагать, тогда мы потерям второго Бельдыева :) Возможно ли такое сделать в рамках запроса? | ||
acht 1 - 23.11.20 - 16:48 | выбрать минимум(период), физик сгрупировать по физик | ||
acht 2 - 23.11.20 - 16:49 | Иначе твое 03.11.2020 | Бельдыев09.11.2020 | Лоханкина 22.11.2020 | Бельдыев Противоричит постановке. | ||
Kozitsyn 3 - 23.11.20 - 16:50 | (1) тогда мы потерям второго Бельдыева (2) не противоречит - "по всем ПОДРЯД записанным физ.лицам" | ||
БаксПо90 4 - 23.11.20 - 16:50 | Т.е. вторую лоханкину можно потерять а бельдыева нельзя .. | ||
Малыш Джон 5 - 23.11.20 - 16:50 | (0) можно, но непроизводительно | ||
Cthulhu 6 - 23.11.20 - 16:51 | различные | ||
Kozitsyn 7 - 23.11.20 - 16:51 | (4) вторая Лоханкина идет ПОДРЯД, ее как раз не нужно выводить, а вот второй Бельдыев записан уже после Лозанкиной и его нужно оставить - только первую дату | ||
Kozitsyn 8 - 23.11.20 - 16:53 | (6) что "различные" ? тогда опять же второго Быльдыева грохнем, а он нужен | ||
PuhUfa 9 - 23.11.20 - 16:54 | (7) а в чем тайный смысл сего действия? мне чисто для себя... | ||
Kozitsyn 10 - 23.11.20 - 16:55 | (9) в рег. сведений записывается периодически определённые статусы (я сильно упростил задачу) и они могут много раз повторяться одни и те же подряд, вот от этого "подряд" нужно избавиться. понятное дело, что тут проще переделать регистр, чтобы в него вприципе не записывались подряд одни и теже данные, но пока вопрос в другом | ||
RomanYS 11 - 23.11.20 - 16:55 | (0) так одно измерение или ресурс? | ||
Kozitsyn 12 - 23.11.20 - 16:56 | (11) Измерение - физ. лицо | ||
RomanYS 13 - 23.11.20 - 16:57 | (0)
Засунуть в ВТ, пронумеровать записи,
соединить записи со следующей по номеру,
отфильтровать лишние (повторяющиеся) записи | ||
Малыш Джон 14 - 23.11.20 - 16:58 | (13) нумеровать лишнее | ||
Cthulhu 15 - 23.11.20 - 16:58 | » | ||
Kozitsyn 16 - 23.11.20 - 16:59 | (13) а если ПОДРЯД таких строк будут сотни (с одним физиком и разыми датами), прокатит этот вариант? | ||
RomanYS 17 - 23.11.20 - 16:59 | +(13) без нумерации придётся группировать с минимум(Рег2.Период) и ещё односоединение | ||
RomanYS 18 - 23.11.20 - 17:00 | (16) А в чем проблема? Совпало с предыдущим - запись не берёшь | ||
RomanYS 19 - 23.11.20 - 17:01 | (12) странная структура, тогда могут быть разные записи на одну дату - что с ними делать? | ||
Kozitsyn 20 - 23.11.20 - 17:01 | (15) идиот здесь не я, если вы такое предлагаете. В итоге вы получите исходную таблицу, потому что даты и так различные | ||
Kozitsyn 21 - 23.11.20 - 17:06 | (19) пока представим что такого нет. Пока задача понять - в принципе возможно ли вынуть запросом только начальные записи по всем подряд записанным физикам. | ||
RomanYS 22 - 23.11.20 - 17:07 | (21) В принципе возможно | ||
ам794123 23 - 23.11.20 - 17:08 | (13) поддерживаю, давно хотел найти применение функция языка запросов АВТОНОМЕРЗАПИСИ(). | ||
RomanYS 24 - 23.11.20 - 17:09 | (23) есть такое))) | ||
Kozitsyn 25 - 23.11.20 - 17:11 | (13) Благодарю. Попробую. Отпишусь | ||
Kozitsyn 26 - 23.11.20 - 17:29 | ВЫБРАТЬ МойРегистр.ФизЛицо КАК ФизЛицо, МойРегистр.Период КАК Период, АВТОНОМЕРЗАПИСИ() КАК НомерСтроки ПОМЕСТИТЬ ВТ ИЗ РегистрСведений.МойРегистр КАК МойРегистр ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ МойРегистр.ФизЛицо КАК ФизЛицо, МойРегистр.Период КАК Период, АВТОНОМЕРЗАПИСИ() КАК НомерСтроки ПОМЕСТИТЬ ВТ2 ИЗ РегистрСведений.МойРегистр КАК МойРегистр ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ВТ.ФизЛицо КАК ФизЛицо, ВТ.Период КАК Период ИЗ ВТ КАК ВТ ЛЕВОЕ СОЕДИНЕНИЕ ВТ2 КАК ВТ2 ПО (ВТ.НомерСтроки = ВТ2.НомерСтроки + 1) ГДЕ ЕСТЬNULL(ВТ2.ФизЛицо, "") <> ВТ.ФизЛицо | ||
Kozitsyn 27 - 23.11.20 - 17:31 | (26) Получился такой запрос. Он работает. Но, если я например добавлю еще одну Лоханкину на 21.11.2020, и он почему её еще выводит, хотя не должен, потому что она относится к той Лоханкиной. Видимо еще нужно сортировать записи перед сравнением | ||
Kozitsyn 28 - 23.11.20 - 17:34 | Добавил ИНДЕКСИРОВАТЬ ПО Период, в итоге вроде всё заработало, всем спасибо, вот итоговый запрос:
ВЫБРАТЬ МойРегистр.ФизЛицо КАК ФизЛицо, МойРегистр.Период КАК Период, АВТОНОМЕРЗАПИСИ() КАК НомерСтроки ПОМЕСТИТЬ ВТ ИЗ РегистрСведений.МойРегистр КАК МойРегистр ИНДЕКСИРОВАТЬ ПО Период ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ МойРегистр.ФизЛицо КАК ФизЛицо, МойРегистр.Период КАК Период, АВТОНОМЕРЗАПИСИ() КАК НомерСтроки ПОМЕСТИТЬ ВТ2 ИЗ РегистрСведений.МойРегистр КАК МойРегистр ИНДЕКСИРОВАТЬ ПО Период ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ВТ.ФизЛицо КАК ФизЛицо, ВТ.Период КАК Период ИЗ ВТ КАК ВТ ЛЕВОЕ СОЕДИНЕНИЕ ВТ2 КАК ВТ2 ПО (ВТ.НомерСтроки = ВТ2.НомерСтроки + 1) ГДЕ ЕСТЬNULL(ВТ2.ФизЛицо, "") <> ВТ.ФизЛицо | ||
RomanYS 29 - 23.11.20 - 17:42 | |||
RomanYS 30 - 23.11.20 - 17:44 | Блин, а к АВТОНОМЕРЗАПИСИ порядок указать нельзя? Без этого как бы смыла нет, номера нужны именно в порядке дат Рекламное место пустует | ||
Kozitsyn 31 - 23.11.20 - 17:46 | (29) Да, так будет проще )
ВЫБРАТЬ МойРегистр.ФизЛицо КАК ФизЛицо, МойРегистр.Период КАК Период, АВТОНОМЕРЗАПИСИ() КАК НомерСтроки ПОМЕСТИТЬ ВТ ИЗ РегистрСведений.МойРегистр КАК МойРегистр ИНДЕКСИРОВАТЬ ПО Период ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ВТ.ФизЛицо КАК ФизЛицо, ВТ.Период КАК Период ИЗ ВТ КАК ВТ ЛЕВОЕ СОЕДИНЕНИЕ ВТ КАК ВТ2 ПО (ВТ.НомерСтроки = ВТ2.НомерСтроки + 1) ГДЕ ЕСТЬNULL(ВТ2.ФизЛицо, "") <> ВТ.ФизЛицо | ||
Kozitsyn 32 - 23.11.20 - 17:46 | (30) порядок я решил с помощью индексирования | ||
Kozitsyn 33 - 23.11.20 - 17:48 | Без индексирования всё разъезжается ) | ||
RomanYS 34 - 23.11.20 - 17:48 | (32) А это чем-то подтверждается, или ты просто решил, что решил :)? | ||
Kozitsyn 35 - 23.11.20 - 17:50 | (34) Подтверждается результатами тестирования. Без индексирования, если добавить еще одну строку к подряд записанным данными, то это последнее добавление в результате запроса отобразится последней строкой, а если проидексировать, то все будет хорошо, не отобразится ) | ||
acht 36 - 23.11.20 - 18:05 | (27) Если упороться, то можно написать на 1С коррелирующий подзапрос
ВЫБРАТЬ ДАТАВРЕМЯ(2020, 11, 3) КАК Период, "Бельдыев" КАК Физик ПОМЕСТИТЬ Регистр ОБЪЕДИНИТЬ ВЫБРАТЬ ДАТАВРЕМЯ(2020, 11, 5), "Бельдыев" ОБЪЕДИНИТЬ ВЫБРАТЬ ДАТАВРЕМЯ(2020, 11, 9), "Лоханкина" ОБЪЕДИНИТЬ ВЫБРАТЬ ДАТАВРЕМЯ(2020, 11, 10), "Лоханкина" ОБЪЕДИНИТЬ ВЫБРАТЬ ДАТАВРЕМЯ(2020, 11, 22), "Бельдыев" ОБЪЕДИНИТЬ ВЫБРАТЬ ДАТАВРЕМЯ(2020, 11, 24), "Бельдыев" ; ВЫБРАТЬ Текущий.Период,Текущий.Физик ИЗ
Регистр КАК Текущий
ЛЕВОЕ СОЕДИНЕНИЕ
Регистр КАК Предыдущий
ПО
Предыдущий.Период В (
ВЫБРАТЬ
МАКСИМУМ(РегистрВнутр.Период)
ИЗ
Регистр КАК РегистрВнутр
ГДЕ
РегистрВнутр.Период < Текущий.Период
)
ГДЕ
Предыдущий.Физик ЕСТЬ NULL
ИЛИ Предыдущий.Физик <> Текущий.Физик
УПОРЯДОЧИТЬ ПО
Текущий.Период | ||
RomanYS 37 - 23.11.20 - 18:13 | (36) страшно :) А если дат будет хотя бы 1000?
И МАКСИМУМ(РегистрВнутр.Период) здесь наверное лучше на "первые 1" заменить | ||
acht 38 - 23.11.20 - 18:17 | (37) Не, на первые 1 оно тебя пошлет в части "упорядочить по" Производительтность, кнечн, мерять надо. Думаю, что на с индексом по периоду будет не так страшно. Но на план запроса посмотреть эт уже завтра... | ||
RomanYS 39 - 23.11.20 - 18:19 | (38) конечно с "упорядочить по". По идее побыстрее должно быть чем максимум | ||
acht 40 - 23.11.20 - 18:20 | (39) Зависит от. На MSSQL, ЕМНИП, еквифаллентно | ||
acht 41 - 23.11.20 - 18:22 | (39) а с "упорядочить по" в подзапросе тебя пошлет 1С, которая не будет такое компилировать | ||
RomanYS 42 - 23.11.20 - 18:24 | (41) проверил, не послала. База файловая.
ВЫБРАТЬ Текущий.Период, Текущий.Физик ИЗ Регистр КАК Текущий ЛЕВОЕ СОЕДИНЕНИЕ Регистр КАК Предыдущий ПО (Предыдущий.Период В (ВЫБРАТЬ ПЕРВЫЕ 1 РегистрВнутр.Период ИЗ Регистр КАК РегистрВнутр ГДЕ РегистрВнутр.Период < Текущий.Период УПОРЯДОЧИТЬ ПО РегистрВнутр.Период УБЫВ)) ГДЕ (Предыдущий.Физик ЕСТЬ NULL ИЛИ Предыдущий.Физик <> Текущий.Физик) УПОРЯДОЧИТЬ ПО Текущий.Период | ||
RomanYS 43 - 23.11.20 - 18:29 | |||
МимохожийОднако 44 - 23.11.20 - 18:32 | Срез первых записей не подходит? | ||
RomanYS 45 - 23.11.20 - 18:34 | (44) Не, физлицо - измерение, и ему не срез нужен совсем. Скорее периоды действия | ||
Alres 46 - 23.11.20 - 18:43 | ВЫБРАТЬ МойРегистр.Период КАК Период, МойРегистр.ФИО КАК ФИО ПОМЕСТИТЬ МойРегистр ИЗ РегистрСведений.МойРегистр КАК МойРегистр ИНДЕКСИРОВАТЬ ПО Период, ФИО ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ МойРегистр.Период КАК Период, МойРегистр.ФИО КАК ФИО, МИНИМУМ(ЕСТЬNULL(МойРегистр_КонецПериода.Период, ДАТАВРЕМЯ(2099, 11, 1))) КАК КонецПериода ПОМЕСТИТЬ МойРегистр_КонецПериода ИЗ МойРегистр КАК МойРегистр ЛЕВОЕ СОЕДИНЕНИЕ МойРегистр КАК МойРегистр_КонецПериода ПО (МойРегистр.Период < МойРегистр_КонецПериода.Период) И (МойРегистр.ФИО <> МойРегистр_КонецПериода.ФИО) СГРУППИРОВАТЬ ПО МойРегистр.Период, МойРегистр.ФИО ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ МИНИМУМ(МойРегистр_КонецПериода.Период) КАК Период, МойРегистр_КонецПериода.ФИО КАК ФИО, МойРегистр_КонецПериода.КонецПериода КАК КонецПериода ИЗ МойРегистр_КонецПериода КАК МойРегистр_КонецПериода СГРУППИРОВАТЬ ПО МойРегистр_КонецПериода.ФИО, МойРегистр_КонецПериода.КонецПериода | ||
RomanYS 47 - 23.11.20 - 18:47 | (46) Идея верная.
Только зачем И (МойРегистр.ФИО <> МойРегистр_КонецПериода.ФИО) во втором запросе? Лишние записи получишь, условие в 3-м запросе должно быть | ||
Alres 48 - 23.11.20 - 19:14 | (47) Чтобы получить дату изменения физлица, она будет одинаковая для 03 Бельдыев и 05 Бельдыев чтобы по ней потом можно было свернуть и оставить только 03 Бельдыев | ||
RomanYS 49 - 23.11.20 - 19:16 | (48) У тебя левое соединение и нет условия ГДЕ, значит ты получишь ВСЕ записи из левой таблицы. | ||
RomanYS 50 - 23.11.20 - 19:20 | (48) Ок. Сгруппировать возможно я не учёл. Возможно правильно (проверять лень), но я бы сделал по другому :) | ||
Alres 51 - 23.11.20 - 19:25 | |||
Kozitsyn 52 - 23.11.20 - 19:31 | Проверил этот запрос тоже работает. Во как, думал никак не получится сделать, а тут даже несколько рабочих вариантов есть )))) Спасибо вам, неравнодушные люди ;)
ВЫБРАТЬ МойРегистр.Период КАК Период, МойРегистр.ФизЛицо КАК Физик ПОМЕСТИТЬ Текущий ИЗ РегистрСведений.МойРегистр КАК МойРегистр ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ Текущий.Период КАК Период, Текущий.Физик КАК Физик ИЗ Текущий КАК Текущий ЛЕВОЕ СОЕДИНЕНИЕ Текущий КАК Предыдущий ПО (Предыдущий.Период В (ВЫБРАТЬ ПЕРВЫЕ 1 РегистрВнутр.Период КАК Период ИЗ РегистрСведений.МойРегистр КАК РегистрВнутр ГДЕ РегистрВнутр.Период < Текущий.Период УПОРЯДОЧИТЬ ПО Период УБЫВ)) ГДЕ (Предыдущий.Физик ЕСТЬ NULL ИЛИ Предыдущий.Физик <> Текущий.Физик) УПОРЯДОЧИТЬ ПО Текущий.Период | ||
Kozitsyn 53 - 23.11.20 - 19:39 | |||
RomanYS 54 - 23.11.20 - 20:03 | |||
acht 55 - 23.11.20 - 23:24 | (54) > я не понимаю, как гарантируется упорядоченность по периоду.
Созданный индекс по периоду на времянку, он по умолчанию как ASC делается =) А дальше ему тупо везет, что чтение строк в порядке кластерного индекса идет, а АВТОНОМЕРЗАПИСИ() дает identity с шагом 1
Профайлер я еще не запускал, так что могу врать. | ||
RomanYS 56 - 23.11.20 - 23:31 | (55) Получается АВТОНОМЕРЗАПИСИ как чемодан без ручки, потенциально офигенная штука, которой кучу задач можно решать, при этом без банального упорядочить - результат непредсказуем.
Но в большинстве случаев вам буде вести... т.е. ещё и мина замедленного действия | ||
Cthulhu 57 - 24.11.20 - 01:24 | (56): почему без упорядочить? | ||
МимохожийОднако 58 - 24.11.20 - 07:09 | (51) Присоединяюсь. При изменении кода, который не позволяет записывать в новой дате того же сотрудника, даст готовую таблицу из записей основной таблицы регистра. Или вместо запроса тупой перебор вниз по датам. | ||
dmpl 59 - 24.11.20 - 07:53 | (35) И чо? Раньше, например, вызов Документ.Записать() перепроводил документ при записи, если он был проведен. А с определенной версии платформы только записывает. | ||
Ненавижу 1С 60 - 24.11.20 - 08:43 | как учитывать факт записи нескольких физлиц одной датой? Рекламное место пустует | ||
Said_We 61 - 24.11.20 - 13:11 | (56) Да это так.
Я не помню, что бы можно было использовать как-то иначе чем так: SELECT row_number() over(ORDER BY <Поле1 [,Поле2...ПолеN]>) as NPP Плюс там ещё может быть "partition BY", но не важно... У 1С свое видение.... Как всегда. Всандалили автоупорядочивание только во внутренние таблицы, в которых нет сортировки без ограничения TOP. Так что в общем случае "АВТОНОМЕРЗАПИСИ" использовать нельзя пока нигде. Так что пока только "коррелирующий подзапрос". Только необходимо, четко отделять записи друг от друга. | ||
RomanYS 62 - 24.11.20 - 13:25 | (61) А если взять "Первые 999999999999" и упорядочить, сработает? | ||
Said_We 63 - 24.11.20 - 13:31 | Да, но если будет больше, то.... | ||
Said_We 64 - 24.11.20 - 13:36 | (62) Только по моему девяток слишком много. Там ограничение есть. | ||
RomanYS 65 - 24.11.20 - 13:39 | |||
Said_We 66 - 24.11.20 - 13:51 | Если бы синтаксис был бы какой-то такой, то было бы здорово:
АВТОНОМЕРЗАПИСИ НАД (ГРУППИРОВАТЬ ПО <Поле1 [,Поле2...,ПолеN]> СОРТИРОВАТЬ ПО <Поле1 [,Поле2...,ПолеN]>) или АВТОНОМЕРЗАПИСИ НАД (СГРУППИРОВАТЬ ПО <Поле1 [,Поле2...,ПолеN]> УПОРЯДОЧИТЬ ПО <Поле1 [,Поле2...,ПолеN]>)Тем более, что на T-SQL такое переводится практически 1 к 1. | ||
Said_We 67 - 24.11.20 - 13:57 | А потом туда же прикрутить:
MAХ(<ИмяПоля>) НАД (РАЗБИЕНИЕ НА <Поле1 [,Поле2...,ПолеN]>) Тоже переводится 1 к 1 Да и вообще оконные функции прикрутить. Запросы были бы короче на много без лишних джоинов. Были бы более читабельны. Выполнялись бы на несколько порядков быстрее. |
|
Список тем форума |