【问题标题】:U-SQL Error in Naming the Column命名列时出现 U-SQL 错误
【发布时间】:2018-03-19 12:09:45
【问题描述】:

我有一个字段顺序不固定的 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

所以,我试图将列名作为 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 ###:
**************

我不允许“动态”输入正确的列名,这是我的问题的绝对必要性。

Input: [A, B, C,], [C, B, A]

Output:        A.name B.name C.name
Row 1's values
Row 2's values

【问题讨论】:

  • 真的是{A, B, C} 还是一个数组?您能否提供一个有效的示例 JSON 文档和所需的输出?
  • @PeterBons 是的,抱歉它的格式为 [A, B , C] 其中 A, B, C 是格式为 {Name:x, Value:y} 的 json 对象
  • @PeterBons 我已经包含了一个小输入输出对

标签: azure analytics azure-data-lake u-sql


【解决方案1】:

这个

@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);

如果您需要更动态的内容,请使用生成的 SqlArraySqlMap 或使用上述方法生成脚本。

但是,我想知道您为什么首先要以这种方式建模您的信息。我建议找到一种更合适的方式来标记 JSON 中值的存在。

更新:我错过了您关于内部数组成员是具有两个键值对的对象的评论,其中一个始终称为名称(用于属性),一个始终称为值适当的价值。所以这就是那个案例的答案。

首先:使用{"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);

【讨论】:

  • 我认为这是这个问题的重复:stackoverflow.com/questions/49137679/… 也许他们为什么再次发布可能是由于序数?
  • 我可以看到关系。对不起,我没有看另一个。我发现我错过了 {Name: name, Value:val} 评论。同样,这是用 JSON 这样的语言对键值对进行建模的错误方法。我也在为他的示例更新我的示例脚本,但我强烈建议以另一种方式对数据进行建模。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-02
  • 1970-01-01
  • 2019-07-07
  • 1970-01-01
相关资源
最近更新 更多