91网首页-91网页版-91网在线观看-91网站免费观看-91网站永久视频-91网站在线播放

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

搞多層 json,SPL 才是專業的

liguoquan
2025年5月28日 9:22 本文熱度 340
: 搞多層 json,SPL 才是專業的


搞多層 json,SPL 才是專業的

業務數據經常存在層次關系,比如訂單包含日期、客戶和訂單明細,訂單明細又包含價格、數量、產品,產品則包含名稱和分類。

json 的可嵌套結構很適合描述這種關系,比如訂單數據:

css
體驗AI代碼助手
代碼解讀
復制代碼
[   {   "order_id": 10248,"order_date": "2022-07-04","freight_rate": 2,"weight": 5,        "order_details": [            {   "price": 14.0,"quantity": 12.0,    "product": {"product_id": 17,"name": "beef","category":"Food"},            },            {   "price": 9.0,"quantity": 10.0    "product": {"product_id": 42,"name": "rice","category":"Food"}            }        ],        "customer": {            "customer_id": 87,"name": "abc inc",            "city": "New York","phone_number": "26471510"        }            },    {   "order_id": 10249,"order_date": "2012-07-05","freight_rate": 10,"weight": 3,        "order_details": [            {   "price": 18.0,"quantity": 9.0    "product": {"product_id": 14,"name": "Computer","category": "Electronic"},            }        ],        "customer": {            "customer_id": 991,"name": "bcd.com",            "city": "Los Angeles","phone_number": "(0251) 1031259"        }     } ...]

訂單既有普通屬性“訂單號、日期、運費單價、重量”,也包括嵌套屬性“訂單明細、客戶”,訂單明細又包含嵌套屬性“產品”。

對于這種可嵌套結構,常見的數據組織方式是多層嵌套表,即字段可以是表或記錄。計算時,無論哪一層的表(記錄),都是對象,都能一致運算。

但 SQL 天生只有平面表,無法實現這種方式。某些新型分析數據庫在一定程度上支持嵌套結構,可以處理 json 數據。

比如要在訂單中查出 order_id, order_date, 以及嵌套屬性 customer 的 name 和 city,用 DuckDB 這樣寫:

csharp
體驗AI代碼助手
代碼解讀
復制代碼
select order_id, order_date, customer.name, customer.city from read_json_auto('orders.json')

這是把單行嵌套字段 customer 看成記錄,用記錄的方式取出其字段。但這種方法只能用于單行嵌套字段,多行的 order_details 就不支持了,這樣寫只能取出空值。

對多行嵌套字段,DuckDB 可以展開后計算。比如要在這個查詢基礎上,對 order_detail 中 quantity*price 匯總求和,得到訂單金額 amount:

scss
體驗AI代碼助手
代碼解讀
復制代碼
select order_id,any_value(order_date),    any_value(customer.name),any_value(customer.city),    sum(od.quantity * od.price) as amount from read_json_auto('orders.json') as o,    lateral unnest(o.order_details) as t(od) group by order_id;

先展開 order_details,與 orders 隱式 join 成大平面表,然后按照訂單號分組匯總求和,代碼很繞。這樣做,還不如轉換成物理的平面表,計算時還能省去“展開”這個步驟。

DuckDB 也可以保持嵌套結構,使用 lambda 語法計算:

csharp
體驗AI代碼助手
代碼解讀
復制代碼
select order_id, order_date,customer.name, customer.city,    list_sum( list_transform(o.order_details,x -> x.price * x.quantity) ) as amount from read_json_auto('orders.json') as o

要使用兩個特殊函數,還要寫顯式的 lambda 語法,略顯啰嗦。

對比一下,普通數據表做類似計算并沒有這么麻煩。比如求訂單運費單價和重量相乘再匯總的代碼是這樣:

scss
體驗AI代碼助手
代碼解讀
復制代碼
select sum(freight_rate*weight) from read_json_auto('orders.json')

語法完全不一致。

實際上,DuckDB 把多行嵌套字段當成數組,而不是數據表。這就造成運算上的不一致,給代碼書寫和閱讀都會帶來麻煩。

esProc SPL 徹底實現了前面說的多層嵌套表機制,可以寫出最簡潔的代碼:

less
體驗AI代碼助手
代碼解讀
復制代碼
orders=json(file("orders.json").read()) orders.new(order_id,order_date,customer.name,customer.city,order_details.sum(price*quantity):amount)

對比一下計算總運費的代碼:

python
體驗AI代碼助手
代碼解讀
復制代碼
orders.sum(freight_rate*weight)

語法完全一致!

字段 order_details 與 orders 一樣都是表對象,計算方法都一致。有這樣簡潔、一致的語法,SPL 處理可嵌套結構的數據,可以說是最專業的了。

Python 也支持多層結構,對于單行的嵌套字段,可以這樣計算:

ini
體驗AI代碼助手
代碼解讀
復制代碼
orders = pd.read_json('orders.json') result_orders = orders[['order_id', 'order_date']].assign(    customer_name=orders['customer'].str['name'],    customer_city=orders['customer'].str['city'] )

取 customer 的字段多了個函數 str,不如 DuckDB 和 SPL 簡潔。而且 str 函數僅支持可以轉為字符串的簡單類型,不支持多行的嵌套字段。

Python 也可以把多行的嵌套字段展開計算:

