powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Связка таблиц по нескольким полям для проставления необходимого флага
11 сообщений из 11, страница 1 из 1
Связка таблиц по нескольким полям для проставления необходимого флага
    #39830822
AVRomanenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. Имеется две таблицы.
В одной таблице хранится информация по клиентам (около 30 полей). Вторая таблица состоит из полей (5 полей, которые есть в первой таблице), в которых прописаны условия, по которым необходимо проставить один из флагов(6 поле из таблицы 2) в первую таблицу.


структура таблицы 1:
LOAN_CL EFF_DT DT_CH_PRC BASE_CCY_F SIMILAR_FДепозитный договор 19.03.2008 01.01.1900 1 NКредитный договор 22.03.2006 01.01.1900 0 NКредитный договор 17.11.2019 01.01.1900 1 Y

структура таблицы 2: (знаки >= и < условия для значений соответствующих полей из таблицы 1, символ # означает логическое НЕ)
LOAN_CLEFF_DTDT_CH_PRCBASE_CCY_FSIMILAR_FRVSRКредитный договор>=2019-03-011YYКредитный договор>=2019-03-011YYКредитный договор<2019-03-01<2019-03-011YNКредитный договор#YNКредитный договор0N

помогите, пожалуйста, разработать корректный алгоритм, который будет сравнивать все условия и выставлять в первую таблицу в конце соответствующий флаг из 6го поля 2й таблицы.

своей фантазии хватило только на такой вариант, но он некорректно отрабатывает. очевидно, даже алгоритм сравнения не очень правильный.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
select
case
when 
CR_SA.LOAN_CL = RVSR.LOAN_CL 
and (CR_SA.EFF_DT >= cast(replace(replace(replace(RVSR.EFF_DT, '>',''), '<',''),'=','') as date) 
or CR_SA.DT_CH_PRC >= cast(replace(replace(replace(RVSR.DT_CH_PRC, '>',''), '<',''),'=','') as date)) 
and CR_SA.BASE_CCY_F = RVSR.BASE_CCY_F 
and CR_SA.SIMILAR_F = RVSR.SIMILAR_F 
then 'Y' else 'N' end RVSR_F

from table_1 CR_SA

left join table_2 RVSR
on  CR_SA.LOAN_CL = RVSR.LOAN_CL 
and (CR_SA.EFF_DT >= cast(replace(replace(replace(RVSR.EFF_DT, '>',''), '<',''),'=','') as date)
or CR_SA.DT_CH_PRC >= cast(replace(replace(replace(RVSR.DT_CH_PRC, '>',''), '<',''),'=','') as date))
and CR_SA.BASE_CCY_F = RVSR.BASE_CCY_F
and CR_SA.SIMILAR_F = RVSR.SIMILAR_F



так же в case пробовал для полей с датами искать по первым двум символам вместо сравнения
Код: sql
1.
left(CR_SA.EFF_DT, 2) = '>='


но тоже никакого толка.
...
Рейтинг: 0 / 0
Связка таблиц по нескольким полям для проставления необходимого флага
    #39830833
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Без кавычек 2019-03-01 = 2015, и это целое число, а не дата.
Преобразование в дату этого числа даст 9 июля 1905 года.

Заключайте даты в одиночные кавычки.
...
Рейтинг: 0 / 0
Связка таблиц по нескольким полям для проставления необходимого флага
    #39830953
AVRomanenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iapБез кавычек 2019-03-01 = 2015, и это целое число, а не дата.
Преобразование в дату этого числа даст 9 июля 1905 года.

Заключайте даты в одиночные кавычки.

С этим нет никаких проблем, строка в дату конвертируется корректно.
...
Рейтинг: 0 / 0
Связка таблиц по нескольким полям для проставления необходимого флага
    #39830959
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AVRomanenko,

посмотри здесь 13088610
имхо, лучший выход
...
Рейтинг: 0 / 0
Связка таблиц по нескольким полям для проставления необходимого флага
    #39830964
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AVRomanenkoВ одной таблице хранится информация по клиентам (около 30 полей).А тип EFF_DT какой, date, или строка?

AVRomanenkoстрока в дату конвертируется корректно.Вы это проверяли? Я бы всё таки использовал CONVERT, и явное указание формата

AVRomanenkoусловия, по которым необходимо проставить один из флагов(6 поле из таблицы 2) в первую таблицу.Нужно проставить поле 6 из таблицы 2 в таблицу 1, но вы зачем то вычисляете RVSR_F.

AVRomanenkoсвоей фантазии хватило только на такой вариант, но он некорректно отрабатывает. очевидно, даже алгоритм сравнения не очень правильный.В нём даже не учитываются условия >, <, и т.д.

Я бы сделал подзапрос из table_2, в котором разложил бы поля EFF_DT и DT_CH_PRC на даты и условия
Это и отладить легко, как отдельный запрос.

А потом уже сделал джойн этого подзапроса с table_1, со связкой типа
Код: sql
1.
2.
3.
4.
5.
6.
7.
(RVSR.EFF_DT_condition = '>' and CR_SA.EFF_DT > RVSR.EFF_DT_date)
or
(RVSR.EFF_DT_condition = '>=' and CR_SA.EFF_DT >= RVSR.EFF_DT_date)
or
(RVSR.EFF_DT_condition = '<' and CR_SA.EFF_DT < RVSR.EFF_DT_date)
or
...

Писать лень, запрос получится на несколько страниц :-)
...
Рейтинг: 0 / 0
Связка таблиц по нескольким полям для проставления необходимого флага
    #39830965
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
courtAVRomanenko,

