SQL Aggregate函数,用于根据3列过滤数据

问题描述 投票:0回答:3

我有以下索赔数据。我需要根据特定年龄组,性别和健康状况查找索赔数量。我想弄清楚是否有办法在结果表中添加每个年龄组的TotalClaims。现在我在下面的查询中添加了Sum(d.totalclaims)这是错误的,因为它是根据条件和性别而不是年龄组过滤的。如何根据所有三个条件(年龄,条件,性别)获得索赔。请提出任何想法/建议!

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 

年龄表

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

条件表

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

索赔表

+----+---------+
| ID | ClaimID |
+----+---------+
|  1 | A11     |
|  1 | 345     |
|  1 | A32     |
|  2 | 542     |
|  2 | 675     |
+----+---------+
sql sql-server aggregate-functions
3个回答
0
投票

年龄组表缺失。使用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));

我不明白为什么你需要那些DISTINCT选择,但我保持原样。


1
投票

我希望将年龄分成一列,而不是每列都有列。

这样的事情能满足你的需求吗?

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

1
投票

这是您要查找的查询:

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
© www.soinside.com 2019 - 2024. All rights reserved.