2017-02-08 3 views
-1

У меня есть таблица с 1000 + строк в базе данных, где у меня есть данные, аналогичные следующим образом:Группировка данных с SQL или регулярным выражением

company_name - revenue 
123 opel AA - 100 
234 GForm BB - 200 
245 opel DF - 250 
235 Gform BC - 350 

Я хочу, чтобы суммировать доходы для компаний, где часть названия и Opel для всех, где часть названия Gform так я вижу:

opel - 350 
gform - 550 

Я хочу, чтобы подвести итог, если часть имени будет совпадать с частью названия из другого ряда. Я не знаю всех имен, которые я хочу обобщить. Я могу, конечно, перейти вручную, но должен быть способ принять все части имени и сопоставить их с частью названия компании в любой строке.

+1

Сколько таких подстрок у вас есть? и будут ли они всегда встречаться с фиксированным начальным и конечным индексом? –

+0

Максимум 8 подстрок, но наиболее распространены 4 подстроки. Нет, они не начинаются с фиксированного начального или конечного индекса. Число, в начале, всегда фиксированный размер, но может быть www. перед некоторыми именами, а не перед другими. – Imageree

+0

Просто сгенерируйте SQL с операторами 'case', как показано ниже, как только вы получите список подстрок. –

ответ

1

Другой вариант ParseName()

Select Co = parsename(replace(company_name,' ','.'),2) 
     ,Revenue = sum(revenue) 
From YourTable 
Group By parsename(replace(company_name,' ','.'),2) 

Возвращает

Co  Revenue 
GForm 550 
opel 350 
+0

Я не знаю имена opel и gform - поэтому я не могу добавить их в подобное заявление. – Imageree

+0

@Imageree затем удалить WHERE –

+0

@Imageree, вы говорите, что название компании может иметь любой шаблон –

0

здесь один из возможных способов сделать это ..

;with mycte as (
select 
'123 opel AA - 100' as rawdata 
union all 
select 
'234 GForm BB - 200 ' 
union all 
select 
'245 opel DF - 250' 
union all 
select 
'235 Gform BC - 350' 
) 
,mycte2 as (
Select 
rawdata 

,ltrim(reverse(left(reverse(rawdata),charindex('-',reverse(rawdata))-1))) as quantity 

,left(substring(rawdata, 
    charindex(' ', rawdata) + 1, len(rawdata)), 
    charindex(' ', substring(rawdata, charindex(' ', rawdata) + 2, len(rawdata)))) as model 

from mycte 
) 

Select model, sum(cast(quantity as int)) total 
from mycte2 

group by model 
+0

, приведенный выше ответ предполагает, что возвращенная строка представляет собой длинную часть строки, а не отдельные столбцы. После того, как у вас есть сводка, вы можете присоединиться к «другой» таблице с названиями автомобилей (Open и т. Д.) И ограничить список только теми, которые вас интересуют. – Harry

+0

* Opel .. not Open и т. – Harry

0

Это будет выполнять нечеткий матч , но есть потенциальные ловушки, но вы можете настроить логику и/или фильтр s

Я хотел бы добавить, если вы не можете использовать UDF, логика может быть легко перенесен в CROSS ОТНОСИТЬСЯ

Declare @YourTable table (company_name varchar(25),revenue int) 
Insert Into @YourTable values 
('123 opel AA' , 100 ), 
('234 GForm BB' , 200 ), 
('245 opel DF' , 250 ), 
('235 Gform BC' , 350 ) 


Select CoName = RetVal 
     ,Revenue = sum(Revenue) 
     ,Records = count(Distinct Company_Name) 
     ,Min_Co = min(company_name) 
     ,Max_Co = max(company_name) 
From @YourTable A 
Cross Apply [dbo].[udf-Str-Parse](A.Company_Name,' ') B 
Where len(RetVal)>3      -- significant word lenth 
    and try_convert(float,RetVal) is null -- exlude numeric values 
Group By RetVal 

возвращений

CoName Revenue Records Min_Co  Max_Co 
GForm 550  2   234 GForm BB 235 Gform BC 
opel 350  2   123 opel AA 245 opel DF 

синтаксический анализ UDF при необходимости

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10)) 
Returns Table 
As 
Return ( 
    Select RetSeq = Row_Number() over (Order By (Select null)) 
      ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)'))) 
    From (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i) 
); 
--Thanks Shnugo for making this XML safe 
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',') 
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ') 
--Select * from [dbo].[udf-Str-Parse]('this,is,<test>,for,< & >',',') 
Смежные вопросы