我有一个JSON,其中字段的顺序不固定。
即。我可以[A, B, C] or [B, C, A]
所有A,B,C都是json对象的形式为{Name:x,Value:y}。
因此,当我使用USQL提取JSON(我不知道他们的订单)并将其放入CSV(我需要列名称)时:
@output =
SELECT
A["Value"] ?? "0" AS CAST ### (("System_" + A["Name"]) AS STRING),
B["Value"] ?? "0" AS "System_" + B["Name"],
System_da
所以,我试图将列名作为" Name" JSON中的字段。
但是我在####上面收到了错误:
Message
syntax error. Expected one of: FROM ',' EXCEPT GROUP HAVING INTERSECT OPTION ORDER OUTER UNION UNION WHERE ';' ')'
Resolution
Correct the script syntax, using expected token(s) as a guide.
Description
Invalid syntax found in the script.
Details
at token '(', line 74
near the ###:
**************
我不允许动态地输入正确的列名和#34;这是我的问题的绝对必要。
Input: [A, B, C,], [C, B, A]
Output: A.name B.name C.name
Row 1's values
Row 2's values
答案 0 :(得分:3)
这个
@output =
SELECT
A["Value"] ?? "0" AS CAST ### (("System_" + A["Name"]) AS STRING),
B["Value"] ?? "0" AS "System_" + B["Name"],
System_da
不是有效的SELECT子句(在U-SQL和我所知道的任何其他SQL方言中都没有。)
什么是JSON数组?它是键/值对吗?还是位置?或者是数组中的一个值,您希望它是否存在于数组中的标记?
从您的示例中,您似乎想要这样的内容:
输入:
[["A","B","C"],["C","D","B"]]
输出:
A B C D
true true true false
false true true true
如果是这种情况,我会把它写成:
REFERENCE ASSEMBLY [Newtonsoft.Json];
REFERENCE ASSEMBLY [Microsoft.Analytics.Samples.Formats];
USING Microsoft.Analytics.Samples.Formats.Json;
@input =
SELECT "[[\"A\", \"B\", \"C\"],[\"C\", \"D\", \"B\"]]" AS json
FROM (VALUES (1)) AS T(x);
@data =
SELECT JsonFunctions.JsonTuple(arrstring) AS a
FROM @input CROSS APPLY EXPLODE( JsonFunctions.JsonTuple(json).Values) AS T(arrstring);
@data =
SELECT a.Contains("A") AS A, a.Contains("B") AS B, a.Contains("C") AS C, a.Contains("D") AS D
FROM (SELECT a.Values AS a FROM @data) AS t;
OUTPUT @data
TO "/output/data.csv"
USING Outputters.Csv(outputHeader : true);
如果您需要更具动态性的内容,请使用生成的SqlArray
或SqlMap
或使用上述方法生成脚本。
但是,我想知道为什么你会首先以这种方式建模你的信息。我建议找一种更合适的方法来标记JSON中值的存在。
UPDATE :我错过了你关于内部数组成员是一个具有两个键值对的对象的评论,其中一个总是被称为名称(对于属性)而一个总是被称为值适当的价值。所以这就是这种情况的答案。
首先:使用{"Name": "propname", "Value" : "value"}
在JSON中建模键值对完全滥用JSON的灵活建模功能,不应该这样做。如果可以的话,请使用{"propname" : "value"}
。
因此更改输入,以下内容将为您提供旋转值。请注意,您需要提前知道这些值,并且有几个选项可用于如何进行数据透视。我在创建新SqlMap
实例的语句中执行此操作以减少过度建模,然后在下一个SELECT
中从地图中获取值。
REFERENCE ASSEMBLY [Newtonsoft.Json];
REFERENCE ASSEMBLY [Microsoft.Analytics.Samples.Formats];
USING Microsoft.Analytics.Samples.Formats.Json;
@input =
SELECT "[[{\"Name\":\"A\", \"Value\": 1}, {\"Name\": \"B\", \"Value\": 2}, {\"Name\": \"C\", \"Value\":3 }], [{\"Name\":\"C\", \"Value\": 4}, {\"Name\":\"D\", \"Value\": 5}, {\"Name\":\"B\", \"Value\": 6}]]" AS json
FROM (VALUES (1)) AS T(x);
@data =
SELECT JsonFunctions.JsonTuple(arrstring) AS a
FROM @input CROSS APPLY EXPLODE( JsonFunctions.JsonTuple(json)) AS T(rowid, arrstring);
@data =
SELECT new SqlMap<string, string>(
a.Values.Select((kvp) =>
new KeyValuePair<string, string>(
JsonFunctions.JsonTuple(kvp)["Name"]
, JsonFunctions.JsonTuple(kvp)["Value"])
)) AS kvp
FROM @data;
@data =
SELECT kvp["A"] AS A,
kvp["B"] AS B,
kvp["C"] AS C,
kvp["D"] AS D
FROM @data;
OUTPUT @data
TO "/output/data.csv"
USING Outputters.Csv(outputHeader : true);