简体   繁体   English

SQL Aggregate函数基于3列过滤数据

[英]SQL Aggregate function to filter data based on 3 columns

I have the below Claims data. 我有以下索赔数据。 I need to find the number of claims based on a certain age group, gender, and Health condition. 我需要根据特定年龄段,性别和健康状况找到索赔的数量。 I'm trying to figure out if there is a way to add TotalClaims per age group in the result table. 我试图找出是否有一种方法可以在结果表中按年龄段添加TotalClaims。 Right now I've added Sum(d.totalclaims) in the below query which is wrong because it is filtered based on condition and gender and not age group. 现在,我在以下查询中添加了Sum(d.totalclaims) ,这是错误的,因为它是根据条件和性别而不是年龄组进行过滤的。 How to get claims based on all three conditions(age, condition, gender). 如何基于所有三个条件(年龄,条件,性别)获得索赔。 Any ideas/suggestions, please! 任何想法/建议,请!

SELECT c.condition, 
       a.gender, 
       Sum(CASE WHEN a.age BETWEEN 40 AND 50 THEN 1 END) AS Members_40_50_years, 
       Sum(d.totalclaims) 
FROM   (SELECT DISTINCT id, gender, age FROM   agetable) AS a 
       INNER JOIN (SELECT DISTINCT id, condition 
                   FROM   conditiontable) AS c 
               ON a.id = c.id 
       INNER JOIN (SELECT Count(DISTINCT claimid) AS TotalClaims, id 
                   FROM   claimstable group by id) d 
               ON d.id = a.id 
GROUP  BY gender, 
          condition 

Age Table 年龄表

+----+--------+-----+
| ID | Gender | Age |
+----+--------+-----+
|  1 | M      |  45 |
|  2 | F      |  60 |
+----+--------+-----+

Condition Table 条件表

+----+--------------+
| ID |  Condition   |
+----+--------------+
|  1 | HeartFailure |
|  1 | Diabetes     |
|  2 | Diabetes     |
+----+--------------+

Claims Table 索偿表

+----+---------+
| ID | ClaimID |
+----+---------+
|  1 | A11     |
|  1 | 345     |
|  1 | A32     |
|  2 | 542     |
|  2 | 675     |
+----+---------+

I'd look to group the ages into one column rather than having columns for each one. 我希望将年龄分组到一列,而不是每列都有一列。

Does something like this give you what you need? 这样的事情能给您您所需要的吗?

SELECT
    A.Gender
    ,
        CASE
            WHEN A.Age BETWEEN 30 AND 40 THEN '30-40'
            WHEN A.Age BETWEEN 40 AND 50 THEN '40-50'
            --etc.
        END AgeGroup
    , CD.Condition
    , COUNT(*) TotalClaims
FROM
    agetable A
    JOIN conditiontable CD ON A.ID = CD.ID
    JOIN claimstable CL ON A.ID = CL.ID
GROUP BY
    A.Gender
    ,
        CASE
            WHEN A.Age BETWEEN 30 AND 40 THEN '30-40'
            WHEN A.Age BETWEEN 40 AND 50 THEN '40-50'
            --etc.
        END
    , CD.Condition

This is the query you are looking for: 这是您要查找的查询:

drop table if exists #age, #condition, #claims 

create table #age
(
id      int,
gender  char(1),
Age     int
);

insert  into 
#age    values (1,'M',45), (2,'F',60)

create table #Conditon
(
Id          int,    
Condition   nvarchar(30)
);

insert      into 
#Conditon   values (1, 'HeartFailure'), (1,'Diabetes'), (2, 'Diabetes')

create table #claims    
(
Id      int,
ClaimId nvarchar(4)
)

insert  into 
#claims values (1, 'A11'), (1, '345'), (1, 'A32'), (2, '542'), (2, '675')



SELECT  a.gender
        , a.Age
        , con.Condition
        , count(distinct cl.ClaimId) as ClaimCnt
FROM    #claims cl
JOIN    #Conditon con
        on cl.Id = con.Id
join    #age a
        on a.id = cl.Id
group 
by      a.gender
        , a.Age
        , con.Condition

The age groups table is missing. 年龄组表丢失。 Using Chris Mack's setup 使用Chris Mack的设置

create table #age
(
id      int,
gender  char(1),
Age     int
);

insert  into 
#age    values (1,'M',45), (2,'F',60)

create table #Condition
(
Id          int,    
Condition   nvarchar(30)
);

insert      into 
#Condition   values (1, 'HeartFailure'), (1,'Diabetes'), (2, 'Diabetes');

create table #claims    
(
Id      int,
ClaimId nvarchar(4)
);


insert  into 
#claims values (1, 'A11'), (1, '345'), (1, 'A32'), (2, '542'), (2, '675');

-- table of ranges
create table #agerange    
(
rfrom   int,
rto int
);
insert  into 
#agerange values (0,39),(40,50),(51,70);

SELECT c.condition, 
       a.gender, 
       cast(r.rfrom as varchar(3))+'_'+cast(r.rto as varchar(3)) range,
       Sum(d.totalclaims) 
FROM   (SELECT DISTINCT id, gender, age FROM  #age) AS a 
       INNER JOIN #agerange r ON a.age BETWEEN r.rfrom and r.rto
       INNER JOIN (SELECT DISTINCT id, condition 
                   FROM   #condition) AS c 
               ON a.id = c.id 
       INNER JOIN (SELECT Count(DISTINCT claimid) AS TotalClaims, id 
                   FROM   #claims group by id) d 
               ON d.id = a.id 
GROUP  BY gender, 
          condition,
          cast(r.rfrom as varchar(3))+'_'+cast(r.rto as varchar(3));

I don't understand why you need those DISTINCT selects, but I've kept it as is. 我不明白您为什么需要这些DISTINCT选择,但我保持原样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM