文章目录


第六章 SQL聚合函数 JSON_ARRAYAGG

创建​​JSON​​格式值数组的聚合函数。

注:IRIS可用,IRIS之前版本不可用。

大纲

JSON_ARRAYAGG([ALL | DISTINCT [BY(col-list)]] string-expr [%FOREACH(col-list)] [%AFTERHAVING])

参数


  • ​ALL​​ - 可选-指定​​JSON_ARRAYAGG​​返回一个​​JSON​​数组,其中包含​​string-expr​​的所有值。
    如果没有指定关键字,这是默认值。
  • ​DISTINCT​​ - 可选-一个​​DISTINCT​​子句,指定​​JSON_ARRAYAGG​​返回一个仅包含唯一字符串​​expr​​值的​​JSON​​数组。
    ​DISTINCT​​可以指定​​BY(colo -list)​​子句,其中​​colo -list​​可以是单个字段,也可以是用逗号分隔的字段列表。
  • ​string-expr​​ - 计算结果为字符串的SQL表达式。
    通常是所选表中列的名称。
  • ​%FOREACH(col-list)​​ - 可选-列名或以逗号分隔的列名列表。
  • ​%AFTERHAVING​​ - 可选-应用在​​HAVING​​子句中的条件。

描述

​JSON_ARRAYAGG​​聚合函数返回指定列中值的JSON格式数组。

一个简单的​​JSON_ARRAYAGG​​(或​​JSON_ARRAYAGG ALL​​)返回一个​​JSON​​数组,其中包含所选行中​​string-expr​​的所有值。

字符串​​-expr​​为空字符串​​(")​​的行由数组中的(​​" u0000"​​)表示。

字符串​​-expr​​为NULL的行不包含在数组中。

如果只有一个字符串​​-expr​​值,并且是空字符串(​​"​​),​​JSON_ARRAYAGG​​将返回​​JSON​​数组​​["\u0000"]​​。

如果所有的​​string-expr​​值为​​NULL​​, ​​JSON_ARRAYAGG​​返回一个空的​​JSON​​数组​​[]​​。

​JSON_ARRAYAGG DISTINCT​​返回一个​​JSON​​数组,由所选行中​​string-expr​​的所有不同(唯一)值组成:​​JSON_ARRAYAGG(DISTINCT col1)​​。

​NULL​​字符串​​-expr​​不包含在​​JSON​​数组中。

​JSON_ARRAYAGG(DISTINCT BY(col2) col1)​​返回一个​​JSON​​数组,该数组只包含记录中​​col2​​值是不同的(唯一的)的那些​​col1​​字段值。

但是请注意,不同的​​col2​​值可能包含一个单独的​​NULL​​值。

​JSON_ARRAYAGG​​ ​​string-expr​​不能是流字段。

指定流字段的结果是​​SQLCODE -37​​。

包含转义字符的数据值


  • 双引号:如果一个​​string-expr​​​值包含一个双引号字符(​​"​​​),​​JSON_ARRAYAGG​​​使用字面转义序列​​\"​​来表示这个字符。
  • 反斜杠:如果​​string-expr​​​值包含反斜杠字符(​​\​​​),则​​JSON_ARRAYAGG​​​使用文字转义序列​​\\​​表示该字符。
  • 单引号:当​​string-expr​​​值包含一个单引号作为文字字符时, SQL要求必须将此字符作为两个单引号字符(​​''​​​进行双倍转义。​​JSON_ARRAYAGG​​将此字符表示为单引号字符‘。

最大JSON数组大小

默认的JSON_ARRAYAGG返回类型是​VARCHAR(8192)​
这个长度包括​JSON​数组格式化字符以及字段数据字符。
如果预期返回的值将需要大于​8192​,可以使用​CAST​函数指定一个更大的返回值。
例如​CAST(JSON_ARRAYAGG(value)) AS VARCHAR(12000))​
如果实际返回的JSON数组长于​JSON_ARRAYAGG​返回类型长度,IRIS将在返回类型长度处截断JSON数组,而不会发出错误。
因为截断JSON数组会删除其关闭的​]​字符,这使得返回值无效。

JSON_ARRAYAGG 和 %SelectMode

可以使用​​%SelectMode​​属性为​​JSON​​数组中的元素指定数据显示值:​​0=Logical​​(默认值),​​1=ODBC​​, ​​2= display​​。

如果​​string-expr​​包含一个​​%List​​结构,则元素以ODBC模式表示,用逗号分隔,在逻辑和显示模式中以​​%List​​格式字符表示,用​​\​​转义序列表示。

JSON_ARRAYAGG和ORDER BY

​JSON_ARRAYAGG​​函数将表中多行列的值组合成一个包含元素值的​​JSON​​数组。

因为在计算所有聚合字段之后,查询结果集中应用了一个​​ORDER BY​​子句,所以​​ORDER BY​​不能直接影响这个列表中的值序列。

在某些情况下,​​JSON_ARRAYAGG​​结果可能是按顺序出现的,但是不应该依赖于这种顺序。

在给定聚合结果值中列出的值不能显式排序。

相关的聚合函数


  • ​LIST​​返回一个逗号分隔的值列表。
  • ​%DLIST​​返回一个包含每个值的元素的IRIS列表。
  • ​XMLAGG​​返回一个串接的值字符串。

示例

下面的嵌入式SQL示例返回一个主机变量,该变量包含示例的​​Home_State​​列中所有值的​​JSON​​数组。

以字母​​A​​开头的人名表:

SELECT JSON_ARRAYAGG(Home_State)
INTO :statearray
FROM Sample.Person
WHERE Home_State %STARTSWITH 'A'

SELECT JSON_ARRAYAGG(CTLOC_Desc) FROM CT_Loc

第六章 SQL聚合函数 JSON_ARRAYAGG_json数组

注意,这个​​JSON​​数组包含重复的值。

下面的动态SQL示例返回一个主机变量,该变量包含样本的​​Home_State​​列中所有不同(唯一)值的JSON数组。

以字母​​A​​开头的人名表:

ClassMethod JsonArrayagg()
{
s myquery = 2
s myquery(1) = "SELECT JSON_ARRAYAGG(DISTINCT Home_State) AS DistinctStates "
s myquery(2) = "FROM Sample.Person WHERE Home_State %STARTSWITH 'A'"
s tStatement = ##class(%SQL.Statement).%New()
s tStatement.%SelectMode=1
s qStatus = tStatement.%Prepare(.myquery)
if qStatus'=1 {
w "%Prepare failed:"
d $System.Status.DisplayError(qStatus)
q
}
s rset = tStatement.%Execute()
d rset.%Display()
w !,"End of data"
}

下面的SQL示例为每个州创建了一个​​JSON​​数组,其中包含在​​Home_City​​列中找到的所有值,以及按州列出的这些城市值的计数。

每个​​Home_State​​行包含该状态的所有​​Home_City​​值的​​JSON​​数组。

这些JSON数组可能包含重复的城市名称:

SELECT Home_State,
COUNT(Home_City) AS CityCount,
JSON_ARRAYAGG(Home_City) AS ArrayAllCities
FROM Sample.Person
GROUP BY Home_State

更有用的是一个​​JSON​​​数组的所有不同的值,发现在​​Home_City​​列为每个州,如下所示的动态SQL示例:

ClassMethod JsonArrayagg1()
{
s myquery = 4
s myquery(1) = "SELECT Home_State,COUNT(DISTINCT Home_City) AS DistCityCount,"
s myquery(2) = "COUNT(Home_City) AS TotCityCount,"
s myquery(3) = "JSON_ARRAYAGG(DISTINCT Home_City) AS ArrayDistCities "
s myquery(4) = "FROM Sample.Person GROUP BY Home_State"
s tStatement = ##class(%SQL.Statement).%New()
s tStatement.%SelectMode=1
s qStatus = tStatement.%Prepare(.myquery)
if qStatus'=1 {
w "%Prepare failed:"
d $System.Status.DisplayError(qStatus)
q
}
s rset = tStatement.%Execute()
d rset.%Display()
w !,"End of data"
}

