sql问题:求机构的客户数量
每个机构有不同的客户经理,若一个客户在同一个机构中归属两个或以上的客户经理,则该客户对归属客户经理业务发生日期最早的计算一户客户数,其他客户经理不计算客户数。(同一客户可能对应2个及2个以上的机构,但只计算该在同一机构内的数量)
TABLE1
| id | inst|manager|time|
| 1001 | A |B01|20220101|
| 1001 | A |B02|20220208|
| 1002 | A |B01|20220115|
| 1003 | A |B03|20220209|
| 1004 | A |B04|20220312|
| 1005 | B |B05|20220109|
| 1006 | B |B06|20220301|
| 1007 | B |B07|20220123|
| 1007 | C |B08|20220103|
| 1008 | C |B09|20220315|
期望得到结果:
| inst | manager|amt |
| A | B01 | 2 | --客户为1001、1002
| A | B02 | 0 | --无客户
| A | B03 |1 | --客户为1003
| A | B04 |1 | --客户为1004
| B |B05 |1 | --客户为1005
| B |B06 |1 | --客户为1006
| B |B07 |1 | --客户为1007
| C |B08 |1 | --客户为1007
| C |B09 |1 | --客户为1008
请教sql的语句该怎么写?成分感谢!(右侧--客户为1001内容为解释说明,非要回显的结果)
SELECT
inst, manager, COUNT(DISTINCT id) as amt
FROM (
SELECT
id, inst, manager, time,
ROW_NUMBER() OVER (PARTITION BY id, inst ORDER BY time) as row_num
FROM
TABLE1
) AS t
WHERE
row_num = 1
GROUP BY
inst, manager
该语句首先使用子查询来对每个客户和机构的客户经理进行排序,获取业务发生日期最早的那个。然后在外层查询中使用 COUNT(DISTINCT id) 来统计每个机构和客户经理的客户数量。
请注意,这是在 MySQL 中的语法,如果您使用的是其他数据库系统,语法可能会有所不同。
可以使用 EXISTS 和 NOT EXISTS 来实现:
SELECT inst, manager, COUNT(DISTINCT id) as amt
FROM TABLE1 t1
WHERE NOT EXISTS (
SELECT 1
FROM TABLE1 t2
WHERE t1.id = t2.id AND t1.inst = t2.inst AND t1.time > t2.time
)
GROUP BY inst, manager
这个查询会检查每一行是否存在其他行在同一机构内具有相同客户编号且业务发生时间更早。如果不存在这样的行,就表示该行是该客户在该机构内归属给客户经理业务发生日期最早的那个客户经理。按照机构和客户经理分组统计数量。
仅供参考,望采纳,谢谢。
你可以使用如下的 SQL 查询来实现这个需求:
WITH cte AS (
SELECT id, inst, manager, time,
ROW_NUMBER() OVER (PARTITION BY id, inst ORDER BY time) AS rn
FROM TABLE1
)
SELECT inst, manager, COUNT(id) as amt
FROM cte
WHERE rn = 1
GROUP BY inst, manager
说明:
使用CTE(Common Table Expression)查询来实现,其中 ROW_NUMBER() OVER (PARTITION BY id, inst ORDER BY time) 语句分别对每个机构中的客户进行排序,并为每个客户分配一个编号。
然后在查询中筛选 rn=1 的客户,并按照机构和客户经理进行分组,求出每个机构和客户经理的客户数量。
DECLARE @t TABLE ( id INT, inst VARCHAR(10),manager VARCHAR(10),TIME VARCHAR(10))
INSERT @t(id,inst,manager,TIME)VALUES
(1001,'A','B01','20220101'),(1001,'A','B02','20220208'),(1002,'A','B01','20220115'),
(1003,'A','B03','20220209'),(1004,'A','B04','20220312'),(1005,'B','B05','20220109'),
(1006,'B','B06','20220301'),(1007,'B','B07','20220123'),(1007,'C','B08','20220103'),
(1008,'C','B09','20220315')
;WITH t AS (SELECT *,ROW_NUMBER() OVER (PARTITION BY inst,id ORDER BY TIME) Seq FROM @t)
SELECT DISTINCT a.inst,a.manager,
(SELECT COUNT(*) FROM t b WHERE b.inst=a.inst AND b.manager=a.manager AND b.Seq=1) amt
FROM t a