Sql 从包含带有键值对的json对象的列中查找最大值
我有一个表,其中有一列JSON字符串(键值对)项,我只想返回最大值的键值对 我可以这样做,首先Sql 从包含带有键值对的json对象的列中查找最大值,sql,json,tsql,greatest-n-per-group,presto,Sql,Json,Tsql,Greatest N Per Group,Presto,我有一个表,其中有一列JSON字符串(键值对)项,我只想返回最大值的键值对 我可以这样做,首先UNNESTing JSON对象,然后通过orderbyitem,value(DESC)获取最大值,然后使用array\u agg获取最大值。问题是这意味着要创建多个表,而且速度很慢。我希望在一次操作中,我能够提取出最大的键值对 这: 应成为: | id | item | value | | -- | ----- | ----- | | 1 | Item3 | 9.8 | | 2 | Item
UNNEST
ing JSON对象,然后通过orderbyitem,value(DESC)
获取最大值,然后使用array\u agg
获取最大值。问题是这意味着要创建多个表,而且速度很慢。我希望在一次操作中,我能够提取出最大的键值对
这:
应成为:
| id | item | value |
| -- | ----- | ----- |
| 1 | Item3 | 9.8 |
| 2 | Item3 | 5.2 |
| 3 | Item5 | 6.6 |
| 4 | Item7 | 11.2 |
我实际上不需要该值,只要该项是JSON对象中最大的,那么以下内容也可以:
| id | item |
| -- | ----- |
| 1 | Item3 |
| 2 | Item3 |
| 3 | Item5 |
| 4 | Item7 |
在子表中每行存储一个值
CREATE TABLE child (
id INT NOT NULL,
item VARCHAR(6) NOT NULL,
value DECIMAL(9,1),
PRIMARY KEY (id, item)
);
您不必执行联接来查找每个组的最大值,只需使用窗口函数:
WITH cte AS (
SELECT id, item, ROW_NUMBER() OVER (PARTITION BY id ORDER BY value DESC) AS rownum
FROM mytable
)
SELECT * FROM cte WHERE rownum = 1;
用JSON解决这个问题是个坏主意。它使您的表非规范化,使查询更难设计,我预测它将使查询性能更差。在Presto 316中。但是,在这种情况下,不需要unest
你可以
- 使用和将JSON转换为一组键/值对
- 要为最大值拾取键的数组
- 由于键/值对表示为匿名
元素,因此使用起来非常方便,()行
- 由于键/值对表示为匿名
SELECT
id,
reduce(
-- conver JSON to array of key/value pairs
map_entries(CAST(data AS map(varchar, double))),
-- initial state for reduce (must be same type as key/value pairs)
(CAST(NULL AS varchar), -1e0), -- assuming your values cannot be negative
-- reduction function
(state, element) -> if(state[2] > element[2], state, element),
-- reduce output function
state -> state[1]
) AS top
FROM (VALUES
(1, JSON '{"Item1":7.3, "Item2":1.3, "Item3":9.8}'),
(4, JSON '{"Item6":0.9, "Item7":11.2, "Item4":8.1}'),
(5, JSON '{}'),
(6, NULL)
) t(id, data);
输出
id | top
----+-------
1 | Item3
4 | Item7
5 | NULL
6 | NULL
(4 rows)
请标记正在使用的RDBMS(供应商和版本):JSON支持是高度特定于产品的。。。
id | top
----+-------
1 | Item3
4 | Item7
5 | NULL
6 | NULL
(4 rows)