You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为现有多表关联SQL查询添加同公司活跃用户统计功能

问题背景

现有四张数据表,建表及插入数据的SQL如下:

create table GROSS(DATE_ACT DATE, SUB_ID BIGINT, PP_ID BIGINT, CUSTOMER_TYPE VARCHAR(50), REACTIVATION int);

insert into GROSS values('2019-11-03', 234, 5, 'Business', 1);
insert into GROSS values('2018-09-02', 131, 8, 'Business', 0);
insert into GROSS values('2018-11-03', 98, 3, 'Private', 1);
insert into GROSS values('2021-12-15', 228, 5, 'Business', 0);

create table TARIFF(PP_ID INT, PP_NAME VARCHAR(100), SUB_ID INT, PP_START_DATE DATE, PP_END_DATE DATE);
insert into TARIFF values(3, 'PLAN_1', 98, '2021-05-03', '2021-06-03');
insert into TARIFF values(5, 'Business plan 3.0', 234, '2021-05-06', '2021-06-06');
insert into TARIFF values(8, 'Business plan 4.0', 131, '2021-05-10', '2021-06-10');
insert into TARIFF values(5, 'Бизнес-план 3.0', 228, '2021-12-15', '2999-01-01');

create table SERVICE(SERVICE_START_DATE DATE, SERVICE_STOP_DATE DATE, SUB_ID INT, SERVICE_NAME VARCHAR(100));
insert into SERVICE values('2021-05-07', '2021-06-07', 98, 'Unlimited Internet 2');
insert into SERVICE values('2021-05-07', '2021-06-07', 98, 'Internet');
insert into SERVICE values('2021-05-07', '2021-06-07', 98, 'Unlimited Internet 512');
insert into SERVICE values('2021-12-15', '2999-01-01', 228, 'Безлимитный Интернет 512');

create table SUBSCRIBER(MONTH DATE, COMPANY_NAME VARCHAR(100), SUB_ID INT, CUSTOMER_TYPE VARCHAR(100), STATUS INT, PP_TYPE_ID VARCHAR(50));
insert into SUBSCRIBER values('2022-01-06', 'A1', 98, 'Private', 1, 'Fixed');
insert into SUBSCRIBER values('2022-01-06', 'MTS', 234, 'Business', 1, 'Fixed');
insert into SUBSCRIBER values('2022-01-06', 'Life', 131, 'Business', 1, 'Fixed');
insert into SUBSCRIBER values('2022-01-01','MTS', 228, 'Business', 1, 'Voice');

已编写多表关联查询语句如下:

select GROSS.DATE_ACT, GROSS.SUB_ID, TARIFF.PP_NAME, SERVICE.SERVICE_NAME, SUBSCRIBER.COMPANY_NAME
from GROSS 
inner join TARIFF on GROSS.SUB_ID = TARIFF.SUB_ID 
inner join SERVICE on TARIFF.SUB_ID = SERVICE.SUB_ID 
inner join SUBSCRIBER on SERVICE.SUB_ID = SUBSCRIBER.SUB_ID
where MONTH(GROSS.DATE_ACT) = 12
and GROSS.CUSTOMER_TYPE = 'Business'
and TARIFF.PP_NAME regexp 'Бизнес-план.+'
and GROSS.DATE_ACT = SERVICE.SERVICE_START_DATE
and SERVICE.SERVICE_NAME = 'Безлимитный интернет 512' or 'Безлимитный интернет 1' or 'Безлимитный интернет 2'
and YEAR(SERVICE.SERVICE_STOP_DATE) = 2999;

需求:在返回现有查询结果的基础上,额外统计当前用户所属公司中,SUBSCRIBER.STATUS=1的活跃用户总数。

解决方案

1. 修正原查询的逻辑错误

原查询的WHERE子句中,SERVICE.SERVICE_NAME的条件写法错误,直接用OR会导致逻辑优先级混乱,应该改用IN匹配多个目标值,同时注意字符串大小写匹配(原数据中服务名称是Безлимитный Интернет 512,首字母大写)。

2. 添加公司活跃用户统计

可以通过关联子查询在SELECT语句中直接获取当前用户所属公司的活跃用户总数,这种方式逻辑清晰,兼容大多数数据库。

最终修改后的SQL如下:

select 
    GROSS.DATE_ACT, 
    GROSS.SUB_ID, 
    TARIFF.PP_NAME, 
    SERVICE.SERVICE_NAME, 
    SUBSCRIBER.COMPANY_NAME,
    -- 统计当前公司STATUS=1的活跃用户总数
    (SELECT COUNT(*) 
     FROM SUBSCRIBER s2 
     WHERE s2.COMPANY_NAME = SUBSCRIBER.COMPANY_NAME 
       AND s2.STATUS = 1) AS COMPANY_ACTIVE_USERS
from GROSS 
inner join TARIFF on GROSS.SUB_ID = TARIFF.SUB_ID 
inner join SERVICE on TARIFF.SUB_ID = SERVICE.SUB_ID 
inner join SUBSCRIBER on SERVICE.SUB_ID = SUBSCRIBER.SUB_ID
where MONTH(GROSS.DATE_ACT) = 12
  and GROSS.CUSTOMER_TYPE = 'Business'
  and TARIFF.PP_NAME regexp 'Бизнес-план.+'
  and GROSS.DATE_ACT = SERVICE.SERVICE_START_DATE
  -- 修正服务名称的匹配逻辑
  and SERVICE.SERVICE_NAME IN ('Безлимитный Интернет 512', 'Безлимитный интернет 1', 'Безлимитный интернет 2')
  and YEAR(SERVICE.SERVICE_STOP_DATE) = 2999;

3. 可选优化:使用窗口函数

如果数据库支持窗口函数(如MySQL 8.0+、PostgreSQL等),可以用窗口函数替代子查询,大数据量下性能更优:

select 
    GROSS.DATE_ACT, 
    GROSS.SUB_ID, 
    TARIFF.PP_NAME, 
    SERVICE.SERVICE_NAME, 
    SUBSCRIBER.COMPANY_NAME,
    -- 窗口函数按公司分组统计活跃用户
    COUNT(*) OVER (PARTITION BY SUBSCRIBER.COMPANY_NAME) AS COMPANY_ACTIVE_USERS
from GROSS 
inner join TARIFF on GROSS.SUB_ID = TARIFF.SUB_ID 
inner join SERVICE on TARIFF.SUB_ID = SERVICE.SUB_ID 
inner join SUBSCRIBER on SERVICE.SUB_ID = SUBSCRIBER.SUB_ID
-- 先筛选出所有活跃用户,再关联其他表
inner join (
    SELECT COMPANY_NAME, SUB_ID 
    FROM SUBSCRIBER 
    WHERE STATUS = 1
) s_active on SUBSCRIBER.SUB_ID = s_active.SUB_ID
where MONTH(GROSS.DATE_ACT) = 12
  and GROSS.CUSTOMER_TYPE = 'Business'
  and TARIFF.PP_NAME regexp 'Бизнес-план.+'
  and GROSS.DATE_ACT = SERVICE.SERVICE_START_DATE
  and SERVICE.SERVICE_NAME IN ('Безлимитный Интернет 512', 'Безлимитный интернет 1', 'Безлимитный интернет 2')
  and YEAR(SERVICE.SERVICE_STOP_DATE) = 2999;

关键说明

  • 子查询方式兼容性更好,适用于所有支持SQL的数据库;窗口函数方式在大数据量下性能更优。
  • 原查询中日期值缺少单引号,已在示例SQL中补充,避免语法错误。

内容的提问来源于stack exchange,提问作者Matvey Androsyuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 01:20:42