powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Запрос хронология ФИО
25 сообщений из 25, страница 1 из 1
Запрос хронология ФИО
    #39983660
Алексаша
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте!!!
MS SQL SERVER 2017

имеется таблица
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
create table ChronFio
(ChronFioId INT IDENTITY(1,1),
PersonId INT,
[Date] Date,
Fam VARCHAR(50),
Nam VARCHAR(50),
Mid VARCHAR(50))

INSERT INTO [dbo].[ChronFio]
           ([PersonId]
		   ,[date]
           ,[Fam]
           ,[Nam]
           ,[Mid])
     VALUES
(1,'19800101','Иванова','Татьяна', 'Ивановна'),
(1,'19920101','Петрова','Татьяна', 'Ивановна'),
(1,'19950101','Моськина','Татьяна', 'Ивановна'),
(2,'19950101','Мартынов','Иван', 'Петрович'),
(2,'20100101','Гузеев','Иван', 'Михайлович'),
(3,'19950101','Добров','Петр', 'Юрьевич'),
(3,'20000101','Добров','Петр', 'Юревич')


Хочу получить результат:
ChronFioIdPersonIdDateFamNamMid311995-01-01Моськина (Петрова;Иванова)ТатьянаИвановна522010-01-01Гузеев (Мартынов)ИванМихайлович (Петрович)732000-01-01ДобровПетрЮревич (Юрьевич)

мое решение такое...
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
SELECT TOP 1 WITH TIES
		ChronFioId
      ,[PersonId]
      ,[Date]
      ,[Fam] = Fam + ' (' +
		(
		SELECT STRING_AGG(ca2.Fam,', ') WITHIN GROUP (ORDER BY ca2.Date DESC)
			FROM [dbo].[ChronFio] ca2
			WHERE ca2.PersonID = са.PersonID
			AND ca2.ChronFioId != са.ChronFioId
		) + ')'
      ,[Nam] = [Nam] + ' (' +
		(
		SELECT STRING_AGG(ca2.[Nam],', ') WITHIN GROUP (ORDER BY ca2.Date DESC)
			FROM [dbo].[ChronFio] ca2
			WHERE ca2.PersonID = са.PersonID
			AND ca2.ChronFioId != са.ChronFioId
		) + ')'
      ,[Mid] = [Mid] + ' (' +
		(
		SELECT STRING_AGG(ca2.[Mid],', ') WITHIN GROUP (ORDER BY ca2.Date DESC)
			FROM [dbo].[ChronFio] ca2
			WHERE ca2.PersonID = са.PersonID
			AND ca2.ChronFioId != са.ChronFioId
		) + ')'
  FROM [dbo].[ChronFio] са
  ORDER BY ROW_NUMBER() OVER(PARTITION BY [PersonId] ORDER BY [Date] DESC)


но оно не дает желаемый результат. Получается так:
ChronFioIdPersonIdDateFamNamMid311995-01-01Моськина (Петрова;Иванова)Татьяна (Татьяна;Татьяна)Ивановна (Ивановна; Ивановна)522010-01-01Гузеев (Мартынов)Иван (Иван)Михайлович (Петрович)732000-01-01Добров (Добров)Петр (Петр)Юревич (Юрьевич)
Подскажите как построить запрос...
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983667
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разучить таки директиву DISTINCT.

ЗЫ. Но если ишо и подумать, то все правильно. Как есть.
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983677
Алексаша
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222,

DISTINCT .... конкатенировать по полю дата нужно, т.е. в обратной хронологии и встает вопрос в каком месте тыкнуть этот DISTINCT ...
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983685
zby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
DROP table IF EXISTS  #ChronFio

GO
create table #ChronFio
(ChronFioId INT IDENTITY(1,1),
PersonId INT,
[Date] Date,
Fam VARCHAR(50),
Nam VARCHAR(50),
Mid VARCHAR(50))

INSERT INTO #ChronFio
           ([PersonId]
		   ,[date]
           ,[Fam]
           ,[Nam]
           ,[Mid])
     VALUES
(1,'19800101','Иванова','Татьяна', 'Ивановна'),
(1,'19920101','Петрова','Татьяна', 'Ивановна'),
(1,'19950101','Моськина','Татьяна', 'Ивановна'),
(2,'19950101','Мартынов','Иван', 'Петрович'),
(2,'20100101','Гузеев','Иван', 'Михайлович'),
(3,'19950101','Добров','Петр', 'Юрьевич'),
(3,'20000101','Добров','Петр', 'Юревич')