посмотри здесь 13088610
имхо, лучший выход
т.е. что имеется в виду: вот эту табличку
AVRomanenkoструктура таблицы 2: (знаки >= и < условия для значений соответствующих полей из таблицы 1, символ # означает логическое НЕ)
LOAN_CLEFF_DTDT_CH_PRCBASE_CCY_FSIMILAR_FRVSRКредитный договор>=2019-03-011YYКредитный договор>=2019-03-011YYКредитный договор<2019-03-01<2019-03-011YNКредитный договор#YNКредитный договор0N
нужно привести к такому виду (в СТЕ например), и затем джойнить с таб1, - EFF_DT и EFF_DT по between, остальное по like
LOAN_CLEFF_DT_minEFF_DT_maxDT_CH_PRC_minDT_CH_PRC_maxBASE_CCY_FSIMILAR_FRVSRКредитный договор2019-03-013000-01-011900-01-013000-01-011YYКредитный договор1900-01-013000-01-011900-01-013000-01-011YYКредитный договор1900-01-012019-03-011900-01-012019-03-011YNКредитный договор1900-01-013000-01-011900-01-013000-01-01%[^Y]NКредитный договор1900-01-013000-01-011900-01-013000-01-010%N
...
Рейтинг: 0 / 0
Связка таблиц по нескольким полям для проставления необходимого флага
    #39830977
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AVRomanenko,

Код: 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.
78.
79.
80.
81.
82.
83.
84.
85.
declare @t1 table (LOAN_CL varchar(30), EFF_DT date, DT_CH_PRC date, BASE_CCY_F bit, SIMILAR_F char(2));
insert into @t1
values
('Депозитный договор', convert(date, '19.03.2008', 104), convert(date, '01.01.1900', 104), 1, 'N'),
('Кредитный договор', convert(date, '22.03.2006', 104), convert(date, '01.01.1900', 104), 0, 'N'),
('Кредитный договор', convert(date, '17.11.2019', 104), convert(date, '01.01.1900', 104), 1, 'Y');

declare @t2 table (LOAN_CL varchar(30), EFF_DT varchar(30), DT_CH_PRC varchar(30), BASE_CCY_F bit, SIMILAR_F char(2), RVSR char(1));
insert into @t2
values
('Кредитный договор', '>=2019-03-01', null, 1, 'Y', 'Y'),
('Кредитный договор', '>=2019-03-01', null, 1, 'Y', 'Y'),
('Кредитный договор', '<2019-03-01', '<2019-03-01',	1, 'Y', 'N'),
('Кредитный договор', null, null, null,'#Y', 'N'),
('Кредитный договор', null, null, 0, null, 'N');

select * from @t1;

with a as
(
 select
  LOAN_CL,
  SIMILAR_F,
  cast('<cond ' + case
    when charindex('>=', EFF_DT) > 0 then replace(EFF_DT, '>=', 'c = "ge">')
    when charindex('<=', EFF_DT) > 0 then replace(EFF_DT, '<=', 'c = "le">')
    when charindex('>', EFF_DT) > 0 then replace(EFF_DT, '>', 'c = "gt">')
    when charindex('<', EFF_DT) > 0 then replace(EFF_DT, '<', 'c = "lt">')
    else 'c = "eq">' + EFF_DT
  end + '</cond>' as xml) as EFF_DT__cond,
  cast('<cond ' + case
    when charindex('>=', DT_CH_PRC) > 0 then replace(DT_CH_PRC, '>=', 'c = "ge">')
    when charindex('<=', DT_CH_PRC) > 0 then replace(DT_CH_PRC, '<=', 'c = "le">')
    when charindex('>', DT_CH_PRC) > 0 then replace(DT_CH_PRC, '>', 'c = "gt">')
    when charindex('<', DT_CH_PRC) > 0 then replace(DT_CH_PRC, '<', 'c = "lt">')
    else 'c = "eq">' + DT_CH_PRC
  end + '</cond>' as xml) as DT_CH_PRC__cond
from
 @t2
where
 EFF_DT is not null or DT_CH_PRC is not null
),
b as
(
 select
  LOAN_CL,
  SIMILAR_F,
  EFF_DT__cond.value('cond[1]/@c', 'char(2)') as EFF_DT__cond,
  try_cast(EFF_DT__cond.value('cond[1]', 'varchar(30)') as date) as EFF_DT__value,
  DT_CH_PRC__cond.value('cond[1]/@c', 'char(2)') as DT_CH_PRC__cond,
  try_cast(DT_CH_PRC__cond.value('cond[1]', 'varchar(30)') as date) as DT_CH_PRC__value
from
 a
)
update t
 set
  SIMILAR_F = s.SIMILAR_F
from
 @t1 t cross apply
 (
  select top (1)
   b.SIMILAR_F
  from
   b
  where
   b.LOAN_CL = t.LOAN_CL and
   (
    b.EFF_DT__cond is null or
    (b.EFF_DT__cond = 'ge' and t.EFF_DT >= b.EFF_DT__value) or
    (b.EFF_DT__cond = 'le' and t.EFF_DT <= b.EFF_DT__value) or
    (b.EFF_DT__cond = 'gt' and t.EFF_DT > b.EFF_DT__value) or
    (b.EFF_DT__cond = 'lt' and t.EFF_DT < b.EFF_DT__value) or
    (b.EFF_DT__cond = 'eq' and t.EFF_DT = b.EFF_DT__value)
   ) and
   (
    b.DT_CH_PRC__cond is null or
    (b.DT_CH_PRC__cond = 'ge' and t.DT_CH_PRC >= b.DT_CH_PRC__value) or
    (b.DT_CH_PRC__cond = 'le' and t.DT_CH_PRC <= b.DT_CH_PRC__value) or
    (b.DT_CH_PRC__cond = 'gt' and t.DT_CH_PRC > b.DT_CH_PRC__value) or
    (b.DT_CH_PRC__cond = 'lt' and t.DT_CH_PRC < b.DT_CH_PRC__value) or
    (b.DT_CH_PRC__cond = 'eq' and t.DT_CH_PRC = b.DT_CH_PRC__value)
   )
 ) s;

select * from @t1;

...
Рейтинг: 0 / 0
Связка таблиц по нескольким полям для проставления необходимого флага
    #39830984
AVRomanenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alexeyvg, авторВы это проверяли? Я бы всё таки использовал CONVERT, и явное указание формата да, проверял, все хорошо с этим.

авторНужно проставить поле 6 из таблицы 2 в таблицу 1, но вы зачем то вычисляете RVSR_F.
в таблице 2 6 поле - это флаг, который должен получиться, если все 5 условий удовлетворены.
если на примере исходных таблиц, то в первой таблице напротив 3й записи должен быть флаг Y (так как все 5 столбцов прошли условие), в остальных строках N.
авторВ нём даже не учитываются условия >, <, и т.д.
их не нужно учитывать.
...
Рейтинг: 0 / 0
Связка таблиц по нескольким полям для проставления необходимого флага
    #39830988
AVRomanenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm,
Спасибо за скрипт!
Вы не правильно поняли, в таблицу 1 не надо делать UPDATE поля SIMILAR_F, а просто добавить в SELECT в конце флаг (если 5 полей таблицы 1 прошли 5 условий таблицы 2, то проставить флаг (а какой именно указан в 6м поле таблицы 2, этот флаг для наглядности). соответственно, в первой таблице должен быть Y напротив 3й строки, N напротив остальных строк).
...
Рейтинг: 0 / 0
Связка таблиц по нескольким полям для проставления необходимого флага
    #39831053
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AVRomanenko,

имо практичнее написать CLR функцию в такой ситуации.
...
Рейтинг: 0 / 0
Связка таблиц по нескольким полям для проставления необходимого флага
    #39831297
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AVRomanenkoавторВ нём даже не учитываются условия >, <, и т.д.
их не нужно учитывать.Ээээ, тогдя я не понял условия задачи, что означает:
AVRomanenkoзнаки >= и < условия для значений соответствующих полей из таблицы 1
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Связка таблиц по нескольким полям для проставления необходимого флага
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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