如何找到 aws redshift 中两个 json 数组列之间的差异?
How to find differences between two json array columns in aws redshift?
我有一个红移表A如下
id
json1
json2
json3
1
[{"p":1,"p":2}]
[{"p":1}]
2
[{"p":3,"p":4}]
[{"p":3}]
我想用 json1 和 json2 的差异填充 json3 列,即对于 id1,json3 列是 [{"p":2}],对于 id2,json3 列是 [{"p":4} ]
这方面需要帮助。
您可以使用 ObjctMapper 并将您的 Json 转换为字符串以找出差异,
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String, Object>> type =
new TypeReference<HashMap<String, Object>>() {};
Map<String, Object> firstJsonMap = mapper.readValue(firstJsonElement, type);
Map<String, Object> secondJsonMap = mapper.readValue(secondJsonElement, type);
MapDifference<String, Object> difference = Maps.difference(firstJsonMap, secondJsonMap);
如果您希望使提取的差异图变平以获得更有意义的结果,请参见。
在第二种方法中,您可以使用 JsonNode 来查找差异,如下所示(下面的示例只是检查它们是否确实相同)
JsonNode actualObj1 = mapper.readTree("your firstJson string");
JsonNode actualObj2 = mapper.readTree("your secondJson string");
TextNodeComparator cmp = new TextNodeComparator();
public class TextNodeComparator implements Comparator<JsonNode>
{
@Override
public int compare(JsonNode o1, JsonNode o2) {
if (o1.equals(o2)) {
return 0;
}
if ((o1 instanceof TextNode) && (o2 instanceof TextNode)) {
String s1 = ((TextNode) o1).asText();
String s2 = ((TextNode) o2).asText();
if (s1.equalsIgnoreCase(s2)) {
return 0;
}
}
return 1;
}
}
这在 SQL 中是可行的,尽管有点复杂。 SQL 对行进行操作,而 json 数组就像折叠成一行的虚拟行。您需要将它们展开并使用 SQL 运算符来识别差异。 JOIN 或 EXCEPT 都可以找到额外的元素(现在是行)。如果您需要将这些差异组合回一个 json 数组,那将是最后一步。
1 - 您需要一组序列号(cte 或 table),其值与 max 数组中的元素一样多。您可以使用它来将数组扩展为类似于此的行 -
2 - 您需要为 json1 和 json2
执行 #1
3 - Outer Join 这些结果针对扩展的 json1 和 json2 的各个值,但仅在不匹配时保留(where 子句)
4 - 如果您需要将多个差异组合回 json 格式,您可以使用 listagg() 将它们组合起来
我有一个红移表A如下
id | json1 | json2 | json3 |
---|---|---|---|
1 | [{"p":1,"p":2}] | [{"p":1}] | |
2 | [{"p":3,"p":4}] | [{"p":3}] |
我想用 json1 和 json2 的差异填充 json3 列,即对于 id1,json3 列是 [{"p":2}],对于 id2,json3 列是 [{"p":4} ]
这方面需要帮助。
您可以使用 ObjctMapper 并将您的 Json 转换为字符串以找出差异,
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String, Object>> type =
new TypeReference<HashMap<String, Object>>() {};
Map<String, Object> firstJsonMap = mapper.readValue(firstJsonElement, type);
Map<String, Object> secondJsonMap = mapper.readValue(secondJsonElement, type);
MapDifference<String, Object> difference = Maps.difference(firstJsonMap, secondJsonMap);
如果您希望使提取的差异图变平以获得更有意义的结果,请参见
在第二种方法中,您可以使用 JsonNode 来查找差异,如下所示(下面的示例只是检查它们是否确实相同)
JsonNode actualObj1 = mapper.readTree("your firstJson string");
JsonNode actualObj2 = mapper.readTree("your secondJson string");
TextNodeComparator cmp = new TextNodeComparator();
public class TextNodeComparator implements Comparator<JsonNode>
{
@Override
public int compare(JsonNode o1, JsonNode o2) {
if (o1.equals(o2)) {
return 0;
}
if ((o1 instanceof TextNode) && (o2 instanceof TextNode)) {
String s1 = ((TextNode) o1).asText();
String s2 = ((TextNode) o2).asText();
if (s1.equalsIgnoreCase(s2)) {
return 0;
}
}
return 1;
}
}
这在 SQL 中是可行的,尽管有点复杂。 SQL 对行进行操作,而 json 数组就像折叠成一行的虚拟行。您需要将它们展开并使用 SQL 运算符来识别差异。 JOIN 或 EXCEPT 都可以找到额外的元素(现在是行)。如果您需要将这些差异组合回一个 json 数组,那将是最后一步。
1 - 您需要一组序列号(cte 或 table),其值与 max 数组中的元素一样多。您可以使用它来将数组扩展为类似于此的行 -
2 - 您需要为 json1 和 json2
执行 #13 - Outer Join 这些结果针对扩展的 json1 和 json2 的各个值,但仅在不匹配时保留(where 子句)
4 - 如果您需要将多个差异组合回 json 格式,您可以使用 listagg() 将它们组合起来