join语句的基本使用
SQL(MySQL) JOIN 用于根据两个或多个表中的字段之间的关系,从这些表中得到数据。
JOIN 通常与 ON 关键字搭配使用,基本语法如下:
... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON conditiona
table1 通常称为左表,table2 称为右表。ON 关键字用于设定匹配条件,用于限定在结果集合中想要哪些行。如果需要指定其他条件,后面可以加上 WHERE 条件 或者 LIMIT 以限制记录返回数目等。
下面以最常见的两表连接来说明 MySQL JOIN 的用法,关于多表 JOIN 请参见《MySQL JOIN 多表》。
MySQL JOIN 分类
JOIN 按照功能大致分为如下三类:
- INNER JOIN(内连接):取得两个表中存在连接匹配关系的记录。
- LEFT JOIN(左连接):取得左表(table1)完全记录,即是右表(table2)并无对应匹配记录。
- RIGHT JOIN(右连接):与 LEFT JOIN 相反,取得右表(table2)完全记录,即是左表(table1)并无匹配对应记录。
关于 MySQL FULL JOIN 全连接
MySQL 没有提供 SQL 标准中的 FULL JOIN(全连接):两个表记录都取出,而不管彼此是否有对应记录。要解决此问题,可以使用 UNION 关键字来合并 LEFT JOIN 与 RIGHT JOIN,达到模拟 FULL JOIN 的目的。
MySQL INNER JOIN
INNER JOIN 用于取得两个表中存在连接匹配关系的记录。下面是两个原始数据表:
article 表中文章的所属用户是通过 uid 这个字段与 user 表关联起来的。通过观察数据不难发现,对于 uid=3 的用户,并没有发表任何文章;而文章中 aid=4 却无法在 uid 表中找到对应记录(可能是该用户被删除而其所属的文章却被保留了下来)。
我们列出所用文章与用户一一对应的数据。
SELECT … INNER JOIN … ON 语句如下:
SELECT article.aid,article.title,user.username FROM article INNER JOIN user ON article.uid = user.uid
返回查询结果如下:
对于 INNER JOIN,等同与下面的 SQL 语句:
SELECT article.aid,article.title,user.username FROM article,user WHERE article.uid = user.uid
CROSS JOIN
CROSS JOIN 即交叉连接,在不指定 ON 条件下:
SELECT article.aid,article.title,user.username FROM article CROSS JOIN user
得到的结果是被连接的两个数据表的乘积,即笛卡尔积。
实际上,在 MySQL 中(仅限于 MySQL) CROSS JOIN 与 INNER JOIN 的表现是一样的,在不指定 ON 条件得到的结果都是笛卡尔积,反之取得两个表完全匹配的结果。
INNER JOIN 与 CROSS JOIN 可以省略 INNER 或 CROSS 关键字,因此下面的 SQL 效果是一样的:
平板视图打印?
... FROM table1 INNER JOIN table2 ... FROM table1 CROSS JOIN table2 ... FROM table1 JOIN table2
join的字段字符集编码对性能的影响
先来看一下示例代码:
建utf-8编码的表 t1:
CREATE TABLE IF NOT EXISTS `t1` ( `name` varchar(50) NOT NULL DEFAULT '', KEY `name` (`name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
随便插入些数据,数量大一点,后面实验结果更清晰,偷个懒,构造随机字符串插入语句
insert into t1(name) select concat( char(round((rand())*25)+97), char(round((rand())*25)+65), char(round((rand())*25)+65), char(round((rand())*25)+97), char(round((rand())*25)+65), char(round((rand())*25)+65), char(round((rand())*25)+97), char(round((rand())*25)+65) )
每次执行插入一条记录,用你熟悉的脚本(python,php,shell等都行)写个循环,执行一万次以上。
将该表复制成一个新表t2,删除一部分数据,1000条左右即可。(推荐使用phpMyAdmin)
再将t2复制为t3,并将字段改为gb2312编码。
使用一个left join语句,写一个语句,查出t2/t3比t1少了哪些记录。
语句很简单,如下:
SELECT SQL_NO_CACHE t1.name, t2.name FROM t1 LEFT JOIN t2 ON t1.name = t2.name WHERE t2.name IS NULL LIMIT 0 , 30
注意加入 SQL_NO_CACHE ,禁用mysql缓存。
先看编码一致的t2表,phpMyAdmin里执行结果:
显示行 0 - 29 ( 1,129 总计, 查询花费 0.0010 秒)
平均耗时大概为0.0010秒
SELECT SQL_NO_CACHE t1.name, t3.name FROM t1 LEFT JOIN t3 ON t1.name = t3.name WHERE t2.name IS NULL LIMIT 0 , 30
phpMyAdmin执行结果:
显示行 0 - 29 ( 30 总计, 查询花费 0.1871 秒)
差两个数量级!
查询语句解释:
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]