據(jù)集分析:從SQL導(dǎo)入到數(shù)據(jù)清洗的完整實(shí)戰(zhàn)指南)
簡介NBA歷史與當(dāng)前比賽及球員統(tǒng)計(jì)數(shù)據(jù)集收錄了自1946年至今的完整比賽記錄覆蓋球員逐場數(shù)據(jù)、球隊(duì)表現(xiàn)、賽程與場館信息并補(bǔ)充了球員身高體重等生物特征資料。資源包共7個(gè)文件包含6個(gè)CSV表格和1個(gè)SQL數(shù)據(jù)庫文件壓縮包總大小79.65MBCSV文件便于用Excel或Python直接讀取SQL文件適合導(dǎo)入MySQL等數(shù)據(jù)庫完成多表關(guān)聯(lián)查詢可用于球員橫向?qū)Ρ?、球?duì)?wèi)?zhàn)績分析或構(gòu)建比賽預(yù)測模型。目前已有410人學(xué)習(xí)下載。數(shù)據(jù)字段設(shè)計(jì)規(guī)范包含player_id、game_id、points、rebounds、assists、steals、blocks等核心指標(biāo)既有1946年以來的歷史沉淀也涵蓋本賽季及下賽季賽程。借助SQL可輕松整合球員與球隊(duì)維度快速復(fù)現(xiàn)經(jīng)典賽季或追蹤職業(yè)生涯軌跡能大幅節(jié)省數(shù)據(jù)清洗時(shí)間支撐從基礎(chǔ)統(tǒng)計(jì)到深度挖掘的完整數(shù)據(jù)分析流程是籃球數(shù)據(jù)分析入門與進(jìn)階的理想素材。1. 這份NBA球員數(shù)據(jù)集的價(jià)值不在“歷史全”而在表結(jié)構(gòu)已經(jīng)幫你拆好了這份NBA球員數(shù)據(jù)集覆蓋1946年至今的比賽和球員統(tǒng)計(jì)記錄6個(gè)Excel表格加SQL文件裝的不只是歷史數(shù)據(jù)而是一套已經(jīng)拆好表結(jié)構(gòu)的分析底座。很多人做NBA數(shù)據(jù)分析第一道坎不是SQL寫得不好而是數(shù)據(jù)獲取公開接口有調(diào)用限制網(wǎng)頁抓下來的數(shù)據(jù)又臟又亂最后還得自己清洗半天。這套數(shù)據(jù)集把球員、球隊(duì)、比賽三個(gè)核心實(shí)體拆成了獨(dú)立的表單場粒度和賽季匯總兩層數(shù)據(jù)都齊了。它適合四類人練SQL的、做體育數(shù)據(jù)分析的、寫課程設(shè)計(jì)或畢業(yè)設(shè)計(jì)的、想在本地搭一個(gè)完整數(shù)據(jù)分析項(xiàng)目練手的。導(dǎo)入數(shù)據(jù)庫就能寫復(fù)雜查詢打開Excel就能拖透視表不需要寫爬蟲也不需要調(diào)API。打開文件前先想清楚一個(gè)問題你拿到的不是“一堆數(shù)據(jù)”而是一個(gè)已經(jīng)建模好的關(guān)系結(jié)構(gòu)。后面所有分析動(dòng)作都是在驗(yàn)證這個(gè)結(jié)構(gòu)對不對、能不能支撐你的業(yè)務(wù)問題。接下來我按“摸清表結(jié)構(gòu) → 導(dǎo)入數(shù)據(jù)庫 → 清洗數(shù)據(jù) → 跑分析 → 避坑 → 搭復(fù)用模板”的順序講每一步都給可執(zhí)行的命令和參數(shù)。2. 先把數(shù)據(jù)裝進(jìn)本地庫Excel導(dǎo)入SQL Server與MySQL的完整命令拿到數(shù)據(jù)集的第一件事不是寫分析而是把數(shù)據(jù)從Excel和SQL文件里安全地弄進(jìn)數(shù)據(jù)庫。這個(gè)步驟看著簡單實(shí)際上決定了后面所有查詢的體驗(yàn)。字符集、存儲(chǔ)引擎、字段類型這三樣沒搞對后面清洗時(shí)全都要返工。2.1 摸清六張表的家底字段、主鍵和表間關(guān)系先別急著導(dǎo)入。用Excel或任意編輯器把每個(gè)文件打開看一眼表頭。這類NBA數(shù)據(jù)集通常包含6個(gè)Excel表格按粒度可以分成兩類維度表球員、球隊(duì)和事實(shí)表比賽、球員比賽統(tǒng)計(jì)、球員賽季匯總、球隊(duì)賽季匯總。常見的表命名和字段如下具體列名以你拿到的文件為準(zhǔn)表名常見命名粒度關(guān)鍵字段players每位球員一行player_id, player_name, birthdate, position, draft_year, is_activeteams每支球隊(duì)一行team_id, team_name, city, founded_year, is_activegames每場比賽一行g(shù)ame_id, game_date, home_team_id, away_team_id, home_score, away_score, season_typeplayer_game_stats每位球員每場比賽一行g(shù)ame_id, player_id, team_id, minutes, points, rebounds, assists, turnoversplayer_season_stats每位球員每個(gè)賽季一行player_id, team_id, season_start, games_played, points, avg_pointsteam_season_stats每支球隊(duì)每個(gè)賽季一行team_id, season_start, wins, losses, home_record, away_record打開文件后重點(diǎn)確認(rèn)三件事第一每一張表有沒有主鍵字段通常是player_id、team_id、game_id這類帶id后綴的列第二player_game_stats是連接球員和比賽的事實(shí)表它的game_id能否在games表里找到對應(yīng)記錄第三season字段是“2023-24”這種格式還是單獨(dú)的起始年份。這三件事確認(rèn)完再考慮導(dǎo)入。這六張表的關(guān)系可以這樣理解players和teams是維度表提供名字、位置、城市等描述信息games和player_game_stats是明細(xì)表記錄每場比賽發(fā)生了什么兩個(gè)season_stats表是預(yù)先聚合好的匯總表省去了重復(fù)計(jì)算賽季數(shù)據(jù)的麻煩。做分析時(shí)優(yōu)先從匯總表入手需要單場維度再下鉆到明細(xì)表。2.2 用SQL文件建庫建表執(zhí)行腳本前必改的三個(gè)參數(shù)SQL文件里通常是建庫建表語句加INSERT數(shù)據(jù)。先建一個(gè)空庫再執(zhí)行整個(gè)腳本。以MySQL為例mysql -u root -p -e CREATE DATABASE nba_analysis DEFAULT CHARACTER SET utf8mb4; mysql -u root -p nba_analysis /path/to/nba_dataset.sql如果是SQL Server 2016及以上版本用sqlcmd工具執(zhí)行sqlcmd -S localhost -U sa -P your_password -d NBA -i /path/to/nba_dataset.sql執(zhí)行前檢查SQL文件里三個(gè)關(guān)鍵點(diǎn)。第一是字符集文件頭部有沒有SET NAMES utf8mb4。沒有的話包含中文球員名比如國際球員的表導(dǎo)入后大概率亂碼建議文件頭和數(shù)據(jù)庫都統(tǒng)一成utf8mb4。第二是存儲(chǔ)引擎確認(rèn)建表語句是ENGINEInnoDB如果寫的是MyISAM改成InnoDB再執(zhí)行。MyISAM不支持事務(wù)和外鍵后面做數(shù)據(jù)修復(fù)時(shí)會(huì)非常被動(dòng)。第三是DROP TABLE語句SQL文件里通常有DROP TABLE IF EXISTS如果庫里已經(jīng)有同名表且里面有手工修改過的數(shù)據(jù)執(zhí)行前先備份。SQL Server環(huán)境下執(zhí)行還要注意SQL文件里的批處理分隔符。如果你的SQL文件里包含視圖或存儲(chǔ)過程定義文件里會(huì)有GO語句sqlcmd能識別如果是從MySQL風(fēng)格改過來的文件里面有DELIMITER $$需要先在SSMS里把這段存儲(chǔ)過程定義單獨(dú)復(fù)制出來執(zhí)行不然整批執(zhí)行會(huì)報(bào)語法錯(cuò)誤。這是很多人第一次導(dǎo)入失敗的原因。2.3 Excel表導(dǎo)入的兩種姿勢圖形界面和命令行都走一遍SQL文件負(fù)責(zé)建表結(jié)構(gòu)6個(gè)Excel表格負(fù)責(zé)灌數(shù)據(jù)。如果SQL文件里已經(jīng)包含了完整的數(shù)據(jù)INSERT語句Excel部分只需要做校驗(yàn)如果SQL文件只有結(jié)構(gòu)沒有數(shù)據(jù)就需要把Excel導(dǎo)入。圖形界面適合一次性操作。SQL Server Management Studio里右鍵目標(biāo)數(shù)據(jù)庫 → 任務(wù) → 導(dǎo)入數(shù)據(jù) → 選擇數(shù)據(jù)源“Microsoft Excel” → 選擇工作表 → 映射字段。MySQL Workbench則用Table Data Import Wizard右鍵目標(biāo)表 → Table Data Import。圖形界面有個(gè)好處是導(dǎo)入前能看到字段映射預(yù)覽但每一步都要點(diǎn)鼠標(biāo)重復(fù)導(dǎo)入時(shí)效率很低。命令行方式適合反復(fù)執(zhí)行和寫進(jìn)腳本。先把Excel另存為CSV文件注意編碼選UTF-8然后執(zhí)行LOAD DATA INFILE /var/lib/mysql-files/players.csv INTO TABLE players CHARACTER SET utf8mb4 FIELDS TERMINATED BY , ENCLOSED BY LINES TERMINATED BY \n IGNORE 1 ROWS;這個(gè)命令的參數(shù)說明CHARACTER SET utf8mb4強(qiáng)制按UTF-8解析CSV防止中文亂碼FIELDS TERMINATED BY ,指CSV用逗號分隔ENCLOSED BY 處理字段值里的逗號比如球員名字里有逗號時(shí)會(huì)被雙引號包起來IGNORE 1 ROWS跳過表頭的列名。MySQL默認(rèn)對LOAD DATA INFILE有限制文件要放在/var/lib/mysql-files/目錄下或者用LOCAL關(guān)鍵字從客戶端本地上傳。如果報(bào)“file not found”錯(cuò)誤檢查文件路徑和secure_file_priv變量。3. 拿到數(shù)據(jù)先別急著分析NBA統(tǒng)計(jì)里繞不開的清洗三板斧NBA數(shù)據(jù)集的臟數(shù)據(jù)非常典型。為什么因?yàn)镹BA有70多年的歷史早期的統(tǒng)計(jì)靠人工記錄口徑和現(xiàn)在完全不一樣球員會(huì)重名球隊(duì)會(huì)遷址換名賽季又跨年。這些歷史包袱讓數(shù)據(jù)清洗成為整個(gè)分析流程里最耗時(shí)的環(huán)節(jié)。我把最常見的三個(gè)問題整理成了三板斧。3.1 球員重名與球隊(duì)遷址用player_id和team_id做主鍵而不是名字NBA歷史上有大量重名球員比如叫John Williams的在不同年代就有好幾位。只看球員名字做關(guān)聯(lián)統(tǒng)計(jì)結(jié)果一定會(huì)翻車。同樣球隊(duì)也有這個(gè)問題雷霆隊(duì)的前身是西雅圖超音速球隊(duì)從西雅圖遷到俄克拉荷馬城之后數(shù)據(jù)怎么算如果直接用球隊(duì)名做關(guān)聯(lián)歷史數(shù)據(jù)和當(dāng)前數(shù)據(jù)會(huì)分成兩段。這類數(shù)據(jù)集通常已經(jīng)用player_id和team_id做了代理主鍵這是最好的情況。先用一條SQL驗(yàn)證重名問題是否存在SELECT player_name, COUNT(DISTINCT player_id) AS id_count FROM players GROUP BY player_name HAVING COUNT(DISTINCT player_id) 1 ORDER BY id_count DESC;如果查詢結(jié)果里出現(xiàn)了id_count大于1的行說明確實(shí)有重名球員。后續(xù)所有關(guān)聯(lián)查詢一律用player_idplayer_name只做展示。球隊(duì)同理所有比賽統(tǒng)計(jì)表里的team_id才是不變的身份標(biāo)識team_name只代表“這一個(gè)名字”不代表“這一支球隊(duì)”。3.2 賽季劃分與“當(dāng)前”口徑正則賽季和latest標(biāo)志位的處理NBA賽季是跨年的2023-24賽季從2023年底打到2024年中。數(shù)據(jù)集的season字段常見寫法是“2023-24”或“202324”分析時(shí)需要統(tǒng)一成起始年份作為排序和分組的依據(jù)。另外games表里通常包含季前賽、常規(guī)賽、季后賽三種類型混在一起算勝率會(huì)得出沒有意義的結(jié)果。把賽季字符串轉(zhuǎn)成起始年份的寫法MySQL和SQL Server不一樣-- MySQL提取2023-24中的起始年份 SELECT game_id, CAST(SUBSTRING_INDEX(season, -, 1) AS UNSIGNED) AS season_start FROM games; -- SQL Server提取2023-24中的起始年份 SELECT game_id, CAST(LEFT(season, CHARINDEX(-, season) - 1) AS INT) AS season_start FROM games;分析比賽時(shí)記住每個(gè)查詢都加上賽季類型過濾。先確認(rèn)數(shù)據(jù)里season_type有哪幾個(gè)取值用SELECT DISTINCT season_type FROM games;查一下然后統(tǒng)一加WHERE season_type Regular Season。球員表里的is_active字段也要注意有的數(shù)據(jù)集用布爾值有的用字符串“Y/N”還有的沒有這個(gè)字段。要不要篩“當(dāng)前球員”取決于你的分析目標(biāo)是全歷史視角還是本賽季視角兩種視角用的表結(jié)構(gòu)完全不同。3.3 缺失值和異常值分鐘數(shù)為0但得分不為0的數(shù)據(jù)要小心還有一種很常見的臟數(shù)據(jù)出場時(shí)間為0的球員卻有得分。這不是數(shù)據(jù)錄入錯(cuò)誤而是NBA規(guī)則里技術(shù)犯規(guī)罰球不算出場時(shí)間但得分會(huì)計(jì)入。這類數(shù)據(jù)會(huì)污染場均指標(biāo)的計(jì)算。另外早期比賽數(shù)據(jù)里還可能出現(xiàn)出手?jǐn)?shù)小于命中數(shù)、籃板數(shù)超過理論值的記錄這些是原始錄入錯(cuò)誤沒法靠業(yè)務(wù)規(guī)則解釋。清洗策略分兩步。第一步把明顯違反業(yè)務(wù)規(guī)則的記錄標(biāo)記出來比如SELECT player_name, game_id, minutes, points FROM player_game_stats WHERE minutes 0 AND points 0;這種記錄如果出現(xiàn)在常規(guī)賽明細(xì)里大概率是技術(shù)犯規(guī)罰球如果出現(xiàn)在季后賽就要人工核對。第二步?jīng)Q定是刪除還是保留。我的習(xí)慣是不直接刪除而是加一個(gè)數(shù)據(jù)質(zhì)量標(biāo)記字段比如把這類記錄標(biāo)成flag_data_issue 1。因?yàn)閿?shù)據(jù)分析項(xiàng)目的第一步產(chǎn)出往往是清洗報(bào)告列出有多少條記錄存在異常、異常集中在哪些年份和球隊(duì)這本身就很有分析價(jià)值。直接刪掉會(huì)讓報(bào)告的“異常發(fā)現(xiàn)”部分無話可寫。4. 從六張表里挖出真東西三類能直接上手的NBA數(shù)據(jù)分析項(xiàng)目數(shù)據(jù)準(zhǔn)備好了接下來才是正經(jīng)的分析環(huán)節(jié)。我挑了三個(gè)頗有代表性的分析方向分別對應(yīng)SQL窗口函數(shù)、多表聚合和Excel透視表三種技能。這三個(gè)方向做下來這套數(shù)據(jù)集的絕大部分價(jià)值你就摸透了。4.1 球員生涯趨勢分析用SQL窗口函數(shù)算場均得分曲線單個(gè)球員的賽季表現(xiàn)變化是最直觀的分析需求也最能體現(xiàn)數(shù)據(jù)集的價(jià)值。先看一個(gè)球員的基礎(chǔ)賽季數(shù)據(jù)SELECT player_name, season_start, games_played, points, avg_points FROM player_season_stats WHERE player_name LeBron James ORDER BY season_start;這個(gè)查詢能直接看到每個(gè)賽季的出場數(shù)和得分?jǐn)?shù)。但單賽季數(shù)據(jù)波動(dòng)大傷病、停擺、換隊(duì)都會(huì)造成突然的下滑或提升直接看原始曲線得到的信息有限。更好用的是移動(dòng)平均把鄰近三個(gè)賽季的場均得分做平滑可以消除單賽季噪音看出真正的長期趨勢SELECT player_name, season_start, avg_points, AVG(avg_points) OVER (PARTITION BY player_name ORDER BY season_start ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS ma_3 FROM player_season_stats WHERE player_name LeBron James;窗口函數(shù)的參數(shù)說明PARTITION BY player_name表示對每個(gè)球員單獨(dú)計(jì)算窗口不會(huì)跨球員混算ORDER BY season_start確定排序規(guī)則這是移動(dòng)平均的方向ROWS BETWEEN 2 PRECEDING AND CURRENT ROW定義窗口范圍是當(dāng)前賽季及前兩個(gè)賽季。得到的三期移動(dòng)平均曲線比原始數(shù)據(jù)平滑得多巔峰期和衰退期一眼就能看出來。ROWS BETWEEN ... PRECEDING是窗口函數(shù)里最常用的滑窗寫法比RANGE更適合處理時(shí)間序列因?yàn)镽ANGE遇到并列排序時(shí)會(huì)擴(kuò)大范圍產(chǎn)生預(yù)期外的結(jié)果。4.2 球隊(duì)歷史戰(zhàn)績對比賽季勝率與主客場差異統(tǒng)計(jì)球隊(duì)層面的分析有個(gè)繞不開的數(shù)據(jù)重塑問題games表里一場比賽只有一行主隊(duì)和客隊(duì)在同一行里。要統(tǒng)計(jì)每支球隊(duì)的勝率需要把一行拆成兩行來算。這里用UNION ALL比用表自連接更直觀、更好維護(hù)SELECT team_id, season_start, SUM(is_home) AS home_games, SUM(CASE WHEN is_home 1 AND team_score opp_score THEN 1 ELSE 0 END) AS home_wins, SUM(1 - is_home) AS away_games, SUM(CASE WHEN is_home 0 AND team_score opp_score THEN 1 ELSE 0 END) AS away_wins FROM ( SELECT game_id, home_team_id AS team_id, home_score AS team_score, away_score AS opp_score, 1 AS is_home, season_start FROM games WHERE season_type Regular Season UNION ALL SELECT game_id, away_team_id AS team_id, away_score AS team_score, home_score AS opp_score, 0 AS is_home, season_start FROM games WHERE season_type Regular Season ) t GROUP BY team_id, season_start;邏輯說明子查詢把每場比賽拆成了主客兩行is_home字段標(biāo)記這行是主隊(duì)還是客隊(duì)外層查詢按球隊(duì)和賽季分組用CASE WHEN判斷主客場的勝負(fù)。這個(gè)寫法之后想擴(kuò)展加“凈勝分”也很容易在子查詢里多算一列team_score - opp_score就可以。這個(gè)量級的數(shù)據(jù)集在MySQL里跑窗口函數(shù)和UNION ALL沒有任何壓力不需要?jiǎng)佑肧park之類的分布式框架。4.3 球員橫向?qū)Ρ扔肊xcel透視表實(shí)現(xiàn)MVP級篩選不是所有分析都要寫SQL。6個(gè)Excel表格里自帶了賽季匯總表打開它就能做透視表分析適合不想搭數(shù)據(jù)庫、用Excel快速出結(jié)果的場景。操作步驟打開球員賽季匯總表全選數(shù)據(jù)后按CtrlT轉(zhuǎn)成正規(guī)表格插入 → 透視表行區(qū)域放player_name列區(qū)域放season_start值區(qū)域放avg_points設(shè)為平均值數(shù)據(jù)范圍選最近十個(gè)賽季這樣可以保證對比的是同時(shí)代的球員。透視表做出來后在“行標(biāo)簽”右側(cè)加篩選條件games_played大于等于50才納入統(tǒng)計(jì)然后按“平均值項(xiàng): avg_points”降序排序就能看到每個(gè)球員的場均得分排名。如果透視表太長不好找某個(gè)球員直接CtrlF輸入名字快速定位不用拖動(dòng)滾動(dòng)條翻幾千行。想突出頂級球員用條件格式 → 數(shù)據(jù)條得分越高條越長視覺上非常直觀。這套操作也回答了“Excel到底適不適合做體育數(shù)據(jù)分析”這個(gè)問題做單維度的排名對比Excel透視表比SQL更方便因?yàn)樗恍枰獙慓ROUP BY拖拽字段就行。5. NBA數(shù)據(jù)集避坑指南字段陷阱、編碼問題和SQL執(zhí)行報(bào)錯(cuò)這部分是我實(shí)際用這類歷史體育數(shù)據(jù)集過程中踩過的坑。每一條都是“現(xiàn)象 → 原因 → 解決”的結(jié)構(gòu)你大概率會(huì)遇到其中至少兩條。5.1 現(xiàn)象導(dǎo)入SQL文件后中文亂碼現(xiàn)象執(zhí)行完SQL文件后查詢含有中文球員名的表顯示的是“????”或繁體亂碼。原因SQL文件本身是UTF-8編碼但數(shù)據(jù)庫客戶端連接時(shí)用了默認(rèn)的latin1字符集導(dǎo)致寫入時(shí)編碼翻譯錯(cuò)誤。解決執(zhí)行前確認(rèn)數(shù)據(jù)庫和連接兩層字符集都設(shè)成utf8mb4。MySQL在命令行加參數(shù)mysql -u root -p --default-character-setutf8mb4 nba_analysis /path/to/nba_dataset.sql如果已經(jīng)導(dǎo)入了把亂碼數(shù)據(jù)所在表清空重新導(dǎo)一遍不要試圖用UPDATE修復(fù)亂碼因?yàn)樵醋址呀?jīng)丟了。另外從Excel另存CSV時(shí)老版本Excel默認(rèn)存成ANSI編碼里面如果有中文導(dǎo)入后也是亂碼。要選“CSV UTF-8帶分隔符”格式或者先用記事本打開CSV看中文是否正常顯示再導(dǎo)入。5.2 現(xiàn)象球員統(tǒng)計(jì)數(shù)字對不上現(xiàn)象按球員名字匯總得分發(fā)現(xiàn)某位球員的生涯總得分比官方數(shù)據(jù)多了一大截。原因極大概率是重名球員被合并了。NBA歷史上叫Michael Williams、John Williams這類常見名字的球員有好幾位如果分析時(shí)用GROUP BY player_name而不是GROUP BY player_id這些球員的得分會(huì)算到同一個(gè)人頭上。解決所有聚合查詢一律用player_id或player_name加player_id聯(lián)合分組。數(shù)據(jù)集的players表里看到同一年代有兩個(gè)相同的名字先查一下是不是不同的人。這也是為什么這個(gè)數(shù)據(jù)集的主鍵字段值得特別關(guān)注的原因。5.3 現(xiàn)象日期字段排序不對現(xiàn)象比賽日期按時(shí)間排序時(shí)“2024-1-5”排在“2024-1-15”后面看起來像亂序。原因Excel里日期保存成了文本格式導(dǎo)入數(shù)據(jù)庫后是VARCHAR類型字符串排序按ASCII碼逐位比較所以“1-15”的第二個(gè)字符“1”排在了“1-5”的第二個(gè)字符“-”前面。解決導(dǎo)入時(shí)把日期字段顯式轉(zhuǎn)換或者導(dǎo)入后用一條UPDATE把文本日期轉(zhuǎn)成真正的DATE類型UPDATE games SET game_date STR_TO_DATE(game_date, %Y-%m-%d) WHERE game_date IS NOT NULL AND game_date ;MySQL用STR_TO_DATESQL Server用CONVERT(DATE, game_date, 120)。轉(zhuǎn)完后把字段類型改成DATE以后排序、比較效率都會(huì)正常。如果Excel文件太大不想動(dòng)也可以在Excel里用“分列”功能把文本日期轉(zhuǎn)成日期格式再另存。5.4 現(xiàn)象Excel雙擊SQL文件打不開現(xiàn)象在Windows里雙擊SQL文件Excel彈出“文件格式與擴(kuò)展名不匹配文件已損壞”之類的提示或者直接亂碼。原因SQL文件是純文本文件但系統(tǒng)里設(shè)置的默認(rèn)打開程序是ExcelExcel不識別SQL文件的擴(kuò)展名。解決SQL文件用Visual Studio Code、Notepad或系統(tǒng)自帶的記事本打開不要雙擊。Excel只負(fù)責(zé)打開那6個(gè)Excel文件兩者職責(zé)分開。這個(gè)現(xiàn)象沒什么技術(shù)含量但幾乎每個(gè)第一次接觸數(shù)據(jù)集的人都會(huì)試一次屬于純粹的體力坑。5.5 現(xiàn)象導(dǎo)入幾萬行數(shù)據(jù)耗時(shí)很長聯(lián)表查詢也慢現(xiàn)象執(zhí)行SQL文件導(dǎo)入數(shù)據(jù)要等好幾分鐘導(dǎo)入后寫了一條三聯(lián)表的查詢跑了幾十秒才出結(jié)果。原因SQL文件里的INSERT語句沒有包在事務(wù)里每插入一行就提交一次磁盤寫入次數(shù)太多另外表上沒建索引聯(lián)表查詢每次都要全表掃描。解決導(dǎo)入前關(guān)閉自動(dòng)提交批量導(dǎo)入完成后再一次性提交。MySQL的命令行導(dǎo)入方式可以這樣處理SET autocommit 0; SOURCE /path/to/nba_dataset.sql; COMMIT;建索引是更關(guān)鍵的一步。主鍵字段player_id、game_id、team_id在導(dǎo)入時(shí)會(huì)自動(dòng)建索引但外鍵關(guān)聯(lián)字段不一定會(huì)建。建議在player_game_stats表的game_id、player_id、team_id三列上各加一個(gè)普通索引查詢速度會(huì)有數(shù)量級提升。EXPLAIN SELECT ...看一下執(zhí)行計(jì)劃如果看到“ALL”類型的訪問方式說明在掃全表這就是慢sql優(yōu)化里需要優(yōu)先處理的信號。這個(gè)量級的數(shù)據(jù)索引建好之后窗口函數(shù)和聯(lián)表查詢都該在秒級內(nèi)返回。6. 讓數(shù)據(jù)集活起來用視圖和參數(shù)化查詢搭一個(gè)可復(fù)用的分析模板數(shù)據(jù)集最大的價(jià)值不是一次性用而是反復(fù)查。我建議把最常用的聯(lián)表邏輯固化成一個(gè)寬表視圖再配上參數(shù)化查詢以后做任何分析都不需要重新寫長SQL。先建一個(gè)球員單場明細(xì)寬表視圖把六張表中的球員維度、球隊(duì)維度和比賽維度一次性JOIN好CREATE VIEW v_player_game_detail AS SELECT g.game_id, g.game_date, g.season_start, g.season_type, p.player_id, p.player_name, t.team_id, t.team_name, s.minutes, s.points, s.rebounds, s.assists, s.turnovers FROM player_game_stats s JOIN games g ON s.game_id g.game_id JOIN players p ON s.player_id p.player_id JOIN teams t ON s.team_id t.team_id;視圖建好之后所有臨時(shí)分析只需要從這個(gè)寬表里SELECT不用再考慮關(guān)聯(lián)條件和表名。再做一個(gè)存儲(chǔ)過程把“輸入球員名直接輸出生涯賽季數(shù)據(jù)”封裝成參數(shù)化查詢CREATE PROCEDURE GetPlayerCareer(IN player_name_param VARCHAR(100)) BEGIN SELECT season_start, games_played, points, avg_points FROM player_season_stats s JOIN players p ON s.player_id p.player_id WHERE p.player_name player_name_param ORDER BY season_start; END;調(diào)用時(shí)直接輸入名字CALL GetPlayerCareer(Michael Jordan);存儲(chǔ)過程的好處是參數(shù)可以復(fù)用不用每次改SQL文本配合Excel的ODBC連接可以在Excel單元格里直接調(diào)用并刷新結(jié)果把SQL能力搬回Excel界面。如果你更習(xí)慣用python做數(shù)據(jù)分析也可以把視圖結(jié)果導(dǎo)出成CSV交給pandas處理后續(xù)的可視化。做球員職業(yè)生涯時(shí)間線時(shí)用Excel甘特圖展示職業(yè)生涯長度和單賽季場均得分峰值是個(gè)不錯(cuò)的落地視角一屏就能看清整個(gè)走勢。我個(gè)人養(yǎng)成的習(xí)慣是拿到任何數(shù)據(jù)集先不改原始表第一件事是跑一遍每張表的行數(shù)、主鍵唯一性和外鍵完整性把結(jié)果存成一張數(shù)據(jù)質(zhì)量檢查表再做任何修改前備份原表等于給自己留一顆后悔藥。這套NBA數(shù)據(jù)集的表結(jié)構(gòu)設(shè)計(jì)得比較干凈分析潛力和鍛煉價(jià)值都相當(dāng)大但最后跑出來的報(bào)告能不能讓人信服完全取決于清洗和關(guān)聯(lián)做得扎不扎實(shí)。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取