el_tot93 Ответов: 3

Как сделать запрос для расчета возраста


я хочу сделать запрос для расчета возраста клиента авто в столбце у меня есть гражданский номер для него типа (286063001795)

Цитата:
286063001795
((2 = 19 , 86 = 86 )(1986 год)) , 06 = 6 месяцев , 30 = 30 дней , 01795 = они не нужны
(1996/6/30)
-
(сегодня)
=
ВОЗРАСТ


как я могу сделать что-то подобное

Что я уже пробовал:

я пробую много вещей о том что я нашел это делает его ручным поэтому я хочу сделать это запросом любой помощи

Maciej Los

Какая версия Sql Server?
Если я вас правильно понял, самое сложное-это "превратить" гражданское нет в свидание.

el_tot93

2017

BillWoodruff

Итак, сначала сосредоточьтесь на доказательстве концепции: напишите метод, который принимает "civil" и возвращает DateTime ... затем разберитесь с SQL-вещами.

el_tot93

thx для вашего ответа о том, что я новичок в кодировании, поэтому я не знаю, как это сделать

BillWoodruff

Когда-то мы все были новичками в программировании :) Для новичка вы имеете дело с некоторыми сложными задачами здесь.

3 Ответов

Рейтинг:
7

CHill60

В дополнение к вышеприведенному решению ОГА я предположил, что вы будете хранить Гражданский номер как ... номер, поэтому я придумал что-то вроде этого...

Получите дату рождения в формате xMMDD, разделив гражданский номер на 100000 (где x-1, 2 в соответствии с вашими правилами).

Преобразовать эту дату в формат CCYYMMDD путем добавления 17000000

Преобразуйте это число в реальную дату.

declare @demo table (id int identity (1,1), civicNo bigint, dob date)
insert into @demo (civicNo) values (286063001795),(260102901794)

update @demo set dob = CONVERT(datetime, convert(varchar(10), 17000000 + (civicNo / 100000)))
Как вы увидите из ссылки в решении 1, существует множество способов расчета возраста - я склонен использовать следующий метод, но имейте в виду, что я не тестировал его во всех комбинациях високосного года в год рождения, високосного года в "Сегодня", дня рождения и т. д.
select *, datediff(Month, dob, getdate())/12 as age, (civicNo / 100000),17000000 + (civicNo / 100000)
from @demo
Однако я полностью согласен с @OriginalGriff - не храните данные, которые являются динамическими в базе данных, вычисляйте их, когда это необходимо.


BillWoodruff

Ахой: магические числа зрячие :)

CHill60

:румянец:

Maciej Los

Кэролайн, я не знаю, как ты это делаешь, но ты потрясающая, когда играешь с sql!
5ed!

el_tot93

братан как я могу сделать это с моей базой данных я новичок в кодировании и я стараюсь muny time
таблица ( табл. )
civicNo ( CIVILIDD )
доб ( доб )

CHill60

Как ты можешь делать что? Я не понимаю остальную часть вашего комментария - что такое tabl, CIVILDD или dob

el_tot93

у меня есть таблица с таким именем столбца
я пробую твой код, но не могу этого сделать

CHill60

Как насчёт

update tabl set dob = CONVERT(datetime, convert(varchar(10), 17000000 + (CIVILIDD / 100000)))

el_tot93

Преобразование типа данных varchar в тип данных datetime привело к значению вне диапазона.
Заявление было прекращено.

CHill60

столбец dob должен иметь тип date или datetime. Вы, очевидно, используете варчар. Всегда используйте соответствующий тип столбца для данных, которые вы собираетесь хранить в нем!

el_tot93

ок, я сделаю это спасибо большое бро спасибо за вашу помощь

el_tot93

как конвертировать float в bigint ?????????

CHill60

Либо отбросьте таблицу и воссоздайте ее с помощью bigint вместо float для CIVILIDD, либо вы можете использовать Приведение и преобразование (Transact-SQL) - SQL Server | Microsoft Docs[^]. Например (непроверенный)

CONVERT(bigint, CIVILIDD)
или
CAST(CIVILIDD AS bigint)
Лучше всего изменить схему таблицы, чтобы использовать правильные типы данных для столбцов

el_tot93

извините братан за то что он дал мне ту же ошибку мне нужно что то иметь потому что у меня много неправильных номеров CIVILD и дал мне ошибку потому что это

Преобразование не удалось при преобразовании даты и/или времени из символьной строки.

CHill60

Покажите мне свой сценарий создания таблицы и фактический запрос, который вы выполняете

el_tot93

я делаю это с ответом ответом

el_tot93

есть ли что-то неправильное в моем ответе

CHill60

Никогда не публикуйте вопросы или комментарии в качестве решений (ответов). Он будет опущен и предан забвению, а информация будет потеряна. Мне удалось захватить копию, но в будущем используйте ссылку "улучшить вопрос", чтобы добавить дополнительную информацию в свой список. вопрос

CHill60

Код, который вы разместили, работает. Об ошибках не сообщается.

el_tot93

