Каталог решений - Альтернативный вариант расчета возраста (лет, месяцев, дней) запросом

Альтернативный вариант расчета возраста (лет, месяцев, дней) запросом

Альтернативный вариант расчета возраста (лет, месяцев, дней) запросом

В наличии

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

Категория:

Описание

Сначала хорошим решением мне показались запросы в этой публикации. Но тестируя на разные случаи (29.02.2016 и 28.02.2017 и тому подобное) получал не совсем верные результаты. + мне сложно было вникнуть во всех хитросплетения и условия, поэтому решил написать свой вариант:

ВЫБРАТЬ
	ГОД(&БольшаяДата) = ГОД(&МеньшаяДата) КАК ГодаРавны,
	МЕСЯЦ(&БольшаяДата) > МЕСЯЦ(&МеньшаяДата) КАК МесяцБольше,
	МЕСЯЦ(&БольшаяДата) = МЕСЯЦ(&МеньшаяДата) КАК МесяцыРавны,
	ДЕНЬ(&БольшаяДата) > ДЕНЬ(&МеньшаяДата) КАК ДеньБольше,
	ДЕНЬ(&БольшаяДата) = ДЕНЬ(&МеньшаяДата) КАК ДниРавны
ПОМЕСТИТЬ Условия
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	Условия.ГодаРавны КАК ГодаРавны,
	Условия.МесяцБольше КАК МесяцБольше,
	Условия.МесяцыРавны КАК МесяцыРавны,
	Условия.ДеньБольше КАК ДеньБольше,
	Условия.ДниРавны КАК ДниРавны,
	ДЕНЬ(КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(&БольшаяДата, МЕСЯЦ, -1), МЕСЯЦ)) КАК ПоследнийДеньПредыдущегоМесяца,
	ДЕНЬ(КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(&БольшаяДата, МЕСЯЦ, -1), МЕСЯЦ)) < ДЕНЬ(&МеньшаяДата) И ДЕНЬ(&БольшаяДата) < 3 КАК ДеньПредыдущегоМесяцаМеньше,
	Условия.ДеньБольше ИЛИ Условия.ДниРавны КАК ДеньБольшеИлиРавен,
	Условия.МесяцБольше ИЛИ Условия.МесяцыРавны КАК МесяцБольшеИлиРавен,
	Условия.ДеньБольше ИЛИ Условия.ДниРавны КАК ПоследнийМесяцПрошел,
	Условия.МесяцБольше ИЛИ Условия.МесяцыРавны И (Условия.ДеньБольше ИЛИ Условия.ДниРавны) КАК ПоследнийГодПрошел
ПОМЕСТИТЬ СложныеУсловия
ИЗ
	Условия КАК Условия
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВЫБОР
		КОГДА СложныеУсловия.ГодаРавны
			ТОГДА 0
		КОГДА СложныеУсловия.ПоследнийГодПрошел
			ТОГДА РАЗНОСТЬДАТ(&МеньшаяДата, &БольшаяДата, ГОД)
		ИНАЧЕ РАЗНОСТЬДАТ(&МеньшаяДата, &БольшаяДата, ГОД) - 1
	КОНЕЦ КАК Лет,
	ВЫБОР
		КОГДА СложныеУсловия.ПоследнийМесяцПрошел И СложныеУсловия.МесяцБольшеИлиРавен
			ТОГДА МЕСЯЦ(&БольшаяДата) - МЕСЯЦ(&МеньшаяДата)
		КОГДА СложныеУсловия.МесяцБольше
			ТОГДА МЕСЯЦ(&БольшаяДата) - МЕСЯЦ(&МеньшаяДата) - 1
		КОГДА СложныеУсловия.ПоследнийМесяцПрошел
			ТОГДА 12 - (МЕСЯЦ(&МеньшаяДата) - МЕСЯЦ(&БольшаяДата))
		ИНАЧЕ 12 - (МЕСЯЦ(&МеньшаяДата) - МЕСЯЦ(&БольшаяДата) + 1)
	КОНЕЦ КАК Месяцев,
	ВЫБОР
		КОГДА СложныеУсловия.МесяцБольшеИлиРавен И СложныеУсловия.ДеньБольшеИлиРавен
			ТОГДА ДЕНЬ(&БольшаяДата) - ДЕНЬ(&МеньшаяДата)
		КОГДА СложныеУсловия.ПоследнийМесяцПрошел И СложныеУсловия.ДеньБольшеИлиРавен
			ТОГДА ДЕНЬ(&БольшаяДата) - ДЕНЬ(&МеньшаяДата)
		КОГДА СложныеУсловия.ДеньПредыдущегоМесяцаМеньше ТОГДА 0
		ИНАЧЕ СложныеУсловия.ПоследнийДеньПредыдущегоМесяца - (ДЕНЬ(&МеньшаяДата) - ДЕНЬ(&БольшаяДата))
	КОНЕЦ КАК Дней	 		
ИЗ
	СложныеУсловия КАК СложныеУсловия

Возможно такой вариант кому-то покажется очевиднее и понятнее. Тестировались различные вариации дат. При этом здесь есть следующее допущение: БольшаяДата всегда больше.

Сверялся с этим онлайн калькулятором, но если кто-то найдет ошибку — жду в комментарии!

has been added to your cart:
Оформление заказа