Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Коллеги, интересный запрос!  [new]
LewaIowa
Member

Откуда:
Сообщений: 2
Коллеги, добрый день!

Возникла интересная задачка:
необходимо расшифровать составное поле типа 000000000A, S00000000A

Привожу легенду:
+
select 1 Num,'S' Code,'SAP' Description 
union all 
select 5,'F','Oracle'
union all 
select 10,'A','Axapta'
union all 
select 12,'S','SQL' 

, где
Num -- позиция,
Code -- значение,
Description -- требуемая расшифровка

Соответственно, результирующая табличка должна иметь следующий вид:


Num Code Description <поле, требующее расшифровки>
10 A Axapta 000000000A
10 A Axapta S00000000A
1 S SAP S00000000A

000000000A -- 1 значение (A-10) => 1 строка
S00000000A -- 2 значения (S-1 ; A-10) => 2 строки

Как бы это половчее сделать средствами MSSQL?)

Модератор: Тема перенесена из форума "Работа".


Сообщение было отредактировано: 10 сен 18, 19:39
10 сен 18, 19:09    [21670203]     Ответить | Цитировать Сообщить модератору
 Re: Коллеги, интересный запрос!  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 20223
А в чём проблема-то? CTE-таблица наборов (буква-позиция-расшифровка), CROSS JOIN да проверка...
10 сен 18, 19:48    [21670241]     Ответить | Цитировать Сообщить модератору
 Re: Коллеги, интересный запрос!  [new]
Владимир Затуливетер
Member

Откуда:
Сообщений: 427
-- запрос работает только для расшифровываемых кодов длиной не более 12 символов, 
-- если надо больше добавьте значения в cteNumbers
with cteNumbers as (select * from (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12))t(Num)),
cteLeg (Num, Code, Description)
as (
              select 1, 'S','SAP' 
    union all select 5, 'F','Oracle'
    union all select 10,'A','Axapta'
    union all select 12,'S','SQL'
),
cteData (Val)
as (
              select '000000000A' 
    union all select 'S00000000A'
)
select sym.Num
     , leg.Code
     , leg.Description
     , d.Val
from cteData d
    -- создаем последовательность для каждого символа расшифровываемого кода
    cross apply (select * from cteNumbers n where n.Num <= len(d.Val)) sym 
    -- проверяем каждый символ расшифровываемого кода на совпадение в легенде
    cross apply (select * from cteLeg l where l.Num = sym.Num and l.Code = substring(d.Val, sym.Num, 1)) leg


Num Code Description Val
----------- ---- ----------- ----------
1 S SAP S00000000A
10 A Axapta 000000000A
10 A Axapta S00000000A

(3 rows affected)
11 сен 18, 08:21    [21670474]     Ответить | Цитировать Сообщить модератору
 Re: Коллеги, интересный запрос!  [new]
court
Member

Откуда:
Сообщений: 1956
Владимир Затуливетер
-- запрос работает только для расшифровываемых кодов длиной не более 12 символов, 
-- если надо больше добавьте значения в cteNumbers
with cteNumbers as (select * from (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12))t(Num)),

зачем вообще нужен cteNumbers ?
Ведь в исх.данных уже есть позиция, на которой нужно проверять символ ...

with cteLeg (Num, Code, Description)
as (
              select 1, 'S','SAP' 
    union all select 5, 'F','Oracle'
    union all select 10,'A','Axapta'
    union all select 12,'S','SQL'
),
cteData (Val)
as (
              select '000000000A' 
    union all select 'S00000000A'
)

select
	a.Val
	,b.Code
	,b.Description
	,b.Num
from cteData a inner join cteLeg b on substring(a.Val, b.Num, 1) = b.Code
order by 1

ValCodeDescriptionNum
000000000AAAxapta10
S00000000ASSAP1
S00000000AAAxapta10
11 сен 18, 10:22    [21670599]     Ответить | Цитировать Сообщить модератору
 Re: Коллеги, интересный запрос!  [new]
LewaIowa
Member

Откуда:
Сообщений: 2
Все гениальное на поверку оказывается чрезвычайно просто.
Коллеги, спасибо большое!
11 сен 18, 11:02    [21670652]     Ответить | Цитировать Сообщить модератору
 Re: Коллеги, интересный запрос!  [new]
Владимир Затуливетер
Member

Откуда:
Сообщений: 427
court,

да точно
11 сен 18, 12:42    [21670811]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить