sql问题:求机构的客户数量的特殊情况

同一客户可能对应2个及2个以上的机构,如果出现此情况时,平均分配给所属机构(若某一客户有两条机构都为A,一条为B,则分配给A的数量为0.6666即2/3,分配给B的数量为0.3333即1/3)
如:
TABLE1
| id | inst|
| 1001 | A |
| 1001 | A |
| 1001 | B |
| 1002 | C |
| 1003 | A |
| 1004 | A |
| 1005 | B |
| 1006 | B |
| 1007 | B |
| 1007 | C |
| 1008 | C |

期望得到结果:
| inst | amt |
| A | 2.6666 |
| B | 2.8333 |
| C | 2.5 |

最后客户总数还是8个
请教sql的语句该怎么写?成分感谢!

借用excel来说明一下:

img

SELECT 
    inst, SUM(col1)
FROM
    (SELECT 
        id,
            inst,
            (COUNT(1) / (SELECT 
                    COUNT(1)
                FROM
                    table1 t1
                WHERE
                    t1.id = t2.id)) AS col1
    FROM
        table1 AS t2
    GROUP BY t2.id , t2.inst) AS t3
GROUP BY t3.inst

首先取一个根据id和inst聚合之后,的到每个id的每个inst的总数量的t1表

img


接着再根据id聚合得到每个id的inst总数表t2

img


接着把这两个表关联一下,得到一个总表

img


然后在这个总表里根据inst聚合后,用instCount列除count列,就能得到结果了

img


完整sql如下:

select t1.inst, sum(t1.instCount/t2.count) as amt from(
    SELECT id, count(inst) as instCount, inst
    FROM table1
    group by id, inst
)t1
left join(
    select id, count(inst) as count
    FROM table1
    group by id
)t2 on t1.id = t2.id
group by t1.inst

SELECT
    t1.inst,
    sum(t1.cn1 / t2.cn2) AS amt
FROM
    (
    SELECT
        id,
        INST,
        COUNT(1) AS cn1
    FROM
        test1
    GROUP BY
        ID,
        INST)t1
JOIN (
    SELECT
        id,
        COUNT(1) AS cn2
    FROM
        test1
    GROUP BY
        ID
    ORDER BY
        id ASC) t2 ON
    t1.id = t2.id
GROUP BY
    t1.inst

img


DECLARE @data TABLE ( id INT NOT NULL,  inst VARCHAR(3))
INSERT @data(id,inst) VALUES
(1001,'A'),(1001,'A'),(1001,'B'),(1002,'C'),(1003,'A'),(1004,'A'),
(1005,'B'),(1006,'B'),(1007,'B'),(1007,'C'),(1008,'C')

SELECT      d.inst, SUM(1 / n)--1/n得到每条记录的占比,再求和即可得到结果
FROM        (   SELECT  inst, CAST(COUNT(*) OVER (PARTITION BY id) AS DECIMAL(18, 10)) n--开窗函数,计算每个ID有多少条记录
                FROM    @data) d
GROUP BY    d.inst;

1、表1你按照id聚合求一下,求每个id的次数,得到id+次数,两个字段的集合1
2、集合1通过id关联表1得到,id,inst,id次数三个字段的集合2(12步骤可用窗口函数实现)
3、集合2按照inst聚合,对 1/id次数 求和即可

表一按照id聚合求一下

真是不错 又学习到一个方法