JSON to Insights:快速而简单

有很多JSON数据集,然后是JSON数据集。每个公司,包括您的公司,都在JSON中存储了大量数据 - 调查,活动和论坛的结果。

有许多方法可以让皮肤成为JSON。您可以为每个报告编写Python程序,您可以进行可视化。或者,您可以使用(SQL for JSON)生成正确的算法  来分析JSON数据。在本文中,我们将向您展示如何使用N1QL快速提取洞察力。我们还使用了下一版本中的两个功能:公用表表达式(CTE)和窗口函数。

目标:将公共JSON数据集用于美国公开赛高尔夫比分,以创建简单的排行榜,排名等。

你要做的三件事:

  1. 轻松将数据提取到Couchbase中。

  2. 立即开始获取此JSON数据的值。

  3. 塑造JSON以快速使用新功能生成有用的报告。

来源数据:https//github.com/jackschultz/usopen

此帖子中的查询也可在以下网址获得:https//github.com/keshavmr/usopen-golf-queries

数据仓库结构:此GitHub 仓库https://github.com/jackschultz/usopen包含US Open golf -2018数据。对于每个洞,它作为每天的单独文件。

每个文档都有这种结构。这是第1天第1洞的文件。提交的Ps有玩家列表,每个玩家都有一个唯一的ID。

每个玩家的游戏统计数据都是按行程划分的。使用玩家的场唯一ID将玩家与得分相匹配。

开始获取见解:

在开始查询之前,请在存储桶上创建主索引。

在usopen上创建主要指数;

任务1:按轮次和最终总数创建球员得分报告。

在自下而上使用JSON后,我们想出了这个查询。解释是在查询之后。

表格结果(以表格形式,来自Couchbase查询工作台)

与AS(
  选择
    pl .hnum  AS holedn,
    pl .ps .Nat  AS country,
    (pl .ps .FN || “” || pl .ps .LN)AS名称,
    pl .ps .ID  AS ID,
    array_length(hps .Sks)AS得分,
    HPL .hole  AS `hole`,
    HPL 。天 AS `day`
  从
    (
      选择
        meta(usopen).id  AS hnum,
        PS
      从
        usopen USE键“孔:1:1”不需要Ps AS ps
    )pl
    INNER JOIN(
      选择
        TONUMBER(分裂(间(usopen).ID,“:”)[ 1 ])AS `hole`,
        TONUMBER(分裂(间(usopen).ID,“:”)[ 2 ])AS `day`,
        HPS
      从
        usopen不需要Rs AS rs UNNEST rs .Hs  AS hs UNNEST hs.HPs  AS hps
    )hpl ON(pl .ps .ID = hps .ID)
选择
  d .name,
  和(
    例如d .day = 1那么d。得分 ELSE 0 END
  )R1,
  和(
    例如d .day = 2那么d。得分 ELSE 0 END
  )R2,
  和(
    例如d .day = 3那么d。分数 ELSE 0 END
  )R3,
  和(
    例如,d .day = 4那么d。分数 ELSE 0 END
  )R4,
  SUM(d .score)T
  d
GROUP  BY
  d .name
ORDER  BY
  d .name


让我们逐块查看查询。

看看WITH d子句。该声明将JSON从PER-day-PER-hole-by-shot-data数据解码为简单的标量值。

  • Holedn是文档密钥 - 空洞日数

  • 国家是球员的国籍

  • ID是玩家的唯一ID。

洞和日是显而易见的,得分是该洞的球员得分。

在SELECT语句的FROM子句中,pl是从第一天的第一个洞(孔:1:1)中取出的文档的完整列表。

Rs是球员的结果,一杆一杆地射门。首先,我们不需要那个数组来计算每个洞的细节和那个洞的得分,由array_length(hps.Sks)决定。

一旦我们获得了逐洞分数,就可以很容易地将最终查询写入由玩家和白天进行聚合。

** WITH子句是即将发布的Mad-Hatter版本中的公用表表达式(CTE)功能。在Couchbase 5.5或更低版本中执行此操作的旧方法是使用LET子句。如果您需要帮助,请在Couchbase论坛中发布问题)。

任务2:现在,创建完整的排行榜并添加信息。被削减的高尔夫球手不会参加第三轮或第四轮比赛。我们使用这些信息来确定被裁掉的球员。

