MySQL中主键同名同值但timestamp同名异值的表能否用Natural Join?
问题解答:NATURAL JOIN的适用性与无别名全量查询方案
1. 能不能使用NATURAL JOIN?
答案是绝对不建议使用,甚至可以说完全不能用。
NATURAL JOIN的核心逻辑是自动将两个表中所有名称相同的列都作为关联条件,而不是只识别主键。你这里的情况是,除了主键列同名且数据一致,还有timestamp列同名但数据不同——用NATURAL JOIN的话,数据库会把主键+timestamp同时作为关联条件,只有当两行的主键和timestamp完全匹配时才会被关联。但你明确说了timestamp数据不同,最终要么查不到任何结果,要么得到的结果完全不符合你“通过主键关联两表”的初衷。
2. 有没有无需表别名就能用SELECT *查询两表所有数据的方法?
很遗憾,直接用SELECT *做不到。因为两个表存在同名的timestamp列,数据库无法区分要返回哪一个,执行时要么直接报错,要么只会返回其中一个表的timestamp值,导致另一个表的该列数据丢失。
不过我们可以换个思路,不用给表起别名也能实现全量查询的需求,这里有两种可行方案:
方案一:用USING子句指定主键关联,单独重命名重复列
USING子句可以明确指定仅通过主键列进行关联,同时会自动在结果中只保留一份主键列。之后我们可以用表名直接引用重复的timestamp列并重命名,配合*获取其他所有列:
SELECT *, table2.timestamp AS timestamp_table2 FROM table1 JOIN table2 USING(id); -- 这里的id是你的主键列名
这样*会返回主键列、table1的所有列(包括它的timestamp),再加上重命名后的table2的timestamp,就拿到了两表的所有数据,全程没给表起别名。
方案二:明确列出所有列(更推荐的最佳实践)
虽然写起来麻烦一点,但明确列名的方式最清晰,也完全避免了歧义,同样不需要表别名:
SELECT id, -- 主键列,两表数据一致,只写一次即可 table1.column_a, table1.column_b, table1.timestamp AS timestamp_t1, table2.column_c, table2.column_d, table2.timestamp AS timestamp_t2 FROM table1 JOIN table2 ON table1.id = table2.id;
这种方式不仅不会出现列冲突,还能让阅读代码的人一眼明白要返回哪些数据,维护性更强。
内容的提问来源于stack exchange,提问作者Ari7
相关产品推荐
相关产品推荐