SELECT TOP 1 WITH TIES
		ChronFioId
      ,[PersonId]
      ,[Date]
      ,[Fam] = Fam + CASE WHEN EXISTS (SELECT
											*
										FROM
											#ChronFio cf
										WHERE
											cf.PersonID = са.PersonID
											AND cf.ChronFioId != са.ChronFioId
											AND cf.Fam != са.Fam) THEN 
		' (' +
		(
		SELECT STRING_AGG(ca2.Fam,', ') WITHIN GROUP (ORDER BY ca2.Date DESC)
			FROM #ChronFio ca2
			WHERE ca2.PersonID = са.PersonID
			AND ca2.ChronFioId != са.ChronFioId
		) + ')' ELSE '' END
      ,[Nam] = [Nam] + CASE WHEN EXISTS (SELECT
											*
										FROM
											#ChronFio cf
										WHERE
											cf.PersonID = са.PersonID
											AND cf.ChronFioId != са.ChronFioId
											AND cf.Nam != са.Nam) THEN 
	  ' (' +
		(
		SELECT STRING_AGG(ca2.[Nam],', ') WITHIN GROUP (ORDER BY ca2.Date DESC)
			FROM #ChronFio ca2
			WHERE ca2.PersonID = са.PersonID
			AND ca2.ChronFioId != са.ChronFioId
		) + ')'  ELSE '' END
      ,[Mid] = [Mid] + CASE WHEN EXISTS (SELECT
											*
										FROM
											#ChronFio cf
										WHERE
											cf.PersonID = са.PersonID
											AND cf.ChronFioId != са.ChronFioId
											AND cf.mid != са.mid) THEN 
	  ' (' +
		(
		SELECT STRING_AGG(ca2.[Mid],', ') WITHIN GROUP (ORDER BY ca2.Date DESC)
			FROM #ChronFio ca2
			WHERE ca2.PersonID = са.PersonID
			AND ca2.ChronFioId != са.ChronFioId
		) + ')'  ELSE '' END
  FROM #ChronFio са
  ORDER BY ROW_NUMBER() OVER(PARTITION BY [PersonId] ORDER BY [Date] DESC)
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983692
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексаша
aleks222,

DISTINCT .... конкатенировать по полю дата нужно, т.е. в обратной хронологии и встает вопрос в каком месте тыкнуть этот DISTINCT ...


Твои
"Гузеев (Мартынов) Иван Михайлович (Петрович)"

бессмысленны, чуть более, чем полностью.

Хронология означает перечень всех ФИО. Полностью.

А то твой Гузев был михалычем или петровичем? Или тем и тем?
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983707
Алексаша
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222,

То что вне скобок - текущее, то что в скобках в убывающем порядке. т.е. гузеев был ранее мартынов всю дорогу - иван , отчество текщее михайлович, а ранее было Петрович.
как правило возникают ситуации с женщинами
Иванова (Петрова, Сидорова) Марья Ивановна. Т.е. текущая Иванова, а ранее была Петровой и сидоровой
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983719
Алексаша
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
zby,

Спасибо!
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983732
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексаша
aleks222,

То что вне скобок - текущее, то что в скобках в убывающем порядке. т.е. гузеев был ранее мартынов всю дорогу - иван , отчество текщее михайлович, а ранее было Петрович.
как правило возникают ситуации с женщинами
Иванова (Петрова, Сидорова) Марья Ивановна. Т.е. текущая Иванова, а ранее была Петровой и сидоровой


Туповаты вы, батенька.

"а ранее было Петрович."
когда был мартынов или когда уже стал гузеев?

Не понимаете тривиального: смена фамилии не синхронна смене отчества.
А из вашего бреда невозможно однозначно это установить.
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983733
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
------------
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983742
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222
А то твой Гузев был михалычем или петровичем? Или тем и тем?

Для начальства "Михалыч", для друзей в гараже "Петрович" :))
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983775
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексаша,

За один проход
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
declare @ChronFio table
(ChronFioId INT IDENTITY(1,1),
PersonId INT,
[Date] Date,
Fam VARCHAR(50),
Nam VARCHAR(50),
Mid VARCHAR(50))

INSERT INTO @ChronFio
           ([PersonId]
		   ,[date]
           ,[Fam]
           ,[Nam]
           ,[Mid])
     VALUES
(1,'19800101','Иванова','Татьяна', 'Ивановна'),
(1,'19920101','Петрова','Татьяна', 'Ивановна'),
(1,'19950101','Моськина','Татьяна', 'Ивановна'),
(2,'19950101','Мартынов','Иван', 'Петрович'),
(2,'20100101','Гузеев','Иван', 'Михайлович'),
(3,'19950101','Добров','Петр', 'Юрьевич'),
(3,'20000101','Добров','Петр', 'Юревич');

