SparkSQL统计新增用户

原始数据,放置在IDEA的data文件夹下的log1.txt

192.168.33.6,hunter,2017-09-15 10:30:20,/a
192.168.33.7,hunter,2017-09-15 10:30:26,/b
192.168.33.6,jack,2017-09-15 10:30:27,/a
192.168.33.8,tom,2017-09-15 10:30:28,/b
192.168.33.9,rose,2017-09-15 10:30:30,/b
192.168.33.10,julia,2017-09-15 10:30:40,/c
192.168.33.16,hunter,2017-09-16 10:30:20,/a
192.168.33.18,jerry,2017-09-16 10:30:30,/b
192.168.33.26,jack,2017-09-16 10:30:40,/a
192.168.33.18,polo,2017-09-16 10:30:50,/b
192.168.33.39,nissan,2017-09-16 10:30:53,/b
192.168.33.39,nissan,2017-09-16 10:30:55,/a
192.168.33.39,nissan,2017-09-16 10:30:58,/c
192.168.33.20,ford,2017-09-16 10:30:54,/c
192.168.33.46,hunter,2017-09-17 10:30:21,/a
192.168.43.18,jerry,2017-09-17 10:30:22,/b
192.168.43.26,tom,2017-09-17 10:30:23,/a
192.168.53.18,bmw,2017-09-17 10:30:24,/b
192.168.63.39,benz,2017-09-17 10:30:25,/b
192.168.33.25,haval,2017-09-17 10:30:30,/c
192.168.33.10,julia,2017-09-17 10:30:40,/c

通过SparkSQL读取文件,注册成一张零食表 log1
TODO 统计每日日活用户(只要当天有一条访问记录的用户[取最早的一条访问记录]),对用户去重

select
ip,uid,access_time,url,day
from
(
    select
    ip,uid,access_time,url,day,
    row_number() over(partition by uid,day order by access_time) rn
    from
    (select
    ip,uid,access_time,url,
    date_format(access_time,'yyyy-MM-dd') day
    from log1
    ) t
    order by day
) t1
where rn=1

结果
2017-09-15活跃用户:hunter,tom,julia,jack,rose
2017-09-16活跃用户:hunter,nissan,jack,ford,polo,jerry
2017-09-17活跃用户:jerry,julia,haval,tom,hunter,benz,bmw
可以通过这个继续求留存用户、留存率

留存用户:2017-09-15登录了应用,2017-09-16继续登录了应用的用户

留存率:留存用户占新增用户(活跃用户)的比例

+------+----------+
|   uid|       day|
+------+----------+
|hunter|2017-09-15|
|  jack|2017-09-15|
| julia|2017-09-15|
|   tom|2017-09-15|
|  rose|2017-09-15|
|nissan|2017-09-16|
|  jack|2017-09-16|
|hunter|2017-09-16|
|  ford|2017-09-16|
|  polo|2017-09-16|
| jerry|2017-09-16|
| jerry|2017-09-17|
| julia|2017-09-17|
| haval|2017-09-17|
|   tom|2017-09-17|
|hunter|2017-09-17|
|  benz|2017-09-17|
|   bmw|2017-09-17|
+------+----------+

求20170917的当日新增,昨日新增、历史累计用户

select
count(distinct t.uid) cnt
from
(select
    ip,uid,access_time,url,
    date_format(access_time,'yyyy-MM-dd') day
    from log1 where date_format(access_time,'yyyy-MM-dd') = '2017-09-17'
) t
left join --取历史用户
(
    select
    ip,uid,access_time,url,
    date_format(access_time,'yyyy-MM-dd') day
    from log1 where date_format(access_time,'yyyy-MM-dd') <= '2017-09-16'
) t1
on t.uid=t1.uid
where t1.uid is null
-- group by t.uid,t.day
union all --昨日新增(20170916)
select
count(distinct t.uid) cnt
from
(select
    ip,uid,access_time,url,
    date_format(access_time,'yyyy-MM-dd') day
    from log1 where date_format(access_time,'yyyy-MM-dd') = '2017-09-16'
) t
left join
(--取历史用户
    select
    ip,uid,access_time,url,
    date_format(access_time,'yyyy-MM-dd') day
    from log1 where date_format(access_time,'yyyy-MM-dd') <= '2017-09-15'
) t1
on t.uid=t1.uid
where t1.uid is null
-- group by t.uid,t.day
union all --历史累计用户
select
    count(distinct uid) cnt
