#sql #sql-server
#sql #sql-сервер
Вопрос:
У меня есть две таблицы, в одной у меня есть такие данные:
id description
2 12.07.13y 1000eur to bank account KZ21321o0002134
4 To bank account KZasd9093636 12 of May 2016y 200dusd
И у меня есть вторая таблица, в которую мне нужно сначала поместить отфильтрованную информацию из таблицы, например:
- ID
- данные
- bank_account
- transfered_money
Сначала мне нужно разделить описание, затем мне нужно распознать ban_account, который всегда начинался с «KZ», data и transfered_money
Комментарии:
1. Какую СУБД вы используете?
2. Какую СУБД вы используете? В ORACLE (не менее 10g) вы можете использовать регулярные выражения, такие как REGEXP_SUBSTR, и попытаться разделить строку с помощью подходящего шаблона.
3. я использую sql server
4. Сколько записей у вас есть? Если меньше 1000 или около того, то повторный ввод всех данных вручную занимает меньше времени 🙂
5. Вы можете просто жестко запрограммировать все 3 случая. В противном случае вам потребуется полная возможность регулярного выражения, которая может быть интегрирована в TSql через CLR. Смотрите codeproject.com/Articles/85954/Use-RegEx-in-SQL-with-CLR-Procs или продукт третьей стороны (подойдет бесплатная версия) sqlsharp.com/features
Ответ №1:
Это просто ужасно, но, похоже, он может извлечь ban_acount:
CREATE TABLE exp
(
column1 varchar(400)
);
Insert into exp (column1) values ('12.07.13y 1000eur to bank account KZ21321o0002134');
Insert into exp (column1) values ('To bank account KZasd9093636 12 of May 2016y 200dusd');
Select
CASE
WHEN CHARINDEX ( SPACE(1), SUBSTRING ( column1, CHARINDEX('KZ' , column1),LEN(column1))) = 0
THEN SUBSTRING ( column1, CHARINDEX('KZ' , column1),LEN(column1))
ELSE SUBSTRING ( SUBSTRING (column1, CHARINDEX('KZ' , column1),LEN(column1)), 0, CHARINDEX (SPACE(1), SUBSTRING(column1, CHARINDEX('KZ' , column1),LEN(column1))))
END result
From exp
Ответ №2:
Сначала преобразуйте вашу таблицу в XML.
Затем создайте таблицу с именами месяцев / дней недели и цифрами от 1 до 3000 (или вы можете взять 2016 в качестве текущего года)
Вам понадобится таблица с валютой. Я сделал его на основе данных отсюда.
DECLARE @x xml
;WITH YourTable AS ( --I use this CTE, you should use your table in scripts below
SELECT *
FROM (VALUES
(2, '12.07.13y 1000eur to bank account KZ21321o0002134'),
(4, 'To bank account KZasd9093636 12 of May 2016y 200dusd')
) as t(id, [description])
)
SELECT @x = ( --XML sample that we get you can see below after output
SELECT CAST(N'<row id="' CAST(id as nvarchar(max)) '"><b>' REPLACE([description],' ','</b><b>') '</b></row>' as xml)
FROM YourTable
FOR XML PATH('')
)
;WITH CurrencyList AS ( --Currency table
SELECT *
FROM (VALUES
('AED', 'United Arab Emirates Dirham'),
('AFN', 'Afghanistan Afghani'),
('ALL', 'Albania Lek'),
('AMD', 'Armenia Dram'),
...
('ZAR', 'South Africa Rand'),
('ZMW', 'Zambia Kwacha'),
('ZWD', 'Zimbabwe Dollar')
) as t(code, countryname)
),cte AS ( --generate numbers 1 to 3000
SELECT 0 as d
UNION ALL
SELECT d 1
FROM cte
WHERE d < 3000
), datenames AS ( --generate datenames
SELECT d,
CASE WHEN d < 7 THEN DATENAME(weekday,DATEADD(day,d,'1970-01-01 00:00:00.000')) ELSE NULL END as weekday_name,
CASE WHEN d < 12 THEN DATENAME(month,DATEADD(month,d,'1970-01-01 00:00:00.000')) ELSE NULL END as mon_name
FROM cte
)
--Final query
SELECT t.c.value('../@id','int') as id,
t.c.value('.','nvarchar(max)') as str_part,
CASE WHEN t.c.value('.','nvarchar(max)') LIKE 'KZ%' THEN 'bank_account'
WHEN countryname IS NOT NULL THEN 'tranfered_money'
WHEN dn.d IS NOT NULL OR RIGHT(t.c.value('.','nvarchar(max)'),1) ='y' THEN 'datepart'
ELSE NULL END as what_is
FROM @x.nodes('/row/b') as t(c)
LEFT JOIN CurrencyList cl
ON RIGHT(t.c.value('.','nvarchar(max)'),3) = cl.code --check 3 last symbols of string with currency codes
LEFT JOIN datenames dn
ON dn.d = t.c.value('. cast as xs:int?','int') -- if it is a day/month/year number
OR t.c.value('.','nvarchar(max)') = dn.weekday_name -- or it is a week day name
OR t.c.value('.','nvarchar(max)') = dn.mon_name --or month name
OPTION (MAXRECURSION 0)
Принесет вам:
id str_part what_is
2 12.07.13y datepart
2 1000eur tranfered_money
2 to NULL
2 bank NULL
2 account NULL
2 KZ21321o0002134 bank_account
4 To NULL
4 bank NULL
4 account NULL
4 KZasd9093636 bank_account
4 12 datepart
4 of NULL
4 May datepart
4 2016y datepart
4 200dusd tranfered_money
После этого вам нужно привести даты в обычную форму даты и все.
Пример XML:
<row id="2">
<b>12.07.13y</b>
<b>1000eur</b>
<b>to</b>
<b>bank</b>
<b>account</b>
<b>KZ21321o0002134</b>
</row>
<row id="4">
<b>To</b>
<b>bank</b>
<b>account</b>
<b>KZasd9093636</b>
<b>12</b>
<b>of</b>
<b>May</b>
<b>2016y</b>
<b>200dusd</b>
</row>