查询2.获取上一个查询并将其命名为公用表dx,然后添加以下表达式以确定该剪切。

这是完整的查询:

与dy AS(
  选择
    pl .hnum  AS holedn,
    pl .ps .Nat  AS country,(pl .ps .FN || “” || pl .ps .LN)AS名称,
    pl .ps .ID  AS ID,
    array_length(hps .Sks)AS得分,
    HPL .hole  AS `hole`,
    HPL 。天 AS `day`
  从
    (
      选择
        meta(usopen).id  AS hnum,
        PS
      从
        usopen USE键“孔:1:1”不需要Ps AS ps
    )pl
    INNER JOIN(
      选择
        TONUMBER(分裂(间(usopen).ID,“:”)[ 1 ])AS `hole`,
        TONUMBER(分裂(间(usopen).ID,“:”)[ 2 ])AS `day`,
        HPS
      从
        usopen不需要Rs AS rs 不需要.Hs  AS hs 不需要hs.HPs  AS hps
    )hpl ON(pl .ps .ID = hps .ID)
dx AS(
  选择
    d .name,
    和(
      例如d .day = 1那么d。得分 ELSE 0 END
    )R1,
    和(
      例如d .day = 2那么d。得分 ELSE 0 END
    )R2,
    和(
      例如d .day = 3那么d。分数 ELSE 0 END
    )R3,
    和(
      例如,d .day = 4那么d。分数 ELSE 0 END
    )R4,
    sum(d .score)T
  从
    dy AS d
  GROUP  BY
    d .name
  ORDER  BY
    d .name
选择
  d2 .name,
  d2 .R 1,
  d2 .R 2,
  d2 .R 3,
  d2 .R 4,
  d2 .T,(
    情况何时(
      d2 .R 1 = 0
      或者 d2 .R 2 = 0
      或者 d2 .R 3 = 0
      或者 d2 .R 4 = 0
    )那么“削减”就会失败
  )AS CUT
  dx AS d2
ORDER  BY
  削减ASC,
  d2 .T  ASC

任务3:确定获胜者。

我们需要根据总得分对玩家进行排名,以确定谁赢得了比赛。如果分数中存在关联,则跳过排名。没有窗口函数的 SQL中执行此操作非常昂贵在这里,我们使用RANK()窗口函数编写查询。窗口函数是即将发布的版本(Mad-Hatter)中N1QL的一项功能

注意因为平局得分而排名4,8,9,10,1缺失!

任务4:现在,让我们看看每个球员在第一轮,第二轮,第三轮比赛后的表现与最后一轮比较。使用窗口功能,使巧克力覆盖的棉花糖消失变得容易。

查询4:使用相同的RANK()函数,按ORDER BY每天的分数(第1天,第1天+第2天,第1天+第2天+第3天)而不是最终得分。

与dy AS(
  选择
    pl .hnum  AS holedn,
    pl .ps .Nat  AS country,(pl .ps .FN || “” || pl .ps .LN)AS名称,
    pl .ps .ID  AS ID,
    array_length(hps .Sks)AS得分,
    HPL .hole  AS `hole`,
    HPL 。天 AS `day`
  从
    (
      选择
        meta(usopen).id  AS hnum,
        PS
      从
        usopen USE键“孔:1:1”不需要Ps AS ps
    )pl
    INNER JOIN(
      选择
        TONUMBER(分裂(间(usopen).ID,“:”)[ 1 ])AS `hole`,
        TONUMBER(分裂(间(usopen).ID,“:”)[ 2 ])AS `day`,
        HPS
      从
        usopen不需要Rs AS rs 不需要.Hs  AS hs 不需要hs.HPs  AS hps
    )hpl ON(pl .ps .ID = hps .ID)
dx AS(
  选择
    d .name,
    和(
      例如d .day = 1那么d。得分 ELSE 0 END
    )R1,
    和(
      例如d .day = 2那么d。得分 ELSE 0 END
    )R2,
    和(
      例如d .day = 3那么d。分数 ELSE 0 END
    )R3,
    和(
      例如,d .day = 4那么d。分数 ELSE 0 END
    )R4,
    sum(d .score)T
  从
    dy AS d
  GROUP  BY
    d .name
  ORDER  BY
    d .name
选择
  d2 .name,
  d2 .R 1,
  d2 .R 2,
  d2 .R 3,
  d2 .R 4,
  d2 .T,
  DENSE_RANK()超过(
    ORDER  BY
      d2 .T + CUT
  )AS rankMoney,
  RANK()超过(
    ORDER  BY
      d2 .T + CUT
  )AS rankFinal,
  RANK()超过(
    ORDER  BY
      d2 .R 1
  )AS round1rank,
  RANK()超过(
    ORDER  BY
      d2 .R 1 + d2 .R 2
  )AS round2rank,
  RANK()超过(
    ORDER  BY
      d2 .R 1 + d2 .R 2 + d2 .R 3 + CUT
  )AS round3rank
  dx AS d2 LET CUT =(
    情况何时(
      d2 .R 1 = 0
      或者 d2 .R 2 = 0
      或者 d2 .R 3 = 0
      或者 d2 .R 4 = 0
    )然后1000 ELSE 0 END
  )
ORDER  BY
  rankFinal,
  round1rank,
  round2rank,
  round3rank


现在你可以看到球员每天如何上下移动。

任务5:使用基本的逐个镜头统计数据为领导者创建完整记分卡。

查询5: Brooks Koepka是美国公开赛的最终赢家。让我们逐洞获得他的分数,然后逐轮获得他的累积分数。注意简单的SUM()和COUNT()聚合如何作为具有OVER()子句的窗口函数。

这首先按天划分分数,然后按洞的顺序划分 - 由PARTITION BY子句指定,按洞的顺序,1-18。然后,SUM将得分加起来。

这个SUM()函数只是将第1天,第1洞到第4天,第18洞的得分加起来 - 这是由OVER()子句中的ORDER BY d3.day,d3.hole指定的。ToTScore领域显示Koepka在每个洞的锦标赛总短缺。

与dy AS(
  选择
    pl .hnum  AS holedn,
    pl .ps .Nat  AS country,(pl .ps .FN || “” || pl .ps .LN)AS名称,
    pl .ps .ID  AS ID,
    array_length(hps .Sks)AS得分,
    HPL .hole  AS `hole`,
    HPL 。天 AS `day`,
    hpl .Par  AS Par
  从
    (
      选择
        meta(usopen).id  AS hnum,
        PS
      从
        usopen USE键“孔:1:1”不需要Ps AS ps
      哪里
        ps .LN = “Koepka”
    )pl
    INNER JOIN(
      选择
        TONUMBER(分裂(间(usopen).ID,“:”)[ 1 ])AS `hole`,
        TONUMBER(分裂(间(usopen).ID,“:”)[ 2 ])AS `day`,
        hs .Par,
        HPS
      从
        usopen不需要Rs AS rs 不需要.Hs  AS hs 不需要hs.HPs  AS hps
    )hpl ON(pl .ps .ID = hps .ID)
dx AS(
  选择
    d .name,
    d .day,
    d。分数,
    d .hole,
    d .Par
  从
    dy AS d
  ORDER  BY
    d .name
dz AS(
  选择
    d2 .day,
    d2 .hole,
    d2 .score,
    SUM(d2 .score)OVER(
      PARTITION BY D2 ·天
      ORDER  BY
        d2 .hole
    )hst,
    d2 .Par,
    SUM(d2 .Par)OVER(
      PARTITION BY D2 ·天
      ORDER  BY
        d2 .hole
    )hpr
  从
    dx AS d2 LET CUT =(
      情况何时(
        d2 .R 1 = 0
        或者 d2 .R 2 = 0
        或者 d2 .R 3 = 0
        或者 d2 .R 4 = 0
      )然后1000 ELSE 0 END
    )
  ORDER  BY
    d2 .day,
    d2 .hole
选择
  d3 .Par,
  d3 .day,
  d3 .hole,
  d3 .hst,
  d3 .score,(d3 .hst -  d3 .hpr)ToPar,
  总和(d3 .score)OVER(
    ORDER  BY
      d3 .day,
      d3 .hole
  )ToTScore,
  数(1)OVER(
    ORDER  BY
      d3 .day,
      d3 .hole
  )HoleNum
  dz AS d3


猜你喜欢

转载自blog.51cto.com/14009535/2328485