Как стать автором
Обновить

Комментарии 27

Как-то все слишком усложнили тут. Вот простая схема:
— список сотрудников;
— список перемещений (прием, перевод, увольнение) с датой документа.

Всё. На основе этих сведений можно делать любые запросы и отчеты. Этот вариант в начале статьи предлагается как слишком затратный и т.п. Как раз для этих случаев и используется «регистр сведений» (аналог из 1С), где хранится актуальная информация по сотрудниках на текущий момент времени.
В случае с «регистром сведений» происходит дублирование информации, а здесь попытался избавиться от этого.
Список перемещений — аналог «Работника», но с ним возникают указанные в статье проблемы.
Если и дальше проводить аналогии с регистром сведений, то здесь и описано как они могли бы быть устроены внутри для оптимизации запросов.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
я же предупредил «включаем фантазию» :)
НЛО прилетело и опубликовало эту надпись здесь
вроде понятно написал о чем
тролль детектед.
group by разве не спасёт отца русской демократии?
думаю, нет :)
особенно тогда, когда выборка не ограничивается только 2-мя объектами — чем их больше, тем сложнее будет использовать group by (вплоть до «невозможно»)
ну приведи чтоли какой-нибудь невозможный пример
Например, если в контексте статьи потребуется вывести список Работников и их непосредственных начальников. В Работниках уже будет group by, в Начальниках тоже придется его использовать (т.к. начальник может меняться у работника), итоговый запрос я даже боюсь представить как написать без подзапроса.
странное желание. особенно в свете того, что начальники — тоже работники и у них есть начальники. но даже если заменить начальников на отделы, то что мешает отсортировать на дате, сгруппировать по номерам работников и номерам отделов и выбрать последнюю запись?
так вот, выбор последней записи и будет являться подзапросом.
при указанном в статье подходе подзапросов не будет.
с чего бы? лимит не рулит?
Как показать «последнюю» должность и «последнего» руководителя работника без поздапроса с LIMIT?
Я пытался это сделать в первой части статьи и пришел к выводу, что добавив одно поле этого можно избежать!
Я не говорю, что нельзя сделать без group by и limit, я говорю, что есть способ быстрее!
Для хранения истории вы предложили вполне адекватный подход — выносить карточку сущности в отдельную таблицу, используя при это основную таблицу, как связочную с небольшой константной информационной нагрузкой.

Неадекватность тут в том, что индексы будут строиться по всей истории, соответственно замедляя выборки (это в лучшем случае). Ну и постройка запроса становится неестественной.

Не проще ли было наряду с историей карточек хранить последнюю копию (заполненный соответственно набор полей с аналогичными именами колонок) карточки сущности непосредственно в сущности? В таком случае будет использоваться укороченный индекс для поиска данных — количество записей в таблице сущностей по определению меньше либо равно количеству записей в таблице карточек. Да и запросы приобретают естественный вид.

Кроме того, в карточку сущности полезно ввести дату создания карточки и ссылку (поле с идентификатором записи) на сущность, а в сущность — ссылку на последнюю карточку. Таким образом упростится обход всей этой структуры, да и можно будет без проблем отказаться от хранения данных карточки в самой сущности, если такое кэширование не применимо в какой-либо ситуации.
Для большинства случаев, у нас в сущности храниться текстовое наименование объекта, которое и вытаскивается. Я не говорю, что везде необходимо подключать таблицу истории — лишь для отчетов/выборок, ее использующих.

Про ссылку из сущности на карточку истории — да, можно сделать и так — я предложил свой вариант, который не встречал ранее.
В 1с уже реализовано.Вообще как RAD для учетных систем — очень хорошая система (начиная с 8.1)
согласен, но не все пишут на 1с
Это верно. Но посмотрев, как 1с хранит, записывает и получает данные — можно многое почерпнуть для себя.
По работе общаюсь с банковским мейнфреймом на Teradata. Вся история хранится подобным образом. Никакого специального разбиения данных на таблицы нет, но все таблицы имеют по две дополнительные колонки — FromDate и ToDate. Максимальная дата во второй показывает активность записи. А так как Teradata легко переваривает громадные объемы данных, то такая избыточность для нее не помеха, тем более, что минимальная разность в истории обычно равна дню.
Ну вот, что и требовалось доказать! Подобная избыточность полезна для выборок и не сильно нагружает обработку.
Ваш второй пример во-первых непонятный, а во-вторых неправильный.
1. Предыдущая и следующие даты относятся к работе в той же самой компании или любой? Если к той же самой, то как вы будете делать такой же запрос, только без условия на конкретную компанию. Если к любой, то это вообще работать не будет, если человек перевелся в другую компанию в пределах одного года.
2. Пример: (ДолжностьА, КомпанияА, 15/02/11-28/02/11), (ДолжностьБ, КомпанияА, 15/03/11-22/03/11). Ваш код не выдаст вообще ни одной записи на сегодняшнюю дату.
На счет непонятности, да есть немного такое. Я рассказывал общий подход к организации регистров сведений, который мы используем, поэтому видимо из-за общности не нашлось нормального примера.

1) Вы совершено правы, совсем забыл упомянуть в статье, что в второй части «Следующая» и «Предыдущая» дата должна указывать на запись, относящуюся только к работнику одной компании, т.е. если человек перевелся в другую компанию, то «Следующая дата» остается в максимальной. Сейчас дополню.
2) Опять вы правы, там в запросе лишнее условие было. Сейчас поправлю.

Спасибо за внимательность!
А разве для того, чтобы посчитать/вывести тех людей, кто поработал в компании с начала года недостаточно «р.ДатаУвольнения > НачалоГода»
Зарегистрируйтесь на Хабре, чтобы оставить комментарий