我需要创建一个"卷起来"斜线"分组"查看我们客户的客户数据。
简化说明是,数据需要按地理(例如国家,省,市等)数据分组,并按照拥有电子邮件地址和/或电话号码的人数累计。
问题是,一个人可以在多个城市(最低级别),然后在任何更高级别(前省)计数多次。
以下是使用GROUPING SETS的示例:
DECLARE @Customer TABLE
(
CustomerId VARCHAR(50),
Phone BIT,
Email BIT,
ProvinceId VARCHAR(50),
CityId VARCHAR(50)
)
INSERT INTO @Customer(CustomerId, Phone, Email, ProvinceId, CityId) VALUES ('Customer A', 1, NULL, 'Province A', 'City A')
INSERT INTO @Customer(CustomerId, Phone, Email, ProvinceId, CityId) VALUES ('Customer A', 1, NULL, 'Province A', 'City B')
INSERT INTO @Customer(CustomerId, Phone, Email, ProvinceId, CityId) VALUES ('Customer B', 1, 1, 'Province A', 'City B')
SELECT COUNT(Phone) PersonWithPhoneCount, COUNT(Email) PersonWithEmailCount, ProvinceId, CityId FROM @Customer
GROUP BY GROUPING SETS ((ProvinceId), (ProvinceId, CityId))
这就是结果:
----------------------------------------------------------------------------
| PersonWithPhoneCount | PersonWithEmailCount | ProvinceId | CityId |
----------------------------------------------------------------------------
| 1 | 0 | Province A | City A |
| 2 | 1 | Province A | City B |
| 3 | 1 | Province A | NULL |
----------------------------------------------------------------------------
结果对于最低级别(城市)是正确的,但对于省级"客户A"被计算两次。我理解为什么,但有没有办法不计算"客户A"两次?
我是否必须单独对所有不同级别进行分组,还是有更好的方法?
性能也是一个主要问题,因为实时数据总计超过1亿行。
提前致谢。
答案 0 :(得分:0)
即使您的数据存在错误,因为客户A无法进入城市A和城市B,这个SQL将为您提供所需的信息。我使用了ROW_NUMBER()函数,因此我只统计客户的第一次出现。
SELECT COUNT(Phone) PersonWithPhoneCount, COUNT(Email) PersonWithEmailCount, ProvinceId, CityId
FROM (
SELECT *
,ROW_NUMBER() OVER(PARTITION BY CustomerId
ORDER BY ProvinceId, CityId) Row
FROM @Customer c1
) Tmp
Where Row = 1
GROUP BY GROUPING SETS ((ProvinceId), (ProvinceId, CityId))