json - Power BI:将来自无序 JSON 对象的查找值放在正确的列中
问题描述
在 Power BI 中,我有一列包含 JSON。每行包含 3 个 key:value 对,格式为 3-digits:4-digits,如下例所示
表格1
{"567":"1259","568":"1535","570":"1264"}
{"393":"9521","392":"5351","394":"4621"}
每个 key:value 可用于在另一个表中查找条目:
表 2
Key | Value | Entry
-------------------
567 | 1259 | Apple
568 | 1535 | Large
570 | 1264 | Red
393 | 9521 | Small
392 | 5351 | Pear
394 | 4621 | Green
我想创建 3 个新列附加到表 1,填充从表 2 中查找的条目,如下所示:
Fruit | Size | Colour
----------------------
Apple | Large | Red
Pear | Small | Green
我的首选解决方案是split
通过分隔符将 JSON 列转换为 3 ,
,然后merge
将其与表 2 通过Key
. 但是,由于 JSON 对象没有排序,因此第 1 列中的第一个键可能代表例如水果,而第 2 列中的第一个键可能代表例如大小。在此插图中,这将导致水果列中的大小值,这不是本意:
Fruit | Size | Colour
----------------------
Apple | Large | Red
Small | Pear | Green
值得庆幸的是,键值的顺序和它在我的表 2 数据中所代表的内容具有一致的模式。换句话说,具有最低值的键代表水果,具有次高值的键代表大小,具有最高值的键代表颜色。
因此,我认为一种解决方案可能是在 Power BI 中找到一种方法,以编程方式获取 JSON 列并通过升序键值对 JSON 内容进行排序。
示例输入:
{"393":"1259","392":"1535","394":"1264"}
期望的输出:
{"392": "1535","393":"1259","394": "1264"}
正如其他人指出的那样,这可能不是解决这个问题的最佳方法,所以我愿意接受建议。
我也知道这归因于糟糕的数据库设计,但我在这里!
解决方案
感谢 mahoneypat在Power BI 社区论坛上回答了这个问题。我可以确认它有效。
我将他的答案粘贴在下面,因此 Stackoverflow 上的任何人都可以:
这是在查询编辑器中执行此操作的一种方法。要查看它是如何工作的,只需创建一个空白查询,打开高级编辑器并将那里的文本替换为下面的 M 代码。
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("NcvLEYAgDEXRXt6aheSHsRVCJY69C0G3Z+7tHXdArQWuQCX1QFlwblDWDe34CpPAg1FyZOdkV6rZsVPC/H6QBLFVzHG8", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [JsonData = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"JsonData", type text}}),
#"Added Custom1" = Table.AddColumn(#"Changed Type", "Result", each let
thisrecord = Json.Document([JsonData]),
sortedrecord = Record.ReorderFields(thisrecord, List.Sort(Record.FieldNames(thisrecord))),
renamedrecord = Record.RenameFields(sortedrecord, List.Zip({Record.FieldNames(sortedrecord), {"Fruit", "Size", "Color"}}))
in
renamedrecord),
#"Expanded Result" = Table.ExpandRecordColumn(#"Added Custom1", "Result", {"Fruit", "Size", "Color"}, {"Fruit", "Size", "Color"})
in
#"Expanded Result"
关键步骤是使用此表达式的自定义列。将 [JsonData] 替换为带有 Json 字符串的实际列名。
let
thisrecord = Json.Document([JsonData]),
sortedrecord = Record.ReorderFields(thisrecord, List.Sort(Record.FieldNames(thisrecord))),
renamedrecord = Record.RenameFields(sortedrecord, List.Zip({Record.FieldNames(sortedrecord), {"Fruit", "Size", "Color"}}))
in
renamedrecord
推荐阅读
- ruby - 有没有一种干净的方法来删除常见的 ruby 对象初始化代码?
- vmware - 如何使用 Powershell 或 risk api 获取环境中的 Vcenter 服务器列表
- c - 将唯一源分配给 C 中的线程池
- javascript - 动态添加 HTML 节点的代码适用于 Chrome 和 Safari,但不适用于 Firefox
- coordinates - 如何使 svg 图像的区域可点击和可操作
- r - 如何使用 fileInput 有条件地设置反应值?
- java - 调用公共方法时如何处理 IllegalAccessException
- javafx - 在 JavaFX 中,如何在画布上绘制一个移动的字符在窗口的中心?
- python - 根据反应删除频道 // Ticket Bot discord.py
- javascript - JavaScript 无法破解的倒数计时器