需求背景:
有一個(gè)表含有兩個(gè)字段
“ID”,“VALUE”
1,香蕉
1,蘋果
2,橘子
3,香蕉
3,蘋果
3,橘子
目標(biāo)要求:將每個(gè)ID的VALUE列聚合成一個(gè)字符串列表
“ID”,“VALUE”
1,[香蕉,蘋果]
2,[橘子]
3,[香蕉,蘋果,橘子]
一、SQL使用 LISTAGG函數(shù)聚合方式
---將使用了LISTAGG函數(shù)來將每個(gè)ID的VALUE列聚合成一個(gè)字符串列表,列表中的元素按VALUE字段的順序排序。
SELECT ID, LISTAGG(VALUE, ',') WITHIN GROUP (ORDER BY VALUE) AS VALUE_LIST
FROM XXX表名
GROUP BY ID
關(guān)于排序的邏輯,想了解的見下回答
二、python連接遠(yuǎn)程數(shù)據(jù)庫的方式,結(jié)果以JSON文件存在本地
也可以在pycharm客戶端使用其他工具(如Python、JSON庫等)來聚合數(shù)據(jù)并生成JSON,將數(shù)據(jù)導(dǎo)出到外部文件,然后給出代碼如下:
import cx_Oracle
# 連接到Oracle數(shù)據(jù)庫
dsn = cx_Oracle.makedsn('YOUR_HOST', 'YOUR_PORT', service_name='YOUR_SERVICE_NAME')
conn = cx_Oracle.connect(user='YOUR_USERNAME', password='YOUR_PASSWORD', dsn=dsn)
# 查詢SQL
query = "select {number_column}, {value_column} FROM {table_name} where rownum<=5"
# 執(zhí)行查詢
cursor = conn.cursor()
cursor.execute(query)
# 初始化一個(gè)字典來聚合同一ID的所有VALUE
id_value_map = {}
# 遍歷查詢結(jié)果并填充字典
for row in cursor:
# print(row)
id, value = row
if id in id_value_map:
id_value_map[id].append(value)#同一個(gè)ID的VALUE值追加
else:
id_value_map[id] = [value]
# 轉(zhuǎn)換為所需的JSON格式
json_data = [{"ID": k, "VALUE": v} for k, v in id_value_map.items()]
# 寫入JSON文件
with open('output.json', 'w', encoding='utf-8') as json_file:
json.dump(json_data, json_file, ensure_ascii=False, indent=4)
# 關(guān)閉數(shù)據(jù)庫連接
cursor.close()
conn.close()
注意:表是普表,以上兩種方法這么執(zhí)行沒有問題!但是,如果表中含有LOB類型字段(large object),即超長(zhǎng)文本字段,方法一 二 就會(huì)報(bào)錯(cuò) !!! 如果遇到“目標(biāo)緩沖區(qū)太小,無法容納字符集轉(zhuǎn)換之后的 CLOB 數(shù)據(jù)”的錯(cuò)誤,這通常意味著在執(zhí)行LISTAGG函數(shù)時(shí),生成的CLOB數(shù)據(jù)超出了數(shù)據(jù)庫允許的緩沖區(qū)大小。
我們可以通過優(yōu)化方法二中的部分代碼來解決這個(gè)問題:文章來源:http://www.zghlxwxcb.cn/news/detail-801427.html
import cx_Oracle
# 連接到Oracle數(shù)據(jù)庫
dsn = cx_Oracle.makedsn('YOUR_HOST', 'YOUR_PORT', service_name='YOUR_SERVICE_NAME')
conn = cx_Oracle.connect(user='YOUR_USERNAME', password='YOUR_PASSWORD', dsn=dsn)
# 查詢SQL
query = "select {number_column}, {value_column} FROM {table_name} where rownum<=5"
# 執(zhí)行查詢
cursor = conn.cursor()
cursor.execute(query)
# 初始化一個(gè)字典來聚合同一ID的所有VALUE
id_value_map = {}
# 遍歷查詢結(jié)果并填充字典
for row in cursor:
# print(row)
id, lob_value = row
# 假設(shè)我們想要讀取整個(gè)LOB數(shù)據(jù)
if lob_value is not None:#lob_value中存在空值,如果沒有不需要加這個(gè)判斷
#使用lob_value.read()來讀取LOB對(duì)象中的全部數(shù)據(jù)
lob_value_str = lob_value.read()
if id in id_value_map:
id_value_map[id].append(lob_value_str)
else:
id_value_map[id] = [lob_value_str]
# 轉(zhuǎn)換為所需的JSON格式
json_data = [{"ID": k, "NOTE": v} for k, v in id_value_map.items()]
# 寫入JSON文件
with open('output_note_ydy.json', 'w', encoding='utf-8') as json_file:
json.dump(json_data, json_file, ensure_ascii=False, indent=4)
# 關(guān)閉數(shù)據(jù)庫連接
cursor.close()
conn.close()
if lob_value is not None:
因?yàn)槲业谋碇衛(wèi)ob_value中存在空值,所以需要加這個(gè)判斷,不然就會(huì)報(bào)如下錯(cuò)誤。文章來源地址http://www.zghlxwxcb.cn/news/detail-801427.html
到了這里,關(guān)于【sql/python】表中某列值以列表聚合的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!