2015-04-29 12 views
5

Cho một bảng có chứa một cột của JSON như thế này:làm thế nào để vượt qua tham gia unnest một mảng json theo mau

{"payload":[{"type":"b","value":"9"}, {"type":"a","value":"8"}]} {"payload":[{"type":"c","value":"7"}, {"type":"b","value":"3"}]}

Làm thế nào tôi có thể viết một truy vấn Presto để cho tôi trung bình giá trị b trên tất cả mục?

Cho đến nay tôi nghĩ rằng tôi cần phải sử dụng một cái gì đó giống như của Hive lateral view explode, có tương đương là cross join unnest trong Presto.

Nhưng tôi bị kẹt về cách viết truy vấn Presto cho cross join unnest.

Tôi làm cách nào để sử dụng cross join unnest để mở rộng tất cả các phần tử mảng và chọn chúng?

Trả lời

3

Như bạn chỉ ra, điều này cuối cùng đã được thực hiện trong Presto 0,79. :)

Dưới đây là một ví dụ về cú pháp cho các diễn viên từ here:

select cast(cast ('[1,2,3]' as json) as array<bigint>); 

từ đặc biệt của lời khuyên, không có 'string' gõ Presto như có trong Hive. Điều đó có nghĩa là nếu mảng của bạn chứa chuỗi, hãy đảm bảo bạn sử dụng loại 'varchar' nếu không bạn sẽ nhận được thông báo lỗi nói 'loại mảng không tồn tại' có thể gây hiểu nhầm.

select cast(cast ('["1","2","3"]' as json) as array<varchar>); 
+0

Giá trị không thể chuyển thành mảng (varchar) – colintobing

0

Dưới đây là một ví dụ về điều đó

with example(message) as (
VALUES 
(json '{"payload":[{"type":"b","value":"9"},{"type":"a","value":"8"}]}'), 
(json '{"payload":[{"type":"c","value":"7"}, {"type":"b","value":"3"}]}') 
) 


SELECT 
     n.type, 
     avg(n.value) 
FROM example 
CROSS JOIN 
    UNNEST(
      CAST(
       JSON_EXTRACT(message,'$.payload') 
        as ARRAY(ROW(type VARCHAR, value INTEGER)) 
        ) 
       ) as x(n) 
WHERE n.type = 'b' 
GROUP BY n.type 

with định nghĩa một biểu thức bảng chung (CTE) tên example với một cột aliased như message

VALUES trả về một bảng rowset đúng nguyên văn

UNNEST đang lấy một mảng trong một cột của một hàng và returni ng các phần tử của mảng dưới dạng nhiều hàng.

CAST đang thay đổi loại JSON thành loại ARRAY được yêu cầu cho UNNEST. Nó có thể dễ dàng là một ARRAY<MAP< nhưng tôi thấy ARRAY(ROW( đẹp hơn khi bạn có thể chỉ định tên cột và sử dụng ký hiệu chấm trong mệnh đề chọn.

JSON_EXTRACT đang sử dụng một biểu thức jsonPath để trả về giá trị mảng của payload chính

avg()group by nên SQL quen thuộc.

+0

Câu hỏi chỉ định Presto, tuy nhiên nếu sử dụng Athena, nó xuất hiện đúc thành 'ARRAY (ROW (' và một số loại phức khác không được hỗ trợ, vì vậy hãy sử dụng 'ARRAY (MAP (VARCHAR) , VARCHAR)) 'thay vào đó và trong mệnh đề select và group by tham chiếu đến các giá trị như' xn ['type'] 'etc – Davos

Các vấn đề liên quan