如何使用SQL查询从一对多关联的多表中获取数据
针对关联表的SQL查询方案
根据你给出的表结构和一对多关联关系,我整理了几种常见的查询场景,帮你灵活获取需要的数据:
1. 查询每个行政单位及其对应的所有电话号码
这是最基础的关联查询需求,根据是否需要保留无电话的行政单位,分两种写法:
仅返回有对应电话的行政单位(INNER JOIN)
如果只关心存在电话号码的行政单位,用INNER JOIN过滤掉无匹配的记录:
SELECT a.Id_Administration, a.Lib_Administration, t.Phone_Number FROM Administration a INNER JOIN Telephone t ON a.Id_Administration = t.Id_Administration;
查询结果会以“每个电话号码对应一行”的形式返回,比如administration1会出现两次,分别对应它的两个号码。
返回所有行政单位(包括无电话的)(LEFT JOIN)
如果想保留所有行政单位,哪怕它还没有录入电话号码,用LEFT JOIN:
SELECT a.Id_Administration, a.Lib_Administration, t.Phone_Number FROM Administration a LEFT JOIN Telephone t ON a.Id_Administration = t.Id_Administration;
没有电话的行政单位,Phone_Number字段会显示NULL。
2. 同时关联行政单位、电话和传真表
因为Fax表数据不完整,推荐用LEFT JOIN关联,避免丢失有电话但没传真的记录:
SELECT a.Id_Administration, a.Lib_Administration, t.Phone_Number, f.Fax_Number FROM Administration a LEFT JOIN Telephone t ON a.Id_Administration = t.Id_Administration LEFT JOIN Fax f ON a.Id_Administration = f.Id_Administration;
⚠️ 注意:如果同一个行政单位既有多个电话又有多个传真,这个查询会返回笛卡尔积(即每个电话和每个传真组合成一行)。如果不想出现这种情况,可以考虑分开查询电话和传真,或者用子查询合并结果。
3. 将同一个行政单位的多组联系方式合并为一行
如果希望每个行政单位只显示一行,同时把所有电话/传真合并成一个字段,可以用数据库的字符串聚合函数,不同数据库的函数有所不同:
MySQL/MariaDB 版本
SELECT a.Id_Administration, a.Lib_Administration, GROUP_CONCAT(t.Phone_Number SEPARATOR ', ') AS Phone_Numbers, GROUP_CONCAT(f.Fax_Number SEPARATOR ', ') AS Fax_Numbers FROM Administration a LEFT JOIN Telephone t ON a.Id_Administration = t.Id_Administration LEFT JOIN Fax f ON a.Id_Administration = f.Id_Administration GROUP BY a.Id_Administration, a.Lib_Administration;
SQL Server 版本
SELECT a.Id_Administration, a.Lib_Administration, STRING_AGG(t.Phone_Number, ', ') AS Phone_Numbers, STRING_AGG(f.Fax_Number, ', ') AS Fax_Numbers FROM Administration a LEFT JOIN Telephone t ON a.Id_Administration = t.Id_Administration LEFT JOIN Fax f ON a.Id_Administration = f.Id_Administration GROUP BY a.Id_Administration, a.Lib_Administration;
Oracle 版本
SELECT a.Id_Administration, a.Lib_Administration, LISTAGG(t.Phone_Number, ', ') WITHIN GROUP (ORDER BY t.Id_Phone) AS Phone_Numbers, LISTAGG(f.Fax_Number, ', ') WITHIN GROUP (ORDER BY f.Id_Fax) AS Fax_Numbers FROM Administration a LEFT JOIN Telephone t ON a.Id_Administration = t.Id_Administration LEFT JOIN Fax f ON a.Id_Administration = f.Id_Administration GROUP BY a.Id_Administration, a.Lib_Administration;
这个查询会把同一个行政单位的所有电话用逗号分隔合并到一个字段,传真同理,结果更简洁易读。
内容的提问来源于stack exchange,提问作者user4340666
相关产品推荐
相关产品推荐