with a as
(
 select
  PersonId, Date, Fam, Nam, Mid,
  lag(Fam) over (partition by PersonId order by Date) as Fam__prev,
  lag(Nam) over (partition by PersonId order by Date) as Nam__prev,
  lag(Mid) over (partition by PersonId order by Date) as Mid__prev
 from
  @ChronFio
),
b as
(
 select
  PersonId,
  max([date]) as [date],
  string_agg(case when Fam = Fam__prev then null else Fam end, ', ') within group (order by [date] desc) as Fam__agg,
  string_agg(case when Nam = Nam__prev then null else Nam end, ', ') within group (order by [date] desc) as Nam__agg,
  string_agg(case when Mid = Mid__prev then null else Mid end, ', ') within group (order by [date] desc) as Mid__agg
 from
  a
 group by
  PersonId
)
select
 PersonId, date,
 d.Fam__left + e.Fam__right,
 d.Nam__left + e.Nam__right,
 d.Mid__left + e.Mid__right
from
 b cross apply
 (select cast(0x7fffffff as int)) x(v) cross apply
 (
  select
   nullif(charindex(',', b.Fam__agg), 0),
   nullif(charindex(',', b.Nam__agg), 0),
   nullif(charindex(',', b.Mid__agg), 0)
 ) c(Fam__p, Nam__p, Mid__p) cross apply
 (
  select
   left(b.Fam__agg, isnull(c.Fam__p - 1, x.v)),
   left(b.Nam__agg, isnull(c.Nam__p - 1, x.v)),
   left(b.Mid__agg, isnull(c.Mid__p - 1, x.v))
 ) d(Fam__left, Nam__left, Mid__left) cross apply
 (
  select
   isnull('(' + ltrim(replace(substring(b.Fam__agg, c.Fam__p + 1, x.v), ',', ';')) + ')', ''),
   isnull('(' + ltrim(replace(substring(b.Nam__agg, c.Nam__p + 1, x.v), ',', ';')) + ')', ''),
   isnull('(' + ltrim(replace(substring(b.Mid__agg, c.Mid__p + 1, x.v), ',', ';')) + ')', '')
 ) e(Fam__right, Nam__right, Mid__right);

...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983854
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

И все это для того, чтобы конкатенировать значения в разных записях. Подобная задача она "нереляционная", т.е. она не решается стандартными операциями реляционной алгебры, а значит её лучше решать уже за пределами БД. При желании можно и гиперболический тангенс средствами БД вычислять, только зачем эот делать, если РБД для этого просто не предназначена.
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983878
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat,

Да ради Бога, никто не запрещает вам забрать все данные таблицы на клиента и вполне себе императивненько их там лопатить. И плевать, что это в разы затратнее, что по ресурсам, что по времени на разработку и тестирование, не говоря уже об эффективности - зато все догмы будут соблюдены.

Не пытались подумать: зачем производители РСУБД включают в свои продукты нереляционные инструменты?
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983883
Дмитрий Мух
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
И плевать, что это в разы затратнее, что по ресурсам, что по времени на разработку и тестирование, не говоря уже об эффективности - зато все догмы будут соблюдены.

Всё это чистой воды спекуляция, так как мы не знаем ни системы в целом, ни задачи в частности.
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983894
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий Мух
Всё это чистой воды спекуляция, так как мы не знаем ни системы в целом, ни задачи в частности.
Вот интересно, почему подобной аргументации, в подавляющем большинстве, придерживаются императивщики?
Мой личный опыт говорит, что они просто по-другому не умеют...

ЗЫ: Ничего личного, просто наблюдения.
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39983964
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
Вот интересно, почему подобной аргументации, в подавляющем большинстве, придерживаются императивщики?
Мой личный опыт говорит, что они просто по-другому не умеют....


Немного времени назад я частенько встречал иную крайность - зачем нам БД, будем хранить в файликах, читать в массивы, таскать их за собой и выбирать по месту. Это включало в себя жуткие попытки реализации многопользовательской работы. Благо не припомню реализацию транзакций. Так что в принципе все возможно.
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39984025
fkthat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
fkthat,

Да ради Бога, никто не запрещает вам забрать все данные таблицы на клиента и вполне себе императивненько их там лопатить. И плевать, что это в разы затратнее, что по ресурсам, что по времени на разработку и тестирование, не говоря уже об эффективности - зато все догмы будут соблюдены.

Не пытались подумать: зачем производители РСУБД включают в свои продукты нереляционные инструменты?

Реляционная БД должна решать реляционные задачи. Если вам приходится натягивать на неё другие задачи нереляционные , то значит что у вас спроектированно все через попу.
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39984040
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
Реляционная БД должна решать реляционные задачи. Если вам приходится натягивать на неё другие задачи нереляционные , то значит что у вас спроектированно все через попу.
Ну вот, я же так и писал - догма прежде всего, здравый смысл и все остальное - вторично.

