我怎样才能做一个不同的总和?
How can I do a distinct sum?
我正在尝试创建一个 "score" 统计数据,该统计数据源自特定列的值,计算为 case 表达式的总和。不幸的是,查询结构需要是一个完整的外部连接(这是从实际查询中简化的,并且连接结构从原始代码中保留下来),因此总和是不正确的,因为每一行可能出现多次。我可以按唯一键分组;但是,这会破坏同一查询中的其他聚合函数。
我真正想做的是 sum (case when ... distinct claim_id) 当然不存在;有没有一种方法可以满足我的需要?或者这是否必须是两个查询?
这是红移,以防万一。
create table t1 (id int, proc_date date, claim_id int, proc_code char(1));
create table t2 (id int, diag_date date, claim_id int);
insert into t1 (id, proc_date, claim_id, proc_code)
values (1, '2012-01-01', 0, 'a'),
(2, '2009-02-01', 1, 'b'),
(2, '2019-02-01', 2, 'c'),
(2, '2029-02-01', 3, 'd'),
(3, '2016-04-02', 4, 'e'),
(4, '2005-01-03', 5, 'f'),
(5, '2008-02-03', 6, 'g');
insert into t2 (id, diag_date, claim_id)
values (4, '2004-01-01', 20),
(5, '2010-02-01', 21),
(6, '2007-04-02', 22),
(5, '2011-02-01', 23),
(6, '2008-04-02', 24),
(5, '2012-02-01', 25),
(6, '2009-04-02', 26),
(7, '2002-01-03', 27),
(8, '2001-02-03', 28);
select id, sum(case when proc_code='a' then 5
when proc_code='b' then 10
when proc_code='c' then 15
when proc_code='d' then 20
when proc_code='e' then 25
when proc_code='f' then 30
when proc_code='g' then 35 end), count(distinct t1.claim_id) as proc_count, min(proc_date) as min_proc_date
from t1 full outer join t2 using (id) group by id order by id;
您可以将条件聚合分离到 cte
或子查询中,并使用 OVER(PARTITION BY id)
获得 id
级别聚合而不分组,如下所示:
with cte AS (SELECT *,sum(case when proc_code='a' then 5
when proc_code='b' then 10
when proc_code='c' then 15
when proc_code='d' then 20
when proc_code='e' then 25
when proc_code='f' then 30
when proc_code='g' then 35 end) OVER(PARTITION BY id) AS Some_Sum
, min(proc_date) OVER(PARTITION BY id) as min_proc_date
FROM t1
)
select id
, Some_Sum
, count(distinct cte.claim_id) as proc_count
, min_proc_date
from cte
full outer join t2 using (id)
group by id,Some_Sum,min_proc_Date
order by id;
演示:SQL Fiddle
请注意,您必须将这些聚合添加到外部查询中的 GROUP BY
,并且 PARTITION BY
中的字段应与您之前在中使用的 t1
字段匹配GROUP BY
,在本例中只是 id
,但如果您的完整查询在 GROUP BY
中有其他 t1
字段,请务必将它们添加到 PARTITION BY
您可以使用子查询(通过 id 和 id_claim)然后重新组合:
with base as (
select id, avg(case when proc_code='a' then 5
when proc_code='b' then 10
when proc_code='c' then 15
when proc_code='d' then 20
when proc_code='e' then 25
when proc_code='f' then 30
when proc_code='g' then 35 end) as value_proc,
t1.claim_id , min(proc_date) as min_proc_date
from t1 full outer join t2 using (id) group by id, t1.claim_id order by id, t1.claim_id)
select id, sum(value_proc), count(distinct claim_id) as proc_count, min(min_proc_date) as min_proc_date
from base
group by id
order by id;
看到我建议 avg
用于内部子查询,但是如果您确定相同的 claim_id 具有相同的字母,则可以使用 max
或 min
那是整数。如果不是更喜欢这个。
我正在尝试创建一个 "score" 统计数据,该统计数据源自特定列的值,计算为 case 表达式的总和。不幸的是,查询结构需要是一个完整的外部连接(这是从实际查询中简化的,并且连接结构从原始代码中保留下来),因此总和是不正确的,因为每一行可能出现多次。我可以按唯一键分组;但是,这会破坏同一查询中的其他聚合函数。
我真正想做的是 sum (case when ... distinct claim_id) 当然不存在;有没有一种方法可以满足我的需要?或者这是否必须是两个查询?
这是红移,以防万一。
create table t1 (id int, proc_date date, claim_id int, proc_code char(1));
create table t2 (id int, diag_date date, claim_id int);
insert into t1 (id, proc_date, claim_id, proc_code)
values (1, '2012-01-01', 0, 'a'),
(2, '2009-02-01', 1, 'b'),
(2, '2019-02-01', 2, 'c'),
(2, '2029-02-01', 3, 'd'),
(3, '2016-04-02', 4, 'e'),
(4, '2005-01-03', 5, 'f'),
(5, '2008-02-03', 6, 'g');
insert into t2 (id, diag_date, claim_id)
values (4, '2004-01-01', 20),
(5, '2010-02-01', 21),
(6, '2007-04-02', 22),
(5, '2011-02-01', 23),
(6, '2008-04-02', 24),
(5, '2012-02-01', 25),
(6, '2009-04-02', 26),
(7, '2002-01-03', 27),
(8, '2001-02-03', 28);
select id, sum(case when proc_code='a' then 5
when proc_code='b' then 10
when proc_code='c' then 15
when proc_code='d' then 20
when proc_code='e' then 25
when proc_code='f' then 30
when proc_code='g' then 35 end), count(distinct t1.claim_id) as proc_count, min(proc_date) as min_proc_date
from t1 full outer join t2 using (id) group by id order by id;
您可以将条件聚合分离到 cte
或子查询中,并使用 OVER(PARTITION BY id)
获得 id
级别聚合而不分组,如下所示:
with cte AS (SELECT *,sum(case when proc_code='a' then 5
when proc_code='b' then 10
when proc_code='c' then 15
when proc_code='d' then 20
when proc_code='e' then 25
when proc_code='f' then 30
when proc_code='g' then 35 end) OVER(PARTITION BY id) AS Some_Sum
, min(proc_date) OVER(PARTITION BY id) as min_proc_date
FROM t1
)
select id
, Some_Sum
, count(distinct cte.claim_id) as proc_count
, min_proc_date
from cte
full outer join t2 using (id)
group by id,Some_Sum,min_proc_Date
order by id;
演示:SQL Fiddle
请注意,您必须将这些聚合添加到外部查询中的 GROUP BY
,并且 PARTITION BY
中的字段应与您之前在中使用的 t1
字段匹配GROUP BY
,在本例中只是 id
,但如果您的完整查询在 GROUP BY
中有其他 t1
字段,请务必将它们添加到 PARTITION BY
您可以使用子查询(通过 id 和 id_claim)然后重新组合:
with base as (
select id, avg(case when proc_code='a' then 5
when proc_code='b' then 10
when proc_code='c' then 15
when proc_code='d' then 20
when proc_code='e' then 25
when proc_code='f' then 30
when proc_code='g' then 35 end) as value_proc,
t1.claim_id , min(proc_date) as min_proc_date
from t1 full outer join t2 using (id) group by id, t1.claim_id order by id, t1.claim_id)
select id, sum(value_proc), count(distinct claim_id) as proc_count, min(min_proc_date) as min_proc_date
from base
group by id
order by id;
看到我建议 avg
用于内部子查询,但是如果您确定相同的 claim_id 具有相同的字母,则可以使用 max
或 min
那是整数。如果不是更喜欢这个。