ini
體驗AI代碼助手
代碼解讀
復制代碼
orders = pd.read_json('orders.json') exploded_orders = orders.explode('order_details') exploded_orders = pd.concat([exploded_orders,exploded_orders['order_details'].apply(pd.Series)], axis=1) exploded_orders['amount'] = exploded_orders['price'] * exploded_orders['quantity'] result = exploded_orders.groupby('order_id').agg({'order_date':'first','amount': 'sum'}).reset_index() final_result = result[['order_id', 'order_date', 'amount']]

先縱向展開 order_details,再橫向展開每行的字段,變成平面表后,再計算分組匯總,這也很繞。多行嵌套結構還要展開兩次,比 DuckDB 更啰嗦。

Python 也能保持嵌套結構,用 lambda 計算:

less
體驗AI代碼助手
代碼解讀
復制代碼
orders = pd.read_json('orders.json') orders['amount'] = orders['order_details'].apply(lambda details:sum(item['price'] * item['quantity'] for item in details)) result=orders[['order_id','order_date','amount']]

Python 是顯式 lambda 語法,要寫 lambda 關鍵字,還要定義參數,有點啰嗦。而且 lambda 函數中還要寫顯式的 for 循環,相當于兩重循環,會增加理解的難度。這里的 for 雖然是簡化寫法,也還是要定義循環變量 item,還是啰嗦。

我們也對比一下計算運費的代碼:

css
體驗AI代碼助手
代碼解讀
復制代碼
total_freight=sum(orders['freight_rate']*orders['weight'])

語法也是完全不一致。

order_details 并不是 orders 那樣的 Dataframe 對象,而是類似數組的列表類型。

在稍復雜的情況下,DuckDB 和 Python 的語法不一致等問題帶來的麻煩會更明顯,比如找出總金額大于 200,而且還包含 Electronics 類產品的訂單,取得 order_id、order_date。

DuckDB 如果采用展開嵌套字段的方式,SQL 就比較難寫了。展開 order_details、product 之后要再分組聚合計算訂單金額,然后再基于這個結果篩選符合條件的訂單,要寫多層子查詢或者 CTE 來保持數據結構的完整性。寫出來的 SQL 會很長,調試起來就不太友好了,這里不再給出,只給出 lambda 的寫法:

csharp
體驗AI代碼助手
代碼解讀
復制代碼
select order_id, order_date from read_json_auto('orders.json') where list_sum(list_transform(order_details,x -> x.price * x.quantity)) > 200 and array_length(list_filter(order_details, x -> x.product.category = 'Electronics')) > 0;

使用了三個特殊函數,兩個顯式 lambda 函數,與一般 SQL 相比,這個代碼復雜、難理解。

Phython 展開方式的代碼也很長,這里只給出 lambda 的寫法:

ini
體驗AI代碼助手
代碼解讀
復制代碼
orders = pd.read_json('orders.json') final_orders = orders[    orders['order_details'].apply(        lambda x: any(item['product']['category'] == 'Electronics' for item in x) and                  sum(item['price'] * item['quantity'] for item in x) >= 200    )] result = final_orders[['order_id', 'order_date']]

apply 一個大循環加顯式的 lambda 語法,套了兩個小的 for 循環,還要定義循環變量,代碼理解起來也費勁。

SPL 使用基本運算函數,不用顯式的 lambda 語法,也不必寫顯式循環,代碼最簡潔、易懂:

less
體驗AI代碼助手
代碼解讀
復制代碼
orders=json(file("orders.json").read()) orders.select(order_details.select@1(product.category=="Electronics") && order_details.sum(price*quantity)>200).new(order_id,order_date)

小結一下,SQL 天生只有平面表,無法實現嵌套結構。DuckDB 補上了嵌套結構,但如果展開嵌套結構再計算的話,還不如直接使用普通平面表。直接對著嵌套結構計算時,各層運算不一致,代碼讀寫都麻煩。且多行嵌套結構要用特殊函數和顯式 lambda 語法,代碼啰嗦。Python 支持嵌套結構,但也存在和 DuckDB 類似的問題。SPL 表的字段可以是表,嵌套結構從上到下的數據組織都一致,都是對象,引用方法也一致,計算代碼簡潔、易懂,是最專業的多層嵌套結構計算語言。

點擊下載免費的esProcSPL試用一下吧~~


該文章在 2025/5/28 9:22:35 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 91社区福利| 最新国产精品剧情在线ss | 午夜日韩一级 | 91午夜在线观看 | 日韩免费视频 | 国产精品一区不卡在 | 欧美日韩免费播 | 韩国欧美在线 | 中文字幕久| 国产特级婬片免费看 | 日韩精品福 | 日本有码中文 | 午夜日韩视频 | 国产精品爽爽在 | 中文字幕第9 | 国语fre| 嫖妓国产在线观看 | 97电影理论 | 91香蕉在线播放 | 国产精品秘果冻 | 国产日韩欧美中文 | 国产又黄又猛又爽 | 青青草免费在线视频 | 91精品国产色综 | 国产午夜三级一区 | 国产又粗又长的视频 | 人人澡人摸人人添 | 91福利导航大全 | 国产日韩欧美二区 | 国产精品制服一 | 国产精品视频一区 | 激情文学小说区另 | 激情五月天综合 | 国产精品丝袜高跟鞋 | 激情视频网站 | 片免费在线 | 日韩制服在线 | 欧美日韩国产在线一 | 伦理影院在线观看 | 日本一黄一区区 | 国产一区二区网站 |