如何在流分析组中将多条记录与字符串和空值合并

Posted

技术标签:

【中文标题】如何在流分析组中将多条记录与字符串和空值合并【英文标题】:How to merge multiple records with strings and nulls in a Stream Analytics Group By 【发布时间】:2017-05-24 17:49:13 【问题描述】:

我正在尝试将一些记录的事件从 Application Insights 提取到我们的 SQL 数据库中。我无法控制输入的格式,这些输入是由文件中的多个 json 数组组成的 json 文件。在每条记录中,5 条信息位于文件中 [context].[custom].[dimensions] 的 json 数组中,并且使用 OUTER APPLY 会展平这些值。问题是它返回的结果不是每条记录一行,而是好像你已经用 5 加入了一行(这确实是它所做的),并且 5 条数据的值在 4 种情况下为 NULL,而实际值在另一个。我只需要 5 个值中的 2 个 - PageType 和 UserId - 并且在我的 GROUP BY 中给出了这个,它返回 3 条记录,每个值一个,一个两个都为空。

在普通 SQL 中,您只需使用 MAX 表达式来获取每个表达式的实际值,但在流分析中,您不能在字符串上使用 MAX。您也不能使用 COALESCE 和我尝试使用的许多其他方法来解决此问题。任何想法如何改变结果:

EventDateTime  Event      PageType UserId  AppVersion CountA
2017-05-24     Nav Show   NULL     NULL    2.0.1293     1
2017-05-24     Nav Show   NULL     SIRTSW  2.0.1293     1
2017-05-24     Nav Show   Trade    NULL    2.0.1293     1

2017-05-24     Nav Show   Trade    SIRTSW  2.0.1293     1  ?

每行返回三行的代码如下(注意e.event是一个数组,所以不会引起同样的问题):

SELECT flatEvent.ArrayValue.name as Event, 
e.context.data.eventTime as EventDateTime,
e.context.application.version as AppVersion 
,flatCustom.ArrayValue.UserId as UserId
,flatCustom.ArrayValue.PageType as PageType, 
SUM(flatEvent.ArrayValue.count) as CountA
INTO
      [insights] 
    FROM [ios] e
    CROSS APPLY GetArrayElements(e.[event]) as flatEvent
    OUTER APPLY GetArrayElements(e.[context].[custom].[dimensions]) as flatCustom
    GROUP BY SlidingWindow(minute, 1),
    flatEvent.ArrayValue.name,
    e.context.data.eventTime,
    e.context.application.version,
    flatCustom.ArrayValue.UserId,
    flatCustom.ArrayValue.PageType

提前致谢, 抢

【问题讨论】:

你可以在流分析中使用子查询吗? 【参考方案1】:

根据您的方案,我假设您可以使用 javascript user-defined functions 进行 Azure 流分析,将多个维度合并为一条记录。这是我对这个问题的测试,你可以参考他们。

JSON 文件


  "context":
     "data":"eventTime":"2017-05-24",
     "application":"version":"2.0.1293",
     "custom":
        "dimensions":[
           "PageType":null,"UserId":"SIRTSW",
           "PageType":"Trade","UserId":null,
           "PageType":null,"UserId":null
        ]
     
  ,
  "event":[
    "name":"Nav Show","count":1
  ]

javascript UDF、UDF.coalesce

function main(items) 
    var result=[];
    var UserIdStr="",PageTypeStr="";
    for(var i=0;i<items.length;i++)
        if(items[i].UserId!=null && items[i].UserId!=undefined)
         UserIdStr+=items[i].UserId;
        if(items[i].PageType!=null && items[i].PageType!=undefined)
         PageTypeStr+=items[i].PageType;
    
    result.push(UserId:UserIdStr,PageType:PageTypeStr);
    return result;

查询

--first query
WITH f AS (
SELECT 
e.context.data.eventTime as EventDateTime,
e.context.application.version as AppVersion,
e.event as flatEvent,
UDF.coalesce(e.[context].[custom].[dimensions]) as flatDimensions
    FROM [ios] e
)

--second query
SELECT flatEvent.ArrayValue.name as Event,
f.EventDateTime,
f.AppVersion,
flatDimension.ArrayValue.UserId,
flatDimension.ArrayValue.PageType,
SUM(flatEvent.ArrayValue.count) as CountA
FROM f
CROSS APPLY GetArrayElements(f.[flatEvent]) as flatEvent
OUTER APPLY GetArrayElements(f.[flatDimensions]) as flatDimension
GROUP BY SlidingWindow(minute, 1),
    flatEvent.ArrayValue.name,
    f.EventDateTime,
    f.AppVersion,
    flatDimension.ArrayValue.UserId,
    flatDimension.ArrayValue.PageType

测试结果

【讨论】:

出色的答案,谢谢。这里的教训是看看其他工具可能能够解决问题,而不是 SQL。奇怪的是,在查询中调用 UDF.coalesce 时出现语法错误(是的,我确定没有拼写错误)。我创建了第二个相同的版本,称为 UDF.combine,它没有语法错误,所以有点神秘。

以上是关于如何在流分析组中将多条记录与字符串和空值合并的主要内容,如果未能解决你的问题,请参考以下文章

Oracle中将查询出的多条记录的某个字段拼接成一个字符串的方法

Paradox 如何管理 null 和空值?

在流分析查询中将已知属性从记录提升到***结果

ES11(2020)可选链操作符和空值合并运算符

ES11(2020)可选链操作符和空值合并运算符

Android Json 和空值