首页 > 解决方案 > 在这个 sql Fifddle 示例中,“a”在哪里。字符不断来自?它根本不在桌子上

问题描述

CREATE TABLE IF NOT EXISTS `docs` (
  `id` int(6) unsigned NOT NULL,
  `rev` int(3) unsigned NOT NULL,
  `content` varchar(200) NOT NULL,
  PRIMARY KEY (`id`,`rev`)
) DEFAULT CHARSET=utf8;
INSERT INTO `docs` (`id`, `rev`, `content`) VALUES
  ('1', '1', 'The earth is flat'),
  ('2', '1', 'One hundred angels can dance on the head of a pin'),
  ('1', '2', 'The earth is flat and rests on a bull\'s horn'),
  ('1', '3', 'The earth is like a ball.');

/////////////////////////////////////////////////////////

然后是实际的查询:

SELECT a.id, a.rev, a.content
FROM `docs` a
INNER JOIN (
    SELECT id, MAX(rev) rev
    FROM `docs`
    GROUP BY id
) b ON a.id = b.id AND a.rev = b.rev;


SELECT a.*
FROM `docs` a
LEFT OUTER JOIN `docs` b
    ON a.id = b.id AND a.rev < b.rev
WHERE b.id IS NULL;

a是某种占位符吗?
在哪里可以找到对此的英文解释?
我希望有人会引导我们完成这个并使其易于理解。谢谢!

标签: mysql

解决方案


"a" 是表别名

选择 a.id、a.rev、a.content
FROM `docs` a     # HERE,在这一行,表格被赋予了一个别名
内部联接 (
    选择 id, MAX(rev) rev
    来自“文档”
    按 ID 分组
) b ON a.id = b.id AND a.rev = b.rev;

该别名在 from 子句中的表名之后立即声明(如上所示)。

别名用于缩写和/或澄清查询。有几个地方可以声明别名,例如

#table alias
from tablex as x

#derived table (subquery) alias
select d.* from (select * from t where col1 = 'xyz') as d

#column alias
select col1 as xyz
from tablex as x

请注意,上面看到的“as”在大多数数据库中是可选的,Oracle 在声明表或子查询别名时不允许使用“as”。

自加入

当您将表连接到自身时,表别名很重要

select
     t1.id as t1_id
   , t2.id as t2_id
from tablex as t1
inner join tablex as t2 on t1.fk = t2.id

如果没有这些别名 t1 和 t2,查询根本无法工作。


编辑

遗憾的是,我们经常看到别名是在查询中“按顺序”定义的。在您的示例中,第一个是“a”,第二个是“b”,依此类推。

那是不好的做法。使用别名的一种更有意义的方式是使用表名中每个单词的“首字母”,或者为子查询分配一些含义。

在示例中,我建议使用“d”(用于文档)和“mr”(用于 max(rev))

SELECT d.id, d.rev, d.content, mr.rev
FROM `docs` as d 
INNER JOIN (
    SELECT id, MAX(rev) rev
    FROM `docs`
    GROUP BY id
) as mr ON d.id = mr.id AND d.rev = mr.rev;

推荐阅读