2016-05-20 7 views
0

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

Один из способов сделать это является разделение по идентификатору, а затем подсчитать, сколько раз встречается каждое значение, сохраняя при этом высокий счетчик для каждого ID:

DROP TABLE dbo.table 
SELECT DISTINCT [id], [ethnic_group] AS [ethnic_mode], ct INTO dbo.table 
FROM (
    SELECT row_number() OVER (PARTITION BY [id] ORDER BY count([ethnic_group]) DESC) as rn, count([ethnic_group]) as ct, [ethnic_group], [id] 
    FROM 
    dbo.mytable GROUP BY [id], [ethnic_group]) ranked 
    where rn = 1 
ORDER BY ct DESC 

Но я хочу сделать это для нескольких переменных (этнических группа, группа доходов и еще несколько).

Как выбрать режим для нескольких переменных внутри одного оператора и вставить в одну таблицу (вместо создания отдельных таблиц для каждой переменной)?

В таблице ниже приведен пример того, что я хочу сделать:

DROP TABLE mytable; 
CREATE TABLE mytable(
    id  VARCHAR(2) NOT NULL PRIMARY KEY 
    ,ethnic_group VARCHAR(12) NOT NULL 
    ,ethnic_mode VARCHAR(11) NOT NULL 
    ,income VARCHAR(6) NOT NULL 
    ,income_mode VARCHAR(11) NOT NULL 
); 
INSERT INTO mytable(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('id','ethnic_group','ethnic_mode','income','income_mode'); 
INSERT INTO mytable(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('1','white','white','middle','middle'); 
INSERT INTO mytable(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('1','white','white','middle','middle'); 
INSERT INTO mytable(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('1','mixed','white','high','middle'); 
INSERT INTO mytable(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('2','asian','asian','middle','middle'); 
INSERT INTO mytable(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('2','mixed','asian','middle','middle'); 
INSERT INTO mytable(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('2','asian','asian','middle','middle'); 

ответ

0

Я хотел бы использовать подзапросы для достижения этой цели в 1 вставной заявлении.

Вот пример, основанный на структуре таблицы с вашей иллюстрации:

/* This is the original table and contains duplicate ID's */ 
DECLARE @source_table TABLE(
    id  VARCHAR(2) NOT NULL 
    ,ethnic_group VARCHAR(12) NULL 
    ,ethnic_mode VARCHAR(11) NULL 
    ,income VARCHAR(6) NULL 
    ,income_mode VARCHAR(11) NULL 
); 

/* This is the destination table and will not contain duplicate ID's */ 
DECLARE @destination_table TABLE(
    id  VARCHAR(2) NOT NULL PRIMARY KEY 
    ,ethnic_group VARCHAR(12) NULL 
    ,income VARCHAR(6) NULL 
); 

/* Populate the source table with data */ 
INSERT INTO @source_table(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('1','white','white','middle','middle'); 
INSERT INTO @source_table(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('1','white','white','middle','middle'); 
INSERT INTO @source_table(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('1','mixed','white','high','middle'); 
INSERT INTO @source_table(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('2','asian','asian','middle','middle'); 
INSERT INTO @source_table(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('2','mixed','asian','middle','middle'); 
INSERT INTO @source_table(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('2','asian','asian','middle','middle'); 
INSERT INTO @source_table(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('3','asian', NULL, NULL, NULL); 
INSERT INTO @source_table(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('3',NULL, NULL,'middle', NULL); 
INSERT INTO @source_table(id,ethnic_group,ethnic_mode,income,income_mode) VALUES ('3',NULL, NULL, NULL, NULL); 

/* Insert from source into destination (removing duplicates) */ 
INSERT INTO @destination_table 
     (
      id 
     , ethnic_group 
     , income 
     ) 
SELECT st.id 
    , (
     SELECT TOP 1 ethnic_group 
     FROM @source_table sub_st 
     WHERE sub_st.id = st.id 
     GROUP BY ethnic_group 
     ORDER BY COUNT(sub_st.id) DESC 
    ) 
    , (
     SELECT TOP 1 income 
     FROM @source_table sub_st 
     WHERE sub_st.id = st.id 
     GROUP BY income 
     ORDER BY COUNT(sub_st.id) DESC 
    ) 
FROM @source_table st 
GROUP BY st.id 


/* View the destination to see there are no duplicates */ 
SELECT id 
     , ethnic_group 
     , income 
FROM @destination_table 
+0

Я хочу включить NULL значения (так что, если они в основном нуль, режим по-прежнему NULL). Когда я попробовал это на реальных данных, NULL был проигнорирован, и режим был назначен только на основе NULL. – user2964644

+0

@ user2964644 Я обновил свой ответ, чтобы обрабатывать значения NULL. –