from log1

结果
当日(0917)新增:3
昨日(0916)新增:4
历史累计:12

+---+
|cnt|
+---+
|  3|
|  4|
| 12|
+---+

优化

count distinct一般都很慢,可以使用count group by代替 即

select
count(1)
from
(
    select
    uid
    from log1
    group by 1
)

IDEA代码

package com.ruozedata.bigdata.sqlzc

import com.ruozedata.bigdata.sql01.Domain.order
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.SparkSession

object LogApp {

  case class logsrc(ip: String, uid: String, access_time: String, url: String)

  def main(args: Array[String]): Unit = {

    val spark: SparkSession = SparkSession.builder() //
      .master("local[2]") //
      .appName("SparkSessionApp") //
      .getOrCreate()

    spark.sparkContext.setLogLevel("ERROR")
    val log1RDD: RDD[String] = spark.sparkContext.textFile("data/log1.txt")

    import spark.implicits._
      log1RDD.map(x => {
      val splits: Array[String] = x.split(",")
      val IP = splits(0)
      val UID = splits(1)
      val ACCESSTIME = splits(2)
      val URL = splits(3)
      logsrc(IP, UID, ACCESSTIME, URL)
    }).toDF.createTempView("log1")

    //TODO 统计每日日活用户(只要当天有一条访问记录的用户[取最早的一条访问记录]),对用户去重
    spark.sql(
      """
       select
        |uid,day
        |from
        |(
        |   select
        |   ip,uid,access_time,url,day,
        |   row_number() over(partition by uid,day order by access_time) rn
        |   from
        |   (select
        |   ip,uid,access_time,url,
        |   date_format(access_time,'yyyy-MM-dd') day
        |   from log1
        |   ) t
        |   order by day
        |) t1
        |where rn=1
        |""".stripMargin).show()

    //TODO  新增
    spark.sql(
      """
        |select
        |count(distinct t.uid) cnt
        |from
        |(select
        |   ip,uid,access_time,url,
        |   date_format(access_time,'yyyy-MM-dd') day
        |   from log1 where date_format(access_time,'yyyy-MM-dd') = '2017-09-17'
        |) t
        |left join --取历史用户
        |(
        |   select
        |   ip,uid,access_time,url,
        |   date_format(access_time,'yyyy-MM-dd') day
        |   from log1 where date_format(access_time,'yyyy-MM-dd') <= '2017-09-16'
        |) t1
        |on t.uid=t1.uid
        |where t1.uid is null
        |-- group by t.uid,t.day
        |union all --昨日新增(20170916)
        |select
        |count(distinct t.uid) cnt
        |from
        |(select
        |   ip,uid,access_time,url,
        |   date_format(access_time,'yyyy-MM-dd') day
        |   from log1 where date_format(access_time,'yyyy-MM-dd') = '2017-09-16'
        |) t
        |left join
        |(--取历史用户
        |   select
        |   ip,uid,access_time,url,
        |   date_format(access_time,'yyyy-MM-dd') day
        |   from log1 where date_format(access_time,'yyyy-MM-dd') <= '2017-09-15'
        |) t1
        |on t.uid=t1.uid
        |where t1.uid is null
        |-- group by t.uid,t.day
        |union all --历史累计用户
        |select
        |   count(distinct uid) cnt
        |from log1
        |""".stripMargin).show()

    spark.stop()
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,306评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,657评论 2 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,928评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,688评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,105评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,024评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,159评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,937评论 0 212
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,689评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,851评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,325评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,651评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,364评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,192评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,985评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,154评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,955评论 2 279

推荐阅读更多精彩内容