sql-查询每日有效会员人数

表字段,
uid bigint(20) NOT NULL DEFAULT '0' COMMENT '用户uid',
start_time bigint(20) NOT NULL DEFAULT '0' COMMENT '会员有效开始时间戳',
end_time bigint(20) NOT NULL DEFAULT '0' COMMENT '会员有效结束时间戳',

按天查询过去每日的有效会员人数
求指导~

start_time 大于等于今天0点,end_time晚于等于今天,今天就是会员用户。
求写法

mysql

SELECT
    DATE_FORMAT(FROM_UNIXTIME(start_time),"%Y:%m:%d"),count(DISTINCT uid)
FROM
    table
WHERE
UNIX_TIMESTAMP(DATE(NOW()))
 BETWEEN start_time and end_time
GROUP BY day(start_time)

img

SQLServer
SELECT count (distinct uid) from tb where getdate() BETWEEN start_time and end_time
MYSQL
SELECT count (distinct uid) from tb where NOW() BETWEEN start_time and end_time ;

tb为表名

1、统计时间点不同,数据有可能有差异,就看start_time和end_time是精确到日期还是时间

-- 以今天 0 点为时间点统计今天的有效会员数:
    SELECT curdate( ), count( 1 ) FROM t_user WHERE unix_timestamp( curdate( ) ) BETWEEN start_time AND end_time;

2、将指定时间转换为整数时间戳的函数(上述SQL中为:unix_timestamp( curdate( ) ) )需要跟业务保存时的方法一致

你好,你这个是hive sql;需要查询每日有效的会员人数,你提供的信息应该不够,
business.ods_dim_hive_zhwnl_member_ship这个表是ods层,我猜测这应该是一个拉链表,写SQL是需要分区字段
、最好建一个临时表,我猜你统计的结果是准备放在dwd层。

报错:AnalysisException: Could not resolve column/field reference: 'ds'
报错原因为:表中不存在ds字段
要解决的问题是时间戳转日期

select 
from_unixtime(cast(start_time/1000 as bigint),'yyyy-MM-dd') as ds,count(distinct uid)
from business.ods_dim_hive_zhwnl_member_ship
group by from_unixtime(cast(start_time/1000 as bigint),'yyyy-MM-dd') ;
-- 求某天会员数量
select count(1)
from business.ods_dim_hive_zhwnl_member_ship
where from_unixtime(cast(start_time/1000 as bigint),'yyyy-MM-dd HH:mm:ss') between  '2017-05-27 00:00:00'  and  '2017-05-27 23:59:59' 

ORACLE
select * FROM
(SELECT 1 ID , TO_DATE('2022-05-23 10:31:11','YYYY-MM-DD HH24:MI:SS') START_DATE,TO_DATE('2022-05-23 19:36:11','YYYY-MM-DD HH24:MI:SS') END_DATE FROM DUAL UNION ALL
SELECT 2 ID , TO_DATE('2022-05-23 11:11:55','YYYY-MM-DD HH24:MI:SS') START_DATE,TO_DATE('2022-05-23 21:11:11','YYYY-MM-DD HH24:MI:SS') END_DATE FROM DUAL UNION ALL
SELECT 3 ID , TO_DATE('2022-05-22 09:01:15','YYYY-MM-DD HH24:MI:SS') START_DATE,TO_DATE('2022-05-22 12:33:11','YYYY-MM-DD HH24:MI:SS') END_DATE FROM DUAL UNION ALL
SELECT 4 ID , TO_DATE('2022-05-21 17:07:15','YYYY-MM-DD HH24:MI:SS') START_DATE,TO_DATE('2022-05-21 23:55:11','YYYY-MM-DD HH24:MI:SS') END_DATE FROM DUAL )
WHERE SYSDATE >=START_dATE AND SYSDATE <= END_DATE

我猜你这个数据是每个会员只有一行记录,后面的开始时间结束时间间隔时间很长,甚至可能达到几年,你想得到的结果是每天都有一行记录,然后对于每一个会员都要和每天来进行匹配,也就是说要将这个开始日期结束日期展开到每一天,然后再进行count。
不确定你是用的什么数据库,一般也就两种方式,
第一种,先明确你是想查哪天到哪天的数据,然后找个日历表,每天都有一行的那种,把这个日历表和你的表关联起来,关联条件为 "日期表.日期 between 会员表.开始日期 and 会员表.结束日期",然后"group by 日期表.日期",前面 "select 日期表.日期,count(1)"即可
第二种,不使用实体的日历表,而是使用with递归出一个日历表,后面的步骤和第一种一样了。
至于unix_timestamp转换,不同数据库方式不一样,而且也不麻烦,就不多说了

最起码要先说你自己用的是什么数据库吧,不同数据库,有些函数用法是不一样的,比如时间戳转标准时间的函数,又比如当前时间函数等等,在不同数据库所用方法不同的
mysql是这么用的:
unix_timestamp(DATE_FORMAT(now(),'%Y-%m-%d')+"00:00:00") //表示当天时间的0点
unix_timestamp(DATE_FORMAT(now(),'%Y-%m-%d')+"23:59:59") //表示当天时间的23点59分59秒
那么可以用语句写成:

SELECT uid from 表名 where start_time>=unix_timestamp(DATE_FORMAT(now(),'%Y-%m-%d')+" 00:00:00")*1000 and end_time<=unix_timestamp(DATE_FORMAT(now(),'%Y-%m-%d')+" 23:59:59")*1000 这个语句表示 取出大于当天时间的0点,小于等于当天时间的235959秒 的会员ID
因为你存的是毫秒的,所以要乘以1000

下面是一种方法,还有一种xml法,自己去研究

--Sql server
/*查询开卡时间为2022-05-01至2022-06-31以来每日有效会员
先生成维度表*/
declare @begin_date NVARCHAR(50) = '2022-05-01',@end_date NVARCHAR(50) = '2022-06-31';
declare @v_dDate DATE = CONVERT(DATE,@begin_date),@v_date DATETIME,@v_adddays INT =1;@v_count INT
create table #temp1(日期 datetime,每日活跃会员数 int)
WHILE (@v_dDate<=CONVERT(DATE,@end_date))
Begin
SET @v_date = CONVERT(DATE,@v_dDate,111); --设置日期类型 
select @v_count =count(uid) from 表名 where begin_time <=DATEDIFF(S,'1970-01-01 08:00:00',@v_date) and end_time >=DATEDIFF(S,'1970-01-01 08:00:00',@v_date);
insert into #temp1(日期,每日活跃会员数) values (@v_date,@v_count);
SET @v_dDate=DATEADD(DAY,@v_adddays,@v_dDate);
    CONTINUE
    IF @v_dDate=DATEADD(DAY,-1,convert(DATE,@end_date))
    BREAK
End
select * from #temp1


SELECT
FROM_UNIXTIME(start_time,'%Y%m%d'),count(DISTINCT uid)
FROM
table
WHERE
UNIX_TIMESTAMP(DATE(NOW()))
BETWEEN start_time and end_time
GROUP BY FROM_UNIXTIME(start_time,'%Y%m%d')