Извини братан но у меня все еще есть та же ошибка msg я думаю потому что у меня неправильный Гражданский нет ?????? или это не проблема

CHill60

Какие данные дают вам ошибку?

Рейтинг:
21

OriginalGriff

Во - первых, создайте значение DATETIME- это довольно просто:

SELECT 
   Civil,
   CONVERT(DATETIME, 
      CASE WHEN SUBSTRING(Civil, 1, 1) = 2 THEN '19' ELSE '20' END + 
      SUBSTRING(Civil, 2, 2) + 
      '/' + SUBSTRING(Civil, 4, 2) +
      '/' + SUBSTRING(Civil, 6, 2), 
      120) AS DOB,
FROM MyTable
Теперь начинается самое трудное ... Возраст - это сложное понятие, потому что это не фиксированное значение, а относительное к текущей дате, и оно также имеет ряд компонентов.
Получить его относительно текущей даты не так уж сложно - GETDATE даст вам это, и вы легко сможете вычесть одно из другого. Проблема состоит из частей: x лет, y месяцев и z дней. Вам нужно будет рассчитать временной интервал, а затем разработать детали отдельно. Видеть здесь: sql server - как рассчитать возраст (в годах) на основе даты рождения и getDate() - переполнение стека[^] что дает решение.

- Я? Я бы вернул DOB из SQL, используя приведенный выше код, а затем обработал дату в C#, чтобы дать возраст: Работа с возрастом: это не то же самое, что промежуток времени![^]

На самом деле, нет, я бы не стал: я бы отказался от "гражданского" формата и сохранил DOB в значении DateTime, где его гораздо легче обрабатывать. "Гражданский" формат может быть сгенерирован из "реального" DOB довольно легко.


CHill60

- "Гражданский" формат может быть сгенерирован из" реального " DOB - только в том случае, если 01795 также был сохранен. Я полностью согласен с магазином доб, несмотря на возраст!

OriginalGriff

Я, наверное, хотел бы знать, что это кодирует - вероятно, время рождения? - и храните это в разумном формате, если это вообще уместно.

Но работа с "полузакодированными" значениями в SQL-это Пита и в лучшие времена ...

Maciej Los

Ты очень быстрый, пол!
5ed!

el_tot93

Тип данных аргумента float недопустим для аргумента 1 функции подстроки.

OriginalGriff

Вы храните гражданскую ценность в поплавке?
Ты сошел с ума.

Это значительно усложняет дело: вместо подстроки вам придется преобразовать значение FLOAT в INT, а затем использовать divide и modulus для извлечения каждой пары цифр / цифр перед построением значения DATETIME.

Серьезно, сбросьте его и используйте DOB в качестве даты-времени. С ним гораздо легче работать...

el_tot93

поэтому я преобразую столбец в int

OriginalGriff

Это решает одну часть - вам все равно придется играть с разделением и модулем каждый раз, когда вы его используете. Гораздо проще хранить значения даты и времени и генерировать свой "гражданский" номер только тогда, когда он вам действительно нужен, Честное слово!

Просто посмотрите, сколько людей здесь говорят: "измените способ хранения", вы думаете, что мы все ошибаемся? :смеяться:

CHill60

Если вы собираетесь сделать это таким образом то вам нужно будет использовать BigInt а не Int

OriginalGriff

Хорошая мысль - я забыл, что вы получите только 10 цифр в лучшем случае в INT.

BillWoodruff

+5

Рейтинг:
14

Maciej Los

Если я вас хорошо понимаю, самое трудное для решения вашей проблемы-это "преобразовать" гражданский номер в дату.

Ну а MS SQL-Server 2017 имеет встроенную функцию, которая может возвращать дату из частей: DATEFROMPARTS (Transact-SQL) - SQL Server | Microsoft Docs[^]
Все, что вам нужно сделать, это передать правильные значения: год, месяц и день. Наконец, вы можете получить результат в годах, месяцах и т. д., Используя: DATEDIFF (Transact-SQL) - SQL Server | Microsoft Docs[^] функция.

--CivilNo to date parts:
SELECT CASE WHEN SUBSTRING(CivilNo, 1, 1) = '2' THEN 19 ELSE 20 END AS YearPart, CONVERT(INT, SUBSTRING(CivilNo, 2, 2)) AS MonthPart, CONVERT(INT, SUBSTRING(CivilNo, 4, 2)) AS DayPart
FROM YourTableName


Теперь вы знаете, как "конвертировать" Гражданский номер в части даты. Остальное принадлежит тебе! Удачи вам!

Для получения более подробной информации, пожалуйста, смотрите:
Подстрока (Transact-SQL) - SQL Server | Microsoft Docs[^]
Приведение и преобразование (Transact-SQL) - SQL Server | Microsoft Docs[^]

[Записка]: Кажется, у нас с оригиналом Гриффом одна и та же идея о преобразовании гражданского номера в дату, но я не так быстро печатаю и выражаю себя, как он!


el_tot93

Тип данных аргумента float недопустим для аргумента 1 функции подстроки.

BillWoodruff

+5

Maciej Los

Спасибо, Билл.