使用MySQL UNION SELECT后如何获取原表的真实ID及对应值
解决方案
要区分UNION结果中每条数据的原表来源、真实ID和对应值,核心是在每个子查询中添加一个来源表标识字段,同时明确指定需要查询的列(避免SELECT *带来的潜在问题)。
修改后的SQL语句
首先调整你的SELECT语句,为每个表的查询结果添加一个自定义字段(比如source_table)来标记数据来源,同时明确列出需要的字段:
SELECT id AS original_id, userName, CreatedTime, 'city' AS source_table FROM city UNION ALL -- 用UNION ALL替代UNION,避免自动去重,性能更优 SELECT id AS original_id, userName, CreatedTime, 'fruit' AS source_table FROM fruit ORDER BY CreatedTime ASC LIMIT 15
这里用UNION ALL而不是UNION,因为UNION会自动过滤重复行,如果你不需要去重,UNION ALL的执行效率更高。
对应的PDO代码
修改后的PHP代码可以直接获取到来源表、原表ID和对应值,同时避免使用extract()(容易引发变量冲突):
$stmt = $DB_con->prepare(' SELECT id AS original_id, userName, CreatedTime, \'city\' AS source_table FROM city UNION ALL SELECT id AS original_id, userName, CreatedTime, \'fruit\' AS source_table FROM fruit ORDER BY CreatedTime ASC LIMIT 15 '); $stmt->execute(); if ($stmt->rowCount() > 0) { while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { // 输出格式化后的结果 echo "来源表: {$row['source_table']} | 原表ID: {$row['original_id']} | 值: {$row['userName']}<br>"; } }
关键说明
- 来源表标识:通过
'city' AS source_table和'fruit' AS source_table,每条结果都会明确标记自己来自哪个表,解决了原代码无法区分数据来源的问题。 - 原表真实ID:保留了每个表自身的
id字段,并通过AS original_id重命名(可选,但能让代码更易读),确保你拿到的是对应表的真实ID。 - 避免SELECT*:明确列出字段可以防止因表结构变更(比如新增字段)导致UNION查询报错,同时让代码逻辑更清晰。
- UNION vs UNION ALL:如果你的业务不需要去重,优先用
UNION ALL,它不会对结果集进行去重排序,性能比UNION更好。
内容的提问来源于stack exchange,提问作者user2226832
相关产品推荐
相关产品推荐

