iT邦幫忙

2024 iThome 鐵人賽

DAY 15
0
AI/ ML & Data

粗暴的資料處理 DuckDB系列 第 15

Day15 -- DuckDB Style SQL (9) ?

  • 分享至 

  • xImage
  •  

不知不覺介紹了 8 種特別的 DuckDB SQL,今天是第九天,所以來介紹一個跟咒術迴戰一樣特別經離叛道的 DuckDB SQL

首先我們先來創建一個咒術迴戰的 table

CREATE TABLE sorcery_battle(id, names) AS
VALUES
    (1, ARRAY['Gojo Satoru', 'Itadori Yuji', 'Fushiguro Megumi', 'Kugisaki Nobara']),
    (2, ARRAY['Sukuna', 'Nanami Kento', 'Todo Aoi']),
    (3, ARRAY['Maki Zenin', 'Inumaki Toge']) 

接著把名子裡面有 'to' 的挑出來,因為感覺他們

會贏喔

SELECT 
    id,
    array_agg(name ORDER BY name) AS filtered_names
FROM (
    SELECT 
        id, 
        unnest(names) AS name
    FROM sorcery_battle
) AS unpacked
WHERE name ILIKE '%to%'
GROUP BY id
ORDER BY id;
id  filtered_names
1	[Gojo Satoru]
2	[Nanami Kento, Todo Aoi]
3	[Inumaki Toge]

就像在第八天說的,DuckDB 吸收了很多 Dataframe 的優點,除此之外 DuckDB 也從 Python 身上借鏡了不少語法。

比方說,上面的 Postgres SQL 需要 unnest 一次再重組每個 names array,
但是在python 中要 filter 每個 list 好做非常多。

import pandas as pd

df = pd.DataFrame({
    'id': [1, 2, 3],
    'names': [
        ['Gojo Satoru', 'Itadori Yuji', 'Fushiguro Megumi', 'Kugisaki Nobara'],
        ['Sukuna', 'Nanami Kento', 'Todo Aoi'],
        ['Maki Zenin', 'Inumaki Toge']
    ]
})

def filter_names(name_list):
    return [name for name in name_list if 'to' in name.lower()]

df['filtered_names'] = df['names'].apply(filter_names)

print(df)

這其中的關鍵,就在於

list comprehension

相信你可以猜到, DuckDB 可以支援 list comprehension 😎

SELECT 
    id,
    names,
    [name FOR name IN names IF name.lower().contains('to')] AS filtered_names
FROM (
    VALUES
        (1, ['Gojo Satoru', 'Itadori Yuji', 'Fushiguro Megumi', 'Kugisaki Nobara']),
        (2, ['Sukuna', 'Nanami Kento', 'Todo Aoi']),
        (3, ['Maki Zenin', 'Inumaki Toge'])
) AS sorcery_battle(id, names);

很神奇吧,我第一次看到也是 O口O
趕快到 DuckDB WASM 或 Colab 試試看吧!


上一篇
Day14 -- DuckDB Style SQL (8) ?
下一篇
Day16 -- DuckDB Style SQL (10) ?
系列文
粗暴的資料處理 DuckDB30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言