Как считать людей в сложных возрастных / гендерных / других группах? - PullRequest
3 голосов
/ 16 марта 2012

Я получил следующую таблицу Patients.

HospitalId INT,
GenderId BIT,
Age TINYINT,
DiseaseId SMALLINT

GenderId = 0 - это мужчина

GenderId = 1 - это женщина

Больница A имеетHospitalId 0

В HospitalB есть HospitalId 1

Вот вывод, который я хочу произвести:

DiseaseId | HospitalA_Male_18-30 | HospitalA_Male_31-40 |
---------------------------------------------------------
0         |   (count here)       |   (count here)       |
1         |   (count here)       |   (count here)       |
2         |   (count here)       |   (count here)       |
3         |   (count here)       |   (count here)       |

(продолжение столбцов)

HospitalA_Female_18-30 | HospitalA_Female_31-40 |
-------------------------------------------------
    (count here)       |     (count here)       |
    (count here)       |     (count here)       |
    (count here)       |     (count here)       |
    (count here)       |     (count here)       |

(продолжение столбцов)

HospitalB_Male_18-30 | HospitalB_Male_31-40 |
---------------------------------------------
    (count here)     |     (count here)     |
    (count here)     |     (count here)     |
    (count here)     |     (count here)     |
    (count here)     |     (count here)     |

(продолжение столбцов)

HospitalB_Female_18-30 | HospitalB_Female_31-40 |
-------------------------------------------------
    (count here)       |     (count here)       |
    (count here)       |     (count here)       |
    (count here)       |     (count here)       |
    (count here)       |     (count here)       |

(9 столбцов в наборе результатов)

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

Как такое группирование можно сделать (наиболее эффективно) в T-SQL

Ответы [ 2 ]

3 голосов
/ 16 марта 2012

Вы можете сделать это с помощью сводного запроса:

select * from 
(
  select diseaseid, 
         'Hospital'
         + case hospitalid when 0 then 'A' when 1 then 'B' end
         + '_'
         + case genderid when 1 then 'Female' else 'Male' end
         + '_'
         + case when age between 18 and 30 
              then '18-30' 
              else (case when age between 31 and 40 then '31-40' end) 
              end Title,
         1 Cnt
  from Patients
  where age between 18 and 40
) t
pivot (
  count (Cnt) for Title in (
    [HospitalA_Male_18-30],   [HospitalA_Male_31-40],
    [HospitalA_Female_18-30], [HospitalA_Female_31-40],
    [HospitalB_Male_18-30],   [HospitalB_Male_31-40],
    [HospitalB_Female_18-30], [HospitalB_Female_31-40]
  )
) as Q

ОБНОВЛЕНИЕ

В качестве развития вышеуказанного решения вы также можете переместить части имени изВыражения CASE к их собственным виртуальным таблицам и присоединение к ним таблицы Patients:

;with
hospital (hospitalid, hospitalname) as (
  select 0, 'HospitalA' union all
  select 1, 'HospitalB'
),
gender (genderid, gendername) as (
  select 0, 'Male' union all
  select 1, 'Female'
),
agerange (agefrom, ageto) as (
  select 18, 30 union all
  select 31, 40
)
select * from 
(
  select p.diseaseid, 
         h.hospitalname + '_' + g.gendername + '_'
         + rtrim(a.agefrom) + '-' + rtrim(a.ageto) as Title,
         1 Cnt
  from Patients p
    inner join hospital h on p.hospitalid = h.hospitalid
    inner join gender   g on p.genderid   = g.genderid
    inner join agerange a on p.age between a.agefrom and a.ageto
  where p.age between 18 and 40
) t
pivot (
  count (Cnt) for Title in (
    [HospitalA_Male_18-30],   [HospitalA_Male_31-40],
    [HospitalA_Female_18-30], [HospitalA_Female_31-40],
    [HospitalB_Male_18-30],   [HospitalB_Male_31-40],
    [HospitalB_Female_18-30], [HospitalB_Female_31-40]
  )
) as Q

Затраты на добавление вложенных элементов и объединений компенсируются большей простотой обслуживания:

  • часть (мета) данных отделена от логической части;

  • списки частей имени удобнее расширять при необходимости;

  • выражение конкатенации легче изменить, если вам нужно изменить формат имен целевых столбцов.

3 голосов
/ 16 марта 2012

Пожалуйста, попробуйте это

SELECT  
    DiseaseId,
    SUM(CASE WHEN HospitalId = 0 AND GenderId=0 AND (Age BETWEEN 18 AND 30)  THEN 1 ELSE 0 END) AS [HospitalA_Male_18-30],
    SUM(CASE WHEN HospitalId = 0 AND GenderId=0 AND (Age BETWEEN 31 AND 40)  THEN 1 ELSE 0 END) AS [HospitalA_Male_31-40],  
    SUM(CASE WHEN HospitalId = 0 AND GenderId=1 AND (Age BETWEEN 18 AND 30)  THEN 1 ELSE 0 END) AS [HospitalA_Female_18-30],    
    ......  
FROM   Patients 
GROUP BY DiseaseId
ORDER BY DiseaseId  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...