Можете, на примере задачи ТС и предложенного решения, перечислить преимущества ее реализации вне СУБД?
А потом еще и ответить на вопрос - что же делать, если результат будет нужен не только на клиенте но и на сервере БД?
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39984041
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fkthat
invm
fkthat,

Да ради Бога, никто не запрещает вам забрать все данные таблицы на клиента и вполне себе императивненько их там лопатить. И плевать, что это в разы затратнее, что по ресурсам, что по времени на разработку и тестирование, не говоря уже об эффективности - зато все догмы будут соблюдены.

Не пытались подумать: зачем производители РСУБД включают в свои продукты нереляционные инструменты?

Реляционная БД должна решать реляционные задачи. Если вам приходится натягивать на неё другие задачи нереляционные , то значит что у вас спроектированно все через попу.
а что такое есть "реляционная задача" ?

вот, применительно к вопросу ТС, я вижу примерно такую ситуйовину:
- через проходную, 20 лет назад, проходит некто Иванова
- 15 лет назад, она выходит замуж за Петрова
- ещё через 5-ть лет, Петров оказуется "казлом" и она возвращает себе свою красссивую фамилию Иванова
- и, буквально вчера, она "полюбила" Сидорова, и теперь "проникает" через проходную как Сидорова

учёт, разумеется, ведется каждый день

Так вот, твоё "нереляционное" предложение, в чём заключается ?
Закачать все данные о проходе за 20-ть лет, и на клиенте, расспарсить ?

... дурня какаито, имхо ...
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39984140
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
court

Так вот, твоё "нереляционное" предложение, в чём заключается ?


Я бы выбирал человека построчно на клиент. Просто потому, что "Моськина (Петрова;Иванова)" это явно вариант отображения, и это уродливый вариант отображения ИМХО. На клиенте можно гораздо более удобно для пользователя сделать вывод, с порядком и датами изменений, с какой то дополнительной информацией, можно подгружать в скрытое меню и показывать по необходимости. А вот это вот "Моськина (Петрова;Иванова)" это какой то dos-стиль, когда вообще наплевать на пользователя.
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39984141
17-77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
court

Так вот, твоё "нереляционное" предложение, в чём заключается ?
Закачать все данные о проходе за 20-ть лет, и на клиенте, расспарсить ?

... дурня какаито, имхо ...

она прикладывает пропуск, у того есть ид, находим в базе пропуск по ид и проверяем действителен ли (все в условиях WHERE)

и да мне тоже не понятно, зачем собирать все старые фамилии в одну строчку
да и где вообще это может только понадобится? для учетной системы загса??
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39984173
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
17-77
и да мне тоже не понятно, зачем собирать все старые фамилии в одну строчку
да и где вообще это может только понадобится? для учетной системы загса??
Для понимания человеком.
Кто это, что за Моськина? А, это же та Моськина, которая у нас 20 лет работала Петровой.
Собственно, такая постановка бизнес-задачи, чего тут обсуждать, "нужно" или "не нужно".

aleks222
Твои
"Гузеев (Мартынов) Иван Михайлович (Петрович)"

бессмысленны, чуть более, чем полностью.

Хронология означает перечень всех ФИО. Полностью.
Нет, это же предназначено для показа пользователю. А не для налогового отчёта, или как идентификатор.

Пользователю не надо знать, "сколько раз человек был Петровым", и в течении какого периода, ему нужно понять, какого это за персонажа показывает система. Для этого обычно достаточно перечислить все фамилии в скобочках. И что бы компактно, а не списком. А если для какого то одного случая недостаточно - чтож, значит, этот случай система будет отрабатывать плохо, только и всего. (тогда пользователю придётся ткнуть в ФИО, что бы получить список всех ФИО с хронологией)
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39984255
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvg

Пользователю не надо знать, "сколько раз человек был Петровым", и в течении какого периода, ему нужно понять, какого это за персонажа показывает система

Если информация не обладает полнотой и способна привести к ошибкам - ее нельзя показывать пользователю.

Аккурат "какого это за персонажа показывает система" по этим спискам определить невозможно.
Персонаж определяется ФИО: Сидоров Сидор Сидорович.
А не шарадой: "Сидоров, а может быть Иванов" "может быть Иван, а может Сидор" "может быть Иванович, а может Сидорович".
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39984278
L_argo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автори да мне тоже не понятно, зачем собирать все старые фамилии в одну строчку
да и где вообще это может только понадобится?Смешной вопрос. Н-р обнаружить факт изменения. Сопоставить новую и старую фамилии для девушек, вышедших замуж и т.д.
Да и ошибки в написании встречаются нередко даже в офиц. документах.
...
Рейтинг: 0 / 0
Запрос хронология ФИО
    #39984397
Алексаша
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm,

Спасибо
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Запрос хронология ФИО
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]