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