[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Fjoin":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Fjoin":638,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Fjoin":664},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":634,"stem":635,"id":636,"extension":637},"\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Fjoin","多表查询","多表查询用于从两个或更多表中获取数据。常见的连接类型包括内连接、外连接（左、右）和自连接。","技能小册",[12,13],"mysql","join","2025-11-29",false,{"type":17,"value":18,"toc":623},"minimark",[19,22,27,44,49,59,65,95,102,108,128,139,143,155,159,177,182,200,215,219,237,241,259,264,282,287,302,306,315,324,344,347,352,372,390,394,458,463,480,484,566,577,580,619],[20,21,8],"h1",{"id":8},[23,24,26],"h2",{"id":25},"多表查询基础","多表查询（基础）",[28,29,30,31,35,36,39,40,43],"p",{},"多表查询用于从两个或更多表中获取数据。常见的连接类型包括",[32,33,34],"strong",{},"内连接","、",[32,37,38],{},"外连接","（左、右）和",[32,41,42],{},"自连接","。",[45,46,48],"h3",{"id":47},"一内连接inner-join","一、内连接（INNER JOIN）",[28,50,51,54,55,58],{},[32,52,53],{},"作用","：返回两个表中",[32,56,57],{},"连接字段匹配","的行。不匹配的行会被丢弃。",[28,60,61,64],{},[32,62,63],{},"语法","：",[66,67,72],"pre",{"className":68,"code":69,"language":70,"meta":71,"style":71},"language-sql shiki shiki-themes material-theme-lighter github-light github-dark","SELECT 列列表\nFROM 表1\nINNER JOIN 表2 ON 表1.关联列 = 表2.关联列;\n","sql","",[73,74,75,83,89],"code",{"__ignoreMap":71},[76,77,80],"span",{"class":78,"line":79},"line",1,[76,81,82],{},"SELECT 列列表\n",[76,84,86],{"class":78,"line":85},2,[76,87,88],{},"FROM 表1\n",[76,90,92],{"class":78,"line":91},3,[76,93,94],{},"INNER JOIN 表2 ON 表1.关联列 = 表2.关联列;\n",[28,96,97,98,101],{},"（",[73,99,100],{},"INNER"," 可省略）",[28,103,104,107],{},[32,105,106],{},"示例","：查询每个员工的部门名称",[66,109,111],{"className":68,"code":110,"language":70,"meta":71,"style":71},"SELECT e.name, d.dept_name\nFROM employees e\nINNER JOIN departments d ON e.dept_id = d.id;\n",[73,112,113,118,123],{"__ignoreMap":71},[76,114,115],{"class":78,"line":79},[76,116,117],{},"SELECT e.name, d.dept_name\n",[76,119,120],{"class":78,"line":85},[76,121,122],{},"FROM employees e\n",[76,124,125],{"class":78,"line":91},[76,126,127],{},"INNER JOIN departments d ON e.dept_id = d.id;\n",[28,129,130,131,134,135,138],{},"只有 ",[73,132,133],{},"dept_id"," 在 ",[73,136,137],{},"departments"," 中存在的员工才会出现。",[45,140,142],{"id":141},"二左外连接left-join","二、左外连接（LEFT JOIN）",[28,144,145,147,148,151,152,43],{},[32,146,53],{},"：返回",[32,149,150],{},"左表所有行","，即使右表中没有匹配的行。右表中不匹配的列将填充 ",[73,153,154],{},"NULL",[28,156,157,64],{},[32,158,63],{},[66,160,162],{"className":68,"code":161,"language":70,"meta":71,"style":71},"SELECT 列列表\nFROM 表1\nLEFT JOIN 表2 ON 表1.关联列 = 表2.关联列;\n",[73,163,164,168,172],{"__ignoreMap":71},[76,165,166],{"class":78,"line":79},[76,167,82],{},[76,169,170],{"class":78,"line":85},[76,171,88],{},[76,173,174],{"class":78,"line":91},[76,175,176],{},"LEFT JOIN 表2 ON 表1.关联列 = 表2.关联列;\n",[28,178,179,181],{},[32,180,106],{},"：查询所有员工及其部门（包括没有部门的员工）",[66,183,185],{"className":68,"code":184,"language":70,"meta":71,"style":71},"SELECT e.name, d.dept_name\nFROM employees e\nLEFT JOIN departments d ON e.dept_id = d.id;\n",[73,186,187,191,195],{"__ignoreMap":71},[76,188,189],{"class":78,"line":79},[76,190,117],{},[76,192,193],{"class":78,"line":85},[76,194,122],{},[76,196,197],{"class":78,"line":91},[76,198,199],{},"LEFT JOIN departments d ON e.dept_id = d.id;\n",[28,201,202,203,205,206,208,209,212,213,43],{},"如果某员工的 ",[73,204,133],{}," 不存在于 ",[73,207,137],{},"，则 ",[73,210,211],{},"dept_name"," 显示为 ",[73,214,154],{},[45,216,218],{"id":217},"三右外连接right-join","三、右外连接（RIGHT JOIN）",[28,220,221,147,223,226,227,229,230,233,234,236],{},[32,222,53],{},[32,224,225],{},"右表所有行","，左表不匹配则补充 ",[73,228,154],{},"。与 ",[73,231,232],{},"LEFT JOIN"," 对称，但通常可用 ",[73,235,232],{}," 重写，因此使用较少。",[28,238,239,64],{},[32,240,63],{},[66,242,244],{"className":68,"code":243,"language":70,"meta":71,"style":71},"SELECT 列列表\nFROM 表1\nRIGHT JOIN 表2 ON 表1.关联列 = 表2.关联列;\n",[73,245,246,250,254],{"__ignoreMap":71},[76,247,248],{"class":78,"line":79},[76,249,82],{},[76,251,252],{"class":78,"line":85},[76,253,88],{},[76,255,256],{"class":78,"line":91},[76,257,258],{},"RIGHT JOIN 表2 ON 表1.关联列 = 表2.关联列;\n",[28,260,261,263],{},[32,262,106],{},"：查询所有部门及其员工（包括空部门）",[66,265,267],{"className":68,"code":266,"language":70,"meta":71,"style":71},"SELECT e.name, d.dept_name\nFROM employees e\nRIGHT JOIN departments d ON e.dept_id = d.id;\n",[73,268,269,273,277],{"__ignoreMap":71},[76,270,271],{"class":78,"line":79},[76,272,117],{},[76,274,275],{"class":78,"line":85},[76,276,122],{},[76,278,279],{"class":78,"line":91},[76,280,281],{},"RIGHT JOIN departments d ON e.dept_id = d.id;\n",[28,283,284,285,43],{},"如果某个部门没有员工，则员工列显示为 ",[73,286,154],{},[288,289,290],"blockquote",{},[28,291,292,293,296,297,299,300,43],{},"提示：",[73,294,295],{},"RIGHT JOIN"," 可以通过交换表顺序改写为 ",[73,298,232],{},"，因此习惯上多用 ",[73,301,232],{},[45,303,305],{"id":304},"四自连接","四、自连接",[28,307,308,310,311,314],{},[32,309,53],{},"：将一张表与",[32,312,313],{},"它自身","进行连接，通常用于处理具有层级关系（如员工-经理）或比较同一表中不同行的数据。",[28,316,317,319,320,323],{},[32,318,63],{},"：必须使用",[32,321,322],{},"表别名","来区分同一张表的两个实例。",[66,325,327],{"className":68,"code":326,"language":70,"meta":71,"style":71},"SELECT a.列, b.列\nFROM 表 a\nINNER JOIN 表 b ON a.关联列 = b.关联列;\n",[73,328,329,334,339],{"__ignoreMap":71},[76,330,331],{"class":78,"line":79},[76,332,333],{},"SELECT a.列, b.列\n",[76,335,336],{"class":78,"line":85},[76,337,338],{},"FROM 表 a\n",[76,340,341],{"class":78,"line":91},[76,342,343],{},"INNER JOIN 表 b ON a.关联列 = b.关联列;\n",[28,345,346],{},"（也可以用外连接）",[28,348,349,351],{},[32,350,106],{},"：查询每个员工及其经理的名字",[66,353,355],{"className":68,"code":354,"language":70,"meta":71,"style":71},"SELECT e.name AS employee, m.name AS manager\nFROM emp e\nLEFT JOIN emp m ON e.manager_id = m.id;\n",[73,356,357,362,367],{"__ignoreMap":71},[76,358,359],{"class":78,"line":79},[76,360,361],{},"SELECT e.name AS employee, m.name AS manager\n",[76,363,364],{"class":78,"line":85},[76,365,366],{},"FROM emp e\n",[76,368,369],{"class":78,"line":91},[76,370,371],{},"LEFT JOIN emp m ON e.manager_id = m.id;\n",[28,373,374,375,378,379,382,383,386,387,389],{},"这里 ",[73,376,377],{},"emp"," 表既作为员工表（别名 ",[73,380,381],{},"e","），又作为经理表（别名 ",[73,384,385],{},"m","）。使用 ",[73,388,232],{}," 确保没有经理的员工（如 CEO）也会显示。",[45,391,393],{"id":392},"五连接类型对比","五、连接类型对比",[395,396,397,413],"table",{},[398,399,400],"thead",{},[401,402,403,407,410],"tr",{},[404,405,406],"th",{},"连接类型",[404,408,409],{},"保留行",[404,411,412],{},"不匹配时右\u002F左表表现",[414,415,416,428,438,448],"tbody",{},[401,417,418,422,425],{},[419,420,421],"td",{},"INNER JOIN",[419,423,424],{},"仅匹配",[419,426,427],{},"丢弃",[401,429,430,432,435],{},[419,431,232],{},[419,433,434],{},"左表全部",[419,436,437],{},"右表列 NULL",[401,439,440,442,445],{},[419,441,295],{},[419,443,444],{},"右表全部",[419,446,447],{},"左表列 NULL",[401,449,450,452,455],{},[419,451,42],{},[419,453,454],{},"取决于是 INNER\u002FLEFT\u002FRIGHT",[419,456,457],{},"同上",[28,459,460,64],{},[32,461,462],{},"实际选择",[464,465,466,472,477],"ul",{},[467,468,469,470,43],"li",{},"需要匹配数据时用 ",[73,471,421],{},[467,473,474,475,43],{},"需要保留左表全部数据（即使无匹配）时用 ",[73,476,232],{},[467,478,479],{},"处理层次或比较同一表内行时用自连接（配合别名）。",[45,481,483],{"id":482},"六完整示例","六、完整示例",[66,485,487],{"className":68,"code":486,"language":70,"meta":71,"style":71},"-- 内连接：查询已分配部门的员工\nSELECT e.name, d.dept_name\nFROM employees e\nINNER JOIN dept d ON e.dept_id = d.id;\n\n-- 左连接：查询所有员工及其部门（未分配也显示）\nSELECT e.name, d.dept_name\nFROM employees e\nLEFT JOIN dept d ON e.dept_id = d.id;\n\n-- 自连接：查询每个员工及其上级经理\nSELECT worker.name AS employee, manager.name AS manager\nFROM employees worker\nLEFT JOIN employees manager ON worker.manager_id = manager.id;\n",[73,488,489,494,498,502,508,515,521,526,531,537,542,548,554,560],{"__ignoreMap":71},[76,490,491],{"class":78,"line":79},[76,492,493],{},"-- 内连接：查询已分配部门的员工\n",[76,495,496],{"class":78,"line":85},[76,497,117],{},[76,499,500],{"class":78,"line":91},[76,501,122],{},[76,503,505],{"class":78,"line":504},4,[76,506,507],{},"INNER JOIN dept d ON e.dept_id = d.id;\n",[76,509,511],{"class":78,"line":510},5,[76,512,514],{"emptyLinePlaceholder":513},true,"\n",[76,516,518],{"class":78,"line":517},6,[76,519,520],{},"-- 左连接：查询所有员工及其部门（未分配也显示）\n",[76,522,524],{"class":78,"line":523},7,[76,525,117],{},[76,527,529],{"class":78,"line":528},8,[76,530,122],{},[76,532,534],{"class":78,"line":533},9,[76,535,536],{},"LEFT JOIN dept d ON e.dept_id = d.id;\n",[76,538,540],{"class":78,"line":539},10,[76,541,514],{"emptyLinePlaceholder":513},[76,543,545],{"class":78,"line":544},11,[76,546,547],{},"-- 自连接：查询每个员工及其上级经理\n",[76,549,551],{"class":78,"line":550},12,[76,552,553],{},"SELECT worker.name AS employee, manager.name AS manager\n",[76,555,557],{"class":78,"line":556},13,[76,558,559],{},"FROM employees worker\n",[76,561,563],{"class":78,"line":562},14,[76,564,565],{},"LEFT JOIN employees manager ON worker.manager_id = manager.id;\n",[28,567,568,569,572,573,576],{},"掌握这些基础连接类型，可以应对绝大多数多表查询需求。后续可进一步学习 ",[73,570,571],{},"FULL OUTER JOIN","（MySQL 不支持，需用 ",[73,574,575],{},"UNION"," 模拟）、交叉连接等高级用法。",[23,578,579],{"id":579},"参考文献",[395,581,582,592],{},[398,583,584],{},[401,585,586,589],{},[404,587,588],{},"资料",[404,590,591],{},"说明",[414,593,594,608],{},[401,595,596,605],{},[419,597,598],{},[599,600,604],"a",{"href":601,"rel":602},"https:\u002F\u002Fdev.mysql.com\u002Fdoc\u002Frefman\u002F8.0\u002Fen\u002F",[603],"nofollow","MySQL 8.0 手册",[419,606,607],{},"官方",[401,609,610,616],{},[419,611,612],{},[599,613,615],{"href":614},"\u002Fknowledge\u002Fbooklet\u002Fsql","数据存储导读",[419,617,618],{},"学习路径",[620,621,622],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":71,"searchDepth":85,"depth":85,"links":624},[625,633],{"id":25,"depth":85,"text":26,"children":626},[627,628,629,630,631,632],{"id":47,"depth":91,"text":48},{"id":141,"depth":91,"text":142},{"id":217,"depth":91,"text":218},{"id":304,"depth":91,"text":305},{"id":392,"depth":91,"text":393},{"id":482,"depth":91,"text":483},{"id":579,"depth":85,"text":579},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fsql\u002FMySql\u002Fjoin","knowledge\u002Fknowledge\u002Fbooklet\u002Fsql\u002FMySql\u002Fjoin.md","md",{"items":639},[640,644,648,652,656,660],{"path":641,"title":642,"description":643,"category":10,"score":517},"\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Ftool","常用函数","MySQL 提供了丰富的内置函数，用于处理字符串、数值、日期和时间以及条件逻辑。下面分类介绍最常用的基础函数。",{"path":645,"title":646,"description":647,"category":10,"score":517},"\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Finstall","MySQL 安装与基本操作","MySQL 的安装因操作系统而异，但安装完成后，通过命令行客户端连接并进行基本管理的方法是通用的。下面分别介绍安装方式和常用命令。",{"path":649,"title":650,"description":651,"category":10,"score":517},"\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Ftype","数据类型","MySQL 支持多种数据类型，可分为数值、字符串、日期时间、枚举\u002F集合以及 JSON 等。选择合适的类型可以优化存储空间和查询性能。",{"path":653,"title":654,"description":655,"category":10,"score":517},"\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Fdql","查询数据","数据查询语言（DQL）用于从数据库中检索数据，核心是 SELECT 语句。下面从基础查询、条件筛选、排序、限制行数、聚合与分组等方面进行介绍。",{"path":657,"title":658,"description":659,"category":10,"score":517},"\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Fddl","数据库与表的基本操作","DDL（Data Definition Language）用于定义数据库结构，包括创建、修改、删除数据库和表。下面介绍 MySQL 中常用的 DDL 语句。",{"path":661,"title":662,"description":663,"category":10,"score":517},"\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Fdml","数据操作","DML（Data Manipulation Language）用于对表中的数据进行增（INSERT）、删（DELETE）、改（UPDATE）。下面详细介绍这三类操作。",{"series":665,"title":12,"items":666,"index":528,"prev":696,"next":697},"booklet\u002Fsql\u002Fmysql",[667,671,675,679,683,685,687,689,691,692,694],{"path":668,"title":669,"date":670,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Fauth","用户与权限管理","2021-06-06",{"path":672,"title":673,"date":674,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Fbackup","备份与恢复","2024-02-23",{"path":676,"title":677,"date":678,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Fbase","MySQL 基础概念","2021-03-18",{"path":680,"title":681,"date":682,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fsql\u002Fmysql\u002Fconstraints","约束","2020-03-31",{"path":657,"title":658,"date":684,"pinned":15},"2024-07-14",{"path":661,"title":662,"date":686,"pinned":15},"2024-05-30",{"path":653,"title":654,"date":688,"pinned":15},"2024-08-16",{"path":645,"title":646,"date":690,"pinned":15},"2025-04-04",{"path":7,"title":8,"date":14,"pinned":15},{"path":641,"title":642,"date":693,"pinned":15},"2026-01-19",{"path":649,"title":650,"date":695,"pinned":15},"2024-10-16",{"path":645,"title":646,"date":690,"pinned":15},{"path":641,"title":642,"date":693,"pinned":15}]