0

次のようなサンプルデータがあります。

Johnson; Michael, Surendir;Mishra, Mohan; Ram
Johnson; Michael R.
Mohan; Anaha
Jordan; Michael
Maru; Tushar

クエリの出力は次のようになります。

Johnson; Michael   2
Mohan; Anaha       1
Michael; Jordon    1
Maru; Tushar       1
Surendir;Mishra    1
Mohan; Ram         1

ご覧のとおり、各名前の数を で区切って出力していますが、ねじれがあります。名前にミドルネームの最初のイニシャルが含まれる場合と含まれない場合があるため、フルネームでグループバイを単純に実行することはできません。例えば。Johnson; Michael単一の名前としてカウントさJohnson; Michael R.れるため、それらのカウントは 2 です。さらに、カウント2 で結果セットに表示されるJohnson; MichaelJohnson; Michael R.、表示される必要があります (両方ではありません。これはレコードが繰り返されるためです)。

テーブルには で区切られた名前が含まれています。これは LIVE であり、他の誰かから提供されたものであるため、非正規化することはできません。

カーソルを使用せずにこれに対するクエリを作成する方法はありますか? DB には約 300 万件のレコードがあり、ページネーションなどもサポートする必要があります。これを達成するための最良の方法は何だと思いますか?

4

1 に答える 1

2

これが、データを正規化する必要がある理由です。

;with cte as  
( 
    select 1 as Item, 1 as Start, CHARINDEX(',',People+',' , 1) as Split, 
           People+',' as People 
    from YourHorribleTable
    union all 
    select cte.Item+1, cte.Split+1, nullif(CHARINDEX(',',people, cte.Split+1),0), People as Split 
    from cte 
    where cte.Split<>0   
)    
select Person, COUNT(*)
from
(
select case when nullif(charindex (' ', person, 2+nullif(CHARINDEX(';', person),0)),0) is null then person  
    else substring(person,1,charindex (' ', person, 2+nullif(CHARINDEX(';', person),0)))
    end as Person
from
(
select LTRIM(RTRIM( SUBSTRING(people, start,isnull(split,len(People)+1)-start))) as person
from cte  
) v
where person<>''
) v
group by Person
order by COUNT(*) desc
于 2012-09-12T11:46:21.107 に答える