如何充分發揮 SQL 能力?
來源:阿里雲開發者
阿里妹導讀
一、前言
1.1 初衷
如何高效地使用 MaxCompute(ODPS)SQL ,將基礎 SQL 語法運用到極致。
1.2 適合人群
不論是初學者還是資深人員,本篇文章或許都能有所幫助,不過更適合中級、高階讀者閱讀。
本篇文章重點介紹資料處理思維,並沒有涉及到過多高階的語法,同時為了避免主題發散,文中涉及的函式、語法特性等,不會花費篇幅進行專門的介紹,讀者可以按自身情況自行了解。
1.3 內容結構
本篇文章將圍繞數列生成、區間變換、排列組合、連續判別等主題進行介紹,並附以案例進行實際運用講解。每個主題之間有輕微的前後依賴關係,依次閱讀更佳。
1.4 提示資訊
本篇文章涉及的 SQL 語句只使用到了 MaxCompute(ODPS)SQL 基礎語法特性,理論上所有 SQL 均可以在當前最新版本中執行,同時特意註明,執行環境、相容性等問題不在本篇文章關注範圍內。
二、數列
數列是最常見的資料形式之一,實際資料開發場景中遇到的基本都是有限數列。本節將從最簡單的遞增數列開始,找出一般方法並推廣到更泛化的場景。
2.1 常見數列
2.1.1 一個簡單的遞增數列
首先引出一個簡單的遞增整數數列場景:
從數值 0 開始; 之後的每個數值遞增 1 ; 至數值 3 結束;
實際上,生成該數列的方式有多種,此處介紹其中一種簡單且通用的方案。
-- SQL - 1select t.pos as a_nfrom ( select posexplode(split(space(3), space(1), false))) t;
透過上述 SQL 片段可得知,生成一個遞增序列只需要三個步驟:
3)取出每個元素的索引下標。以上三個步驟可以推廣至更一般的數列場景:等差數列、等比數列。下文將以此為基礎,直接給出最終實現模板。
2.1.2 等差數列
若設首項,公差為 ,則等差數列的通項公式為 。
SQL 實現:
-- SQL - 2select a + t.pos * d as a_nfrom ( select posexplode(split(space(n - 1), space(1), false))) t;
2.1.3 等比數列
若設首項 ,公比為 ,則等比數列的通項公式為。
SQL 實現:
-- SQL - 3select a * pow(q, t.pos) as a_nfrom ( select posexplode(split(space(n - 1), space(1), false))) t;
-- SQL - 4
select sequence(1, 3, 1);
-- result
[1, 2, 3]
2.2 應用場景舉例
2.2.1 還原任意維度組合下的維度列簇名稱
在多維分析場景下,可能會用到高階聚合函式,如 cube 、 rollup 、 grouping sets 等,可以針對不同維度組合下的資料進行聚合統計。
場景描述
現有使用者訪問日誌表 visit_log ,每一行資料表示一條使用者訪問日誌。
-- SQL - 5with visit_log as ( select stack ( 6, '2024-01-01', '101', '湖北', '武漢', 'Android', '2024-01-01', '102', '湖南', '長沙', 'IOS', '2024-01-01', '103', '四川', '成都', 'Windows', '2024-01-02', '101', '湖北', '孝感', 'Mac', '2024-01-02', '102', '湖南', '邵陽', 'Android', '2024-01-03', '101', '湖北', '武漢', 'IOS' ) -- 欄位:日期,使用者,省份,城市,裝置型別 as (dt, user_id, province, city, device_type))select * from visit_log;
2)想要輸出 聚合的維度列的名稱,用於下游的報表展示等場景,又該如何處理?
解決思路
可以藉助 MaxCompute(ODPS)提供的 GROUPING__ID 來解決,核心方法是對 GROUPING__ID 進行逆向實現。
詳細步驟如下:
一、準備好所有的 GROUPING__ID 。
生成一個包含個數值的遞增數列,將每個數值轉為 2 進位制字串,並展開該 2 進位制字串的每個位元位。
GROUPING__ID | bits |
0 | { ..., 0, 0, 0 } |
1 | { ..., 0, 0, 1 } |
2 | { ..., 0, 1, 0 } |
3 | { ..., 0, 1, 1 } |
... | ... |
... |
二、準備好所有維度名稱。
生成一個字串序列,依次儲存個維度列的名稱,即
{ dim_name_1, dim_name_2, ..., dim_name_n }
對於 GROUPING__ID 遞增數列中的每個數值,將該數值的 2 進位制每個位元位與維度名稱序列的下標進行對映,輸出所有對應位元位 0 的維度名稱。例如:
GROUPING__ID:3 => { 0, 1, 1 }
維度名稱序列:{ 省份, 城市, 裝置型別 }
對映:{ 0:省份, 1:城市, 1:裝置型別 }
GROUPING__ID 為 3 的資料行聚合維度即為:省份
SQL 實現
-- SQL - 6with group_dimension as ( select -- 每種分組對應的維度欄位 gb.group_id, concat_ws(",", collect_list(case when gb.placeholder_bit = 0 then dim_col.val else null end)) as dimension_name from ( select groups.pos as group_id, pe.* from ( select posexplode(split(space(cast(pow(2, 3) as int) - 1), space(1), false)) ) groups -- 所有分組 lateral view posexplode(regexp_extract_all(lpad(conv(groups.pos,10,2), 3, "0"), '(0|1)')) pe as placeholder_idx, placeholder_bit -- 每個分組的bit資訊 ) gb left join ( -- 所有維度欄位 select posexplode(split("省份,城市,裝置型別", ',')) ) dim_col on gb.placeholder_idx = dim_col.pos group by gb.group_id)select group_dimension.dimension_name, province, city, device_type, visit_countfrom ( select grouping_id(province, city, device_type) as group_id, province, city, device_type, count(1) as visit_count from visit_log b group by province, city, device_type GROUPING SETS( (province), (province, city), (province, city, device_type) )) tjoin group_dimension on t.group_id = group_dimension.group_idorder by group_dimension.dimension_name;
dimension_name | province | city | device_type | visit_count |
省份 | 湖北 | NULL | NULL | 3 |
省份 | 湖南 | NULL | NULL | 2 |
省份 | 四川 | NULL | NULL | 1 |
省份,城市 | 湖北 | 武漢 | NULL | 2 |
省份,城市 | 湖南 | 長沙 | NULL | 1 |
省份,城市 | 湖南 | 邵陽 | NULL | 1 |
省份,城市 | 湖北 | 孝感 | NULL | 1 |
省份,城市 | 四川 | 成都 | NULL | 1 |
省份,城市,裝置型別 | 湖北 | 孝感 | Mac | 1 |
省份,城市,裝置型別 | 湖南 | 長沙 | IOS | 1 |
省份,城市,裝置型別 | 湖南 | 邵陽 | Android | 1 |
省份,城市,裝置型別 | 四川 | 成都 | Windows | 1 |
省份,城市,裝置型別 | 湖北 | 武漢 | Android | 1 |
省份,城市,裝置型別 | 湖北 | 武漢 | IOS | 1 |
三、區間
區間相較數列具有不同的資料特徵,不過在實際應用中,數列與區間的處理具有較多相通性。本節將介紹一些常見的區間場景,並抽象出通用的解決方案。
3.1 常見區間操作
3.1.1 區間分割
已知一個數值區間,如何將該區間均分成 段子區間?
該問題可以簡化為數列問題,數列公式為 ,其中,具體步驟如下:
3)取出每個元素的索引下標,並進行數列公式計算,得出每個子區間的起始值與結束值。
SQL 實現:
-- SQL - 7select a + t.pos * d as sub_interval_start, -- 子區間起始值 a + (t.pos + 1) * d as sub_interval_end -- 子區間結束值from ( select posexplode(split(space(n - 1), space(1), false))) t;
3.1.2 區間交叉
已知兩個日期區間存在交叉 ['2024-01-01', '2024-01-03'] 、 ['2024-01-02', '2024-01-04']。問:
1)如何合併兩個日期區間,並返回合併後的新區間?
2)如何知道哪些日期是交叉日期,並返回該日期交叉次數?
解決上述問題的方法有多種,此處介紹其中一種簡單且通用的方案。核心思路是結合數列生成、區間分割方法,先將日期區間分解為最小處理單元,即多個日期組成的數列,然後再基於日期粒度做統計。具體步驟如下:
3)透過日期序列統計合併後的區間,交叉次數。
SQL 實現:
-- SQL - 8with dummy_table as ( select stack( 2, '2024-01-01', '2024-01-03', '2024-01-02', '2024-01-04' ) as (date_start, date_end))select min(date_item) as date_start_merged, max(date_item) as date_end_merged, collect_set( -- 交叉日期計數 case when date_item_cnt > 1 then concat(date_item, ':', date_item_cnt) else null end ) as overlap_datefrom ( select -- 拆解後的單個日期 date_add(date_start, pos) as date_item, -- 拆解後的單個日期出現的次數 count(1) over (partition by date_add(date_start, pos)) as date_item_cnt from dummy_table lateral view posexplode(split(space(datediff(date_end, date_start)), space(1), false)) t as pos, val) t;
date_start_merged | date_end_merged | overlap_date |
2024-01-01 | 2024-01-04 | ["2024-01-02:2","2024-01-03:2"] |
?增加點兒難度!
如果有多個日期區間,且區間之間交叉狀態未知,上述問題又該如何求解。即:
2)如何知道哪些日期是交叉日期,並返回該日期交叉次數?
SQL 實現:
-- SQL - 9with dummy_table as ( select stack( 5, '2024-01-01', '2024-01-03', '2024-01-02', '2024-01-04', '2024-01-06', '2024-01-08', '2024-01-08', '2024-01-08', '2024-01-07', '2024-01-10' ) as (date_start, date_end))select min(date_item) as date_start_merged, max(date_item) as date_end_merged, collect_set( -- 交叉日期計數 case when date_item_cnt > 1 then concat(date_item, ':', date_item_cnt) else null end ) as overlap_datefrom ( select -- 拆解後的單個日期 date_add(date_start, pos) as date_item, -- 拆解後的單個日期出現的次數 count(1) over (partition by date_add(date_start, pos)) as date_item_cnt, -- 對於拆解後的單個日期,重組為新區間的標記 date_add(date_add(date_start, pos), 1 - dense_rank() over (order by date_add(date_start, pos))) as cont from dummy_table lateral view posexplode(split(space(datediff(date_end, date_start)), space(1), false)) t as pos, val) tgroup by cont;
date_start_merged | date_end_merged | overlap_date |
2024-01-01 | 2024-01-04 | ["2024-01-02:2","2024-01-03:2"] |
2024-01-06 | 2024-01-10 | ["2024-01-07:2","2024-01-08:3"] |
3.2 應用場景舉例
3.2.1 按任意時段統計資料
場景描述
現有使用者還款計劃表 user_repayment ,該表內的一條資料,表示使用者在指定日期區間內 [date_start, date_end] ,每天還款 repayment 元。
-- SQL - 10with user_repayment as ( select stack( 3, '101', '2024-01-01', '2024-01-15', 10, '102', '2024-01-05', '2024-01-20', 20, '103', '2024-01-10', '2024-01-25', 30 ) -- 欄位:使用者,開始日期,結束日期,每日還款金額 as (user_id, date_start, date_end, repayment))select * from user_repayment;
解決思路
核心思路是將日期區間轉換為日期序列,再按日期序列進行彙總統計。
SQL 實現
-- SQL - 11select date_item as day, sum(repayment) as total_repaymentfrom ( select date_add(date_start, pos) as date_item, repayment from user_repayment lateral view posexplode(split(space(datediff(date_end, date_start)), space(1), false)) t as pos, val) twhere date_item >= '2024-01-15' and date_item <= '2024-01-16'group by date_itemorder by date_item;
day | total_repayment |
2024-01-15 | 60 |
2024-01-16 | 50 |
四、排列組合
排列組合是針對離散資料常用的資料組織方法,本節將分別介紹排列、組合的實現方法,並結合例項著重介紹透過組合對資料的處理。
4.1 常見排列組合操作
4.1.1 排列
已知字元序列 [ 'A', 'B', 'C' ] ,每次從該序列中可重複地選取出 2 個字元,如何獲取到所有的排列?
藉助多重 lateral view 即可解決,整體實現比較簡單。
-- SQL - 12select concat(val1, val2) as permfrom (select split('A,B,C', ',') as characters) dummylateral view explode(characters) t1 as val1lateral view explode(characters) t2 as val2;
perm |
AA |
AB |
AC |
BA |
BB |
BC |
CA |
CB |
CC |
4.1.2 組合
已知字元序列 [ 'A', 'B', 'C' ] ,每次從該序列中可重複地選取出 2 個字元,如何獲取到所有的組合?
藉助多重 lateral view 即可解決,整體實現比較簡單。
-- SQL - 13select concat(least(val1, val2), greatest(val1, val2)) as combfrom (select split('A,B,C', ',') as characters) dummylateral view explode(characters) t1 as val1lateral view explode(characters) t2 as val2group by least(val1, val2), greatest(val1, val2);
comb |
AA |
AB |
AC |
BB |
BC |
CC |
提示:亦可直接使用 MaxCompute(ODPS)系統函式 combinations 快速生成組合。
-- SQL - 14
select combinations(array('foo', 'bar', 'boo'),2);
-- result
[['foo', 'bar'], ['foo', 'boo']['bar', 'boo']]
4.2 應用場景舉例
4.2.1 分組對比統計
場景描述
現有投放策略轉化表,該表內的一條資料,表示一天內某投放策略帶來的訂單量。
-- SQL - 15with strategy_order as ( select stack( 3, '2024-01-01', 'Strategy A', 10, '2024-01-01', 'Strategy B', 20, '2024-01-01', 'Strategy C', 30 ) -- 欄位:日期,投放策略,單量 as (dt, strategy, order_cnt))select * from strategy_order;
對比組 | 投放策略 | 轉化單量 |
Strategy A-Strategy B | Strategy A | xxx |
Strategy A-Strategy B | Strategy B | xxx |
解決思路
核心思路是從所有投放策略列表中不重複地取出 2 個策略,生成所有的組合結果,然後關聯 strategy_order 表分組統計結果。
SQL 實現
-- SQL - 16select /*+ mapjoin(combs) */ combs.strategy_comb, so.strategy, so.order_cntfrom strategy_order sojoin ( -- 生成所有對比組 select concat(least(val1, val2), '-', greatest(val1, val2)) as strategy_comb, least(val1, val2) as strategy_1, greatest(val1, val2) as strategy_2 from ( select collect_set(strategy) as strategies from strategy_order ) dummy lateral view explode(strategies) t1 as val1 lateral view explode(strategies) t2 as val2 where val1 <> val2 group by least(val1, val2), greatest(val1, val2)) combs on 1 = 1where so.strategy in (combs.strategy_1, combs.strategy_2)order by combs.strategy_comb, so.strategy;
對比組 | 投放策略 | 轉化單量 |
Strategy A-Strategy B | Strategy A | 10 |
Strategy A-Strategy B | Strategy B | 20 |
Strategy A-Strategy C | Strategy A | 10 |
Strategy A-Strategy C | Strategy C | 30 |
Strategy B-Strategy C | Strategy B | 20 |
Strategy B-Strategy C | Strategy C | 30 |
五、連續
本節主要介紹連續性問題,重點描述了常見連續活躍場景。對於靜態型別的連續活躍、動態型別的連續活躍,分別闡述了不同的實現方案。
5.1 普通連續活躍統計
場景描述
現有使用者訪問日誌表 visit_log ,每一行資料表示一條使用者訪問日誌。
-- SQL - 17with visit_log as ( select stack ( 6, '2024-01-01', '101', '湖北', '武漢', 'Android', '2024-01-01', '102', '湖南', '長沙', 'IOS', '2024-01-01', '103', '四川', '成都', 'Windows', '2024-01-02', '101', '湖北', '孝感', 'Mac', '2024-01-02', '102', '湖南', '邵陽', 'Android', '2024-01-03', '101', '湖北', '武漢', 'IOS' ) -- 欄位:日期,使用者,省份,城市,裝置型別 as (dt, user_id, province, city, device_type))select * from visit_log;
上述問題在分析連續性時,獲取連續性的結果以超過固定閾值為準,此處歸類為 連續活躍大於 N 天閾值的普通連續活躍場景統計。
SQL 實現
基於相鄰日期差實現( lag / lead 版)
整體實現比較簡單。
-- SQL - 18select user_idfrom ( select *, lag(dt, 2 - 1) over (partition by user_id order by dt) as lag_dt from (select dt, user_id from visit_log group by dt, user_id) t0) t1where datediff(dt, lag_dt) + 1 = 2group by user_id;
user_id |
101 |
102 |
基於相鄰日期差實現(排序版)
整體實現比較簡單。
-- SQL - 19select user_idfrom ( select *, dense_rank() over (partition by user_id order by dt) as dr from visit_log) t1where datediff(dt, date_add(dt, 1 - dr)) + 1 = 2group by user_id;
user_id |
101 |
102 |
基於連續活躍天數實現
可以視作 基於相鄰日期差實現(排序版) 的衍生版本,該實現能獲取到更多資訊,如連續活躍天數。
-- SQL - 20select user_idfrom ( select *, -- 連續活躍天數 count(distinct dt) over (partition by user_id, cont) as cont_days from ( select *, date_add(dt, 1 - dense_rank() over (partition by user_id order by dt)) as cont from visit_log ) t1) t2where cont_days >= 2group by user_id;
user_id |
101 |
102 |
基於連續活躍區間實現
可以視作 基於相鄰日期差實現(排序版) 的衍生版本,該實現能獲取到更多資訊,如連續活躍區間。
-- SQL - 21select user_idfrom ( select user_id, cont, -- 連續活躍區間 min(dt) as cont_date_start, max(dt) as cont_date_end from ( select *, date_add(dt, 1 - dense_rank() over (partition by user_id order by dt)) as cont from visit_log ) t1 group by user_id, cont) t2where datediff(cont_date_end, cont_date_start) + 1 >= 2group by user_id;
user_id |
101 |
102 |
5.2 動態連續活躍統計
場景描述
現有使用者訪問日誌表 visit_log ,每一行資料表示一條使用者訪問日誌。
-- SQL - 22with visit_log as ( select stack ( 6, '2024-01-01', '101', '湖北', '武漢', 'Android', '2024-01-01', '102', '湖南', '長沙', 'IOS', '2024-01-01', '103', '四川', '成都', 'Windows', '2024-01-02', '101', '湖北', '孝感', 'Mac', '2024-01-02', '102', '湖南', '邵陽', 'Android', '2024-01-03', '101', '湖北', '武漢', 'IOS' ) -- 欄位:日期,使用者,省份,城市,裝置型別 as (dt, user_id, province, city, device_type))select * from visit_log;
上述問題在分析連續性時,獲取連續性的結果不是且無法與固定的閾值作比較,而是各自以最長連續活躍作為動態閾值,此處歸類為 動態連續活躍場景統計。
SQL 實現
基於 普通連續活躍場景統計 的思路進行擴充套件即可,此處直接給出最終 SQL :
-- SQL - 23select user_id, -- 最長連續活躍天數 datediff(max(dt), min(dt)) + 1 as cont_days, -- 最長連續活躍日期區間 min(dt) as cont_date_start, max(dt) as cont_date_endfrom ( select *, date_add(dt, 1 - dense_rank() over (partition by user_id order by dt)) as cont from visit_log) t1group by user_id, contorder by cont_days desclimit 2;
user_id | cont_days | cont_date_start | cont_date_end |
101 | 3 | 2024-01-01 | 2024-01-03 |
102 | 2 | 2024-01-01 | 2024-01-02 |
六、擴充套件
引申出更復雜的場景,是本篇文章前面章節內容的結合與變種。
6.1 區間連續(最長子區間切分)
場景描述
現有使用者掃描或連線 WiFi 記錄表 user_wifi_log ,每一行資料表示某時刻使用者掃描或連線 WiFi 的日誌。
-- SQL - 24with user_wifi_log as ( select stack ( 9, '2024-01-01 10:01:00', '101', 'cmcc-Starbucks', 'scan', -- 掃描 '2024-01-01 10:02:00', '101', 'cmcc-Starbucks', 'scan', '2024-01-01 10:03:00', '101', 'cmcc-Starbucks', 'scan', '2024-01-01 10:04:00', '101', 'cmcc-Starbucks', 'conn', -- 連線 '2024-01-01 10:05:00', '101', 'cmcc-Starbucks', 'conn', '2024-01-01 10:06:00', '101', 'cmcc-Starbucks', 'conn', '2024-01-01 11:01:00', '101', 'cmcc-Starbucks', 'conn', '2024-01-01 11:02:00', '101', 'cmcc-Starbucks', 'conn', '2024-01-01 11:03:00', '101', 'cmcc-Starbucks', 'conn' ) -- 欄位:時間,使用者,WiFi,狀態(掃描、連線) as (time, user_id, wifi, status))select * from user_wifi_log;
3)不同行為區間在滿足定義的情況下應取到最長;
user_id | wifi | status | time_start | time_end | 備註 |
101 | cmcc-Starbucks | scan | 2024-01-01 10:01:00 | 2024-01-01 10:03:00 | 使用者掃描了 WiFi |
101 | cmcc-Starbucks | conn | 2024-01-01 10:04:00 | 2024-01-01 10:06:00 | 使用者連線了 WiFi |
101 | cmcc-Starbucks | conn | 2024-01-01 11:01:00 | 2024-01-01 11:02:00 | 距離上次連線已經超過 30 分鐘,認為是一次新的連線行為 |
上述問題稍顯複雜,可視作 動態連續活躍統計 中介紹的 最長連續活躍 的變種。可以描述為 結合連續性閾值與行為序列中的上下文資訊,進行最長子區間的劃分 的問題。
SQL 實現
核心邏輯:以使用者、WIFI 分組,結合連續性閾值與行為序列上下文資訊,劃分行為區間。
詳細步驟:
3)最終輸出結果:使用者、WIFI、行為狀態(掃描態、連線態)、行為開始時間、行為結束時間;
-- SQL - 25select user_id, wifi, max(status) as status, min(time) as start_time, max(time) as end_timefrom ( select *, max(if(lag_status is null or lag_time is null or status <> lag_status or datediff(time, lag_time, 'ss') > 60 * 30, rn, null)) over (partition by user_id, wifi order by time) as group_idx from ( select *, row_number() over (partition by user_id, wifi order by time) as rn, lag(time, 1) over (partition by user_id, wifi order by time) as lag_time, lag(status, 1) over (partition by user_id, wifi order by time) as lag_status from user_wifi_log ) t1) t2group by user_id, wifi, group_idx;
user_id | wifi | status | start_time | end_time |
101 | cmcc-Starbucks | scan | 2024-01-01 10:01:00 | 2024-01-01 10:03:00 |
101 | cmcc-Starbucks | conn | 2024-01-01 10:04:00 | 2024-01-01 10:06:00 |
101 | cmcc-Starbucks | conn | 2024-01-01 11:01:00 | 2024-01-01 11:03:00 |
該案例中的連續性判別條件可以推廣到更多場景,例如基於日期差值、時間差值、列舉型別、距離差值等作為連續性判別條件的資料場景。
結語
透過靈活的、散發性的資料處理思維,就可以用基礎的語法,解決複雜的資料場景 是本篇文章貫穿全文的思想。文中針對數列生成、區間變換、排列組合、連續判別等常見的場景,給出了相對通用的解決方案,並結合例項進行了實際運用的講解。
本篇文章嘗試獨闢蹊徑,強調靈活的資料處理思維,希望能讓讀者覺得眼前一亮,更希望真的能給讀者產生幫助。同時畢竟個人能力有限,思路不一定是最優的,甚至可能出現錯誤,歡迎提出意見或建議。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027826/viewspace-2991418/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 找出能讓服裝企業發揮最大能力的“球”
- 如何在微軟Hyper-V下發揮SQL Server最大功效?AY微軟SQLServer
- 人們沒有充分利用人工智慧來發揮人類的潛力人工智慧
- 哈工大提出創新迭代推理框架 DPE-MNER :充分發揮多模態表示潛力框架
- 文旅產業如何充分發掘特色資源優勢產業
- CRM如何讓客戶關係發揮作用
- 新基建浪潮下,區塊鏈如何發揮作用?區塊鏈
- 如何讓友情連結發揮出最佳SEO效果?
- CRM如何讓客戶關係管理發揮作用?
- 如何讓CAD技術發揮的更有價值
- [譯] 如何在 Android 開發中充分利用多攝像頭 APIAndroidAPI
- MySQL如何充分利用系統資源?MySql
- 如何充分利用你的會話工具會話
- 提高遊戲留存,如何讓遊戲社群發揮效用?遊戲
- 如何讓敏捷中的每日站會發揮最大效果?敏捷
- ERP系統如何發揮作用,提高企業生產力?
- 如何有效利用企業資源,發揮Scrum最大優勢?Scrum
- 教你吧GV發簡訊充分VG不回你即可
- 如何提升伺服器的高併發能力伺服器
- 如何快速排程 PTS 的百萬併發能力
- 專案管理中如何充分利用子任務專案管理
- 如何充分利用Apple的macOS預覽應用APPMac
- 一文教你如何發揮好 TDengine Grafana 外掛作用Grafana
- “追逐戲”是如何在電子遊戲裡發揮作用的?遊戲
- 記憶體資料庫如何發揮記憶體優勢?記憶體資料庫
- SQL稽核 | 如何使用 SQLE 進行開發階段 SQL稽核SQL
- 如何充分了解業務需求的戰略目標? - nick
- 資料視覺化是如何在智慧水利中發揮作用的?視覺化
- 面對棘手問題,專案經理如何發揮核心作用?
- 夜經濟時代下,文旅夜遊如何發揮最大效益?
- 安全沙箱技術如何在企業數字化中發揮作用?
- 資料要素如何發揮價值,華為雲展現新思路
- 紐約州立大學:提前退休可能在老年人認知能力下降中發揮“重要作用”
- 如何快速構建服務發現的高可用能力
- 如何提高伺服器的併發處理能力?硬核!伺服器
- 充分理解 python -m modPython
- 如何讓TPM在企業中落地生根,發揮其最大價值?
- Liunx皮膚如何設定能充分利用伺服器效能伺服器