Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Связка таблиц по нескольким полям для проставления необходимого флага / 11 сообщений из 11, страница 1 из 1
26.06.2019, 17:31
    #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
26.06.2019, 18:16
    #39830833
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Связка таблиц по нескольким полям для проставления необходимого флага
Без кавычек 2019-03-01 = 2015, и это целое число, а не дата.
Преобразование в дату этого числа даст 9 июля 1905 года.

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

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

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

посмотри здесь 13088610
имхо, лучший выход
...
Рейтинг: 0 / 0
27.06.2019, 09:51
    #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
27.06.2019, 09:55
    #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
27.06.2019, 10:22
    #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
27.06.2019, 10:33
    #39830984
AVRomanenko
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Связка таблиц по нескольким полям для проставления необходимого флага
alexeyvg, авторВы это проверяли? Я бы всё таки использовал CONVERT, и явное указание формата да, проверял, все хорошо с этим.

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

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


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