2015-08-17 2 views
0

У меня есть таблица с диагнозами и терпеливыми. Таблица имеет один ряд для каждого диагноза с идентификатором пациента и диагнозом.SQL - подсчитывать все возможные комбинации

например

Patient ID | Diagnosis 
-----------|---------- 
0   | Asthma 
1   | Hypertension 
1   | Asthma 
2   | Asthma 
2   | Hypertension 
2   | Cancer 
3   | Asthma 

И я хотел бы выводить что-то вдоль линий

Asthma       | 4 
Hypertension     | 2 
Asthma & Hypertension   | 2 
Asthma, Hypertension and Cancer | 1 

Как я могу подсчитать количество комбинаций диагнозов с именами диагноза?

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

Некоторые пациенты имеют целых 12 диагнозов , Заранее спасибо!

+2

Редактировать Ваши вопросы и предоставить образец данные и желаемые результаты (в текстовом формате). Кроме того, пометьте вопрос с помощью базы данных, которую вы используете. –

+2

Гордон, действительно ли база данных ** действительно ** имеет значение в этом случае? Это вопрос подхода, конечно, не синтаксис? И он очень хорошо описывает данные –

+0

Сколько всего уникальных диагнозов у ​​вас есть? –

ответ

1

Это может потребоваться редактирование от кого-то более хорошо разбирающихся, чем себя в использовании FOR XML для конкатенации строк, но это один из способов сделать это:

WITH CTE AS (
SELECT 
PatientID, 
STUFF(
    (
    SELECT ', ' + [Diagnosis] 
    FROM Table 
    WHERE (PatientID = B.PatientID) 
    ORDER BY Diagnosis 
    FOR XML PATH('') 
    ) 
    ,1,1,'') AS Diagnoses 
FROM Table B 
) 

SELECT Diagnoses,COUNT(DISTINCT PatientID) as Total 
FROM CTE 
GROUP BY Diagnoses 

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

+0

@jpw Вы правы. У меня нет большого опыта использования FOR XML, поэтому я решил, что они будут автоматически сгруппированы и будут заботиться о повторяющихся значениях. –

0

Если я вас правильно понимаю, вы можете сделать это с помощью рекурсивного запроса :

with recursive all_diags as (
    select patient_id, diagnosis, diagnosis as diagnosis_list 
    from diagnostics 
    union all 
    select c.patient_id, c.diagnosis, p.diagnosis_list||','||c.diagnosis 
    from diagnostics c 
    join all_diags p on p.patient_id = c.patient_id and p.diagnosis < c.diagnosis 
) 
select diagnosis_list, count(*) 
from all_diags 
group by diagnosis_list 
order by diagnosis_list; 

Обратите внимание, что ключевое слово recursive требуется стандартом SQL, но не все СУБД фактически поддерживают это ключевое слово.

Существует разница в ожидаемом выходе: мое решение также возвращает комбинации: Cancer, Cancer,Hypertension и Asthma,Cancer, которые вы не включили в свой образец.

Вот SQLFiddle пример: http://sqlfiddle.com/#!15/21087/1