2016-01-08 65 views
1

由於我是SQL Server的新手,請耐心等待。我正在處理一個有大約2850個人的數據集,他們多次出現,大約有18,500行,所以雖然我可以手工編輯,但這需要一段時間。我想要做到以下幾點:正常化數據以便在SQL Server 2008中選擇獨特

SELECT DISTINCT ID, RACE 
INTO new_table 
FROM table_name; 

但事實證明,我的比賽數據沒有得到很好的清理。如下所示,Person 27已被列爲白人和西班牙裔。不是每個人都有這個問題,但很多人都這麼做。

+----+----------+ 
| ID | RACE | 
+----+----------+ 
| 27 | Hispanic | 
| 27 | Hispanic | 
| 27 | White | 
| 27 | White | 
| 27 | White | 
| 27 | White | 
+----+----------+ 

我希望通過數據來運行,採取使用列出的大部分比賽的情況下,並重新分配給他們,這樣我就可以SELECT DISTINCT。因此,它會從表上面去到:

+----+----------+ 
| ID | RACE | 
+----+----------+ 
| 27 | White | 
| 27 | White | 
| 27 | White | 
| 27 | White | 
| 27 | White | 
| 27 | White | 
+----+----------+ 

我意識到,這可能需要多個步驟,但人有我怎麼能做到這一點,而不是手工清洗,或在Stata做一個想法或Excel?謝謝!

+0

它可以寫成多個查詢,或者你想在簡單的大查詢做這項工作? – wmehanna

+0

我更喜歡一個大的,但如果多個是最好的方式,那很好。 – seder163

回答

0

你可以做到這一點使用row_number()和聚集:

SELECT ID, RACE 
INTO new_table 
FROM (SELECT id, race, count(*) as cnt, 
      ROW_NUMBER() OVER (PARTITION BY id ORDER BY COUNT(*) DESC) as seqnum 
     FROM table_name 
     GROUP BY id, race 
    ) ir 
WHERE seqnum = 1; 

注:在關係的情況下,這將任意選擇一個種族。

ROW_NUBMER()是一個窗口/排名函數。它會從PARTITION BY條款定義的每個組開始分配連號。訂購由ORDER BY指定。因此,值「1」被分配給每個id的值最大的COUNT(*)的行。 。 。外面的WHERE選擇這一行。

+0

你真該死! – wmehanna

+0

謝謝,它工作得很漂亮! – seder163

+0

我不知道爲什麼這得到了downvote。 –

0

這可能不是最好的或最有效的方式,但我會使用row_number()common table expression的組合。

只使用你所提供的數據,這個工作對我來說:

create table #temp (
id int, 
race varchar(10) 
) 


insert into #temp 
select 27, 'Hispanic' 
union all select 27, 'Hispanic' 
union all select 27, 'White' 
union all select 27, 'White' 
union all select 27, 'White' 
union all select 27, 'White' 




with foo 
as (
    select id, 
     race, 
     row_number() over (partition by id, race order by id, race) as cnt 
    from #temp 
) 
update #temp 
set race = (
    select top 1 race 
    from foo 
    where id = #temp.id 
    order by cnt desc 
) 


select * 
from #temp 

我建議先在的情況下創建數據備份的東西都被打亂。

我也提供了一個SQLFiddle鏈接,但該網站似乎沒有在這個時候做出響應。