注意,这个示例返回每个州的不同城市名称和总城市名称的整数计数。

下面的动态SQL示例使用​​%SelectMode​​​属性为​​DOB​​​日期字段返回的JSON值数组指定​​ODBC​​显示模式:

ClassMethod JsonArrayagg2()
{
s myquery = 2
s myquery(1) = "SELECT JSON_ARRAYAGG(DOB) AS DOBs "
s myquery(2) = "FROM Sample.Person WHERE Name %STARTSWITH 'A'"
s tStatement = ##class(%SQL.Statement).%New()
s tStatement.%SelectMode=1
s qStatus = tStatement.%Prepare(.myquery)
if qStatus'=1 {
w "%Prepare failed:"
d $System.Status.DisplayError(qStatus)
q
}
s rset = tStatement.%Execute()
d rset.%Display()
w !,"End of data"
}

下面的动态SQL示例使用​​%FOREACH​​关键字。

它为每个不同的​​Home_State​​返回一行,其中包含该​​Home_State​​的年龄值的JSON数组。

ClassMethod JsonArrayagg3()
{
s myquery = 3
s myquery(1) = "SELECT DISTINCT Home_State,"
s myquery(2) = "JSON_ARRAYAGG(Age %FOREACH(Home_State)) AgesForState "
s myquery(3) = "FROM Sample.Person WHERE Home_State %STARTSWITH 'M'"
s tStatement = ##class(%SQL.Statement).%New()
s tStatement.%SelectMode=1
s qStatus = tStatement.%Prepare(.myquery)
if qStatus'=1 {
w "%Prepare failed:"
d $System.Status.DisplayError(qStatus)
q
}
s rset = tStatement.%Execute()
d rset.%Display()
w !,"End of data"
}

下面的动态SQL示例使用​​%AFTERHAVING​​关键字。

它为每个​​Home_State​​返回一行,其中至少包含一个满足​​HAVING​​子句条件的​​Name​​值(以​​“M”​​开头的名称)。

第一个​​JSON_ARRAYAGG​​函数返回一个包含该状态所有名称的​​JSON​​数组。

第二个​​JSON_ARRAYAGG​​函数返回的​​JSON​​数组只包含满足​​HAVING​​子句条件的名称:

ClassMethod JsonArrayagg4()
{
s myquery = 4
s myquery(1) = "SELECT Home_State,JSON_ARRAYAGG(Name) AS AllNames,"
s myquery(2) = "JSON_ARRAYAGG(Name %AFTERHAVING) AS HavingClauseNames "
s myquery(3) = "FROM Sample.Person GROUP BY Home_State "
s myquery(4) = "HAVING Name LIKE 'M%' ORDER BY Home_State"
s tStatement = ##class(%SQL.Statement).%New()
s tStatement.%SelectMode=1
s qStatus = tStatement.%Prepare(.myquery)
if qStatus'=1 {
w "%Prepare failed:"
d $System.Status.DisplayError(qStatus)
q
}
s rset = tStatement.%Execute()
d rset.%Display()
w !,"End of data"
}