对于SQL的Join,在学习起来可能是比较乱的。我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚。Coding Horror上有一篇文章,通过文氏图 Venn diagrams 解释了SQL的Join。我觉得清楚易懂,转过来。
对于SQL的Join,在学习起来可能是比较乱的。我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚。Coding Horror上有一篇文章,通过文氏图 Venn diagrams 解释了SQL的Join。我觉得清楚易懂,转过来。
假设我们有两张表。Table A 是左边的表。Table B 是右边的表。其各有四条记录,其中有两条记录name是相同的,如下所示:让我们看看不同JOIN的不同。
A表 |
|
id | name |
1 | Pirate |
2 | Monkey |
3 | Ninja |
4 | Spaghetti |
B表 |
|
id | name |
1 | Rutabaga |
2 | Pirate |
3 | Darth Vade |
4 | Ninja |
1. INNER JOIN
SELECT * FROM TableA INNER JOIN TableB ON TableA.name = TableB.name
结果集 |
|
|
|
(TableA.) |
| (TableB.) |
|
id | name | id | name |
1 | Pirate | 2 | Pirate |
3 | Ninja | 4 | Ninja |
Inner join 产生的结果集中,是A和B的交集。
2. FULL [OUTER] JOIN
(1)
SELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.name = TableB.name
结果集 |
|
|
|
(TableA.) |
| (TableB.) |
|
id | name | id | name |
1 | Pirate | 2 | Pirate |
2 | Monkey | null | null |
3 | Ninja | 4 | Ninja |
4 | Spaghetti | null | null |
null | null | 1 | Rutabaga |
null | null | 3 | Darth Vade |
Full outer join 产生A和B的并集。但是需要注意的是,对于没有匹配的记录,则会以null做为值。
可以使用IFNULL判断。
(2)
SELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.name = TableB.name
WHERE TableA.id IS null OR TableB.id IS null
结果集 |
|
|
|
(TableA.) |
| (TableB.) |
|
id | name | id | name |
2 | Monkey | null | null |
4 | Spaghetti | null | null |
null | null | 1 | Rutabaga |
null | null | 3 | Darth Vade |
产生A表和B表没有交集的数据集。
3. LEFT [OUTER] JOIN
(1) SELECT * FROM TableA LEFT OUTER JOIN TableB ON TableA.name = TableB.name
结果集 |
|
|
|
(TableA.) |
| (TableB.) |
|
id | name | id | name |
1 | Pirate | 2 | Pirate |
2 | Monkey | null | null |
3 | Ninja | 4 | Ninja |
4 | Spaghetti | null | null |
Left outer join 产生表A的完全集,而B表中匹配的则有值,没有匹配的则以null值取代。
(2)
SELECT * FROM TableA LEFT OUTER JOIN TableB ON TableA.name = TableB.name WHERE TableB.id IS null
结果集 |
|
|
|
(TableA.) |
| (TableB.) |
|
id | name | id | name |
2 | Monkey | null | null |
4 | Spaghetti | null | null |
产生在A表中有而在B表中没有的集合。
4. RIGHT [OUTER] JOIN
RIGHT OUTER JOIN 是后面的表为基础,与LEFT OUTER JOIN用法类似。这里不介绍了。
5. UNION 与 UNION ALL
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。UNION 只选取记录,而UNION ALL会列出所有记录。
(1) SELECT name FROM TableA UNION SELECT name FROM TableB
新结果集 |
name |
Pirate |
Monkey |
Ninja |
Spaghetti |
Rutabaga |
Darth Vade |
选取不同值
(2) SELECT name FROM TableA UNION ALL SELECT name FROM TableB
新结果集 |
name |
Pirate |
Monkey |
Ninja |
Spaghetti |
Rutabaga |
Pirate |
Darth Vade |
Ninja |
全部列出来
(3) 注意:
SELECT * FROM TableA UNION SELECT * FROM TableB
新结果集 |
|
id | name |
1 | Pirate |
2 | Monkey |
3 | Ninja |
4 | Spaghetti |
1 | Rutabaga |
2 | Pirate |
3 | Darth Vade |
4 | Ninja |
由于 id 1 Pirate 与 id 2 Pirate 并不相同,不合并
还需要注册的是我们还有一个是"交差集" cross join, 这种Join没有办法用文式图表示,因为其就是把表A和表B的数据进行一个N*M的组合,即笛卡尔积。表达式如下:
SELECT * FROM TableA CROSS JOIN TableB
这个笛卡尔乘积会产生 4 x 4 = 16 条记录,一般来说,我们很少用到这个语法。但是我们得小心,如果不是使用嵌套的select语句,一般系统都会产生笛卡尔乘积然再做过滤。这是对于性能来说是非常危险的,尤其是表很大的时候。
还需要注册的是我们还有一个是“交差集” cross join, 这种Join没有办法用文式图表示,因为其就是把表A和表B的数据进行一个N*M的组合,即笛卡尔积。表达式如下:
还需要注册的是我们还有一个是"交差集" cross join, 这种Join没有办法用文式图表示,因为其就是把表A和表B的数据进行一个N*M的组合,即笛卡尔积。表达式如下:
SELECT * FROM TableA CROSS JOIN TableB
这个笛卡尔乘积会产生 4 x 4 = 16 条记录,一般来说,我们很少用到这个语法。但是我们得小心,如果不是使用嵌套的select语句,一般系统都会产生笛卡尔乘积然再做过滤。这是对于性能来说是非常危险的,尤其是表很大的时候。
《Linux命令行与shell脚本编程大全》 第三章 学习笔记
第三章:基本的bash shell命令
bash程序使用命令行参数来修改所启动shell的类型
参数 | 描述 |
-c string | 从string中读取命令并处理他们 |
-r | 启动限制性shell,限制用户在默认目录下活动 |
-i | 启动交互性shell,允许用户输入 |
-s | 从标准输入读取命令 |
环境变量PS1、PS2
PS1:控制默认命令行提示符格式
PS2:控制后续命令行提示符格式
bash shell提示符字符串中使用的特殊字符
字符 | 描述 |
\a | 报警字符 |
\d | “日 月 年”格式显示的日期 |
\e | ASCII转义字符 |
\h | 本地主机名 |
\H | 完全限定名(FQDN) |
\j | shell当前管理的任务数 |
\l | shell的终端设备名中的基名 |
\n | ASCII换行符 |
\r | ASCII回车符 |
\s | shell的名称 |
\t | 24小时制HH:MM:SS格式的当前时间 |
\T | 12小时制HH:MM:SS格式的当前时间 |
\@ | 12小时制am/pm格式的当前时间 |
\u | 当前用户的用户名 |
\v | bash shell的版本 |
\V | bash shell的发行版本 |
\w | 当前工作目录 |
\W | 当前工作目录的基名 |
\! | 这个命令在bash shell历史记录中的位置 |
\# | 这个命令在当前命令行的位置 |
\$ | 普通用户下的美元符,root用户下的井号 |
\nnn | 与8进制nnn对应的字符 |
\\ | 反斜线 |
\[ | 开始一个控制字符序列 |
\] | 结束一个控制字符序列 |
Linux文件系统
Linux PC上安装的第一块硬盘为根驱动器。根驱动器包含了虚拟目录的核心,其他目录都是从那里开始创建的
挂载点(mount point)是虚拟目录中用于分配额外存储设备的目录
ls
(其余参数及例子见#2 )
单字母 | 全字 | 描述 |
-A | --almost-all | 不要输出“.”和“..”文件 |
--author | 作者 | |
-b | --escape | 输出不可打印字符的8进制值 |
--block-size=size | 按size字节大小的块来计算块大小(块数) | |
-B | --ignore-backups | 不要列出名称中包含波浪线(~)的条目(波浪线用来表示备份的副本) |
-F | --classify | 给条目追加文件类型标识符 |
--file-type | 只在部分文件类型(非可执行文件)后追加文件类型标识符 | |
--format=word | 将输出格式化成across(交叉)、commas(逗号)、horizontal(水平)、long(长)、single-column(单列)、verbose(详细)或vertical(垂直) | |
--group-directories-first | 在文件之前列出所有目录 | |
-G | --no-group | 长列表输出格式下,不要显示组名(in a long listing, don't print group names) |
-h | --human-readable | 打印大小 |
--si | 和-h相同,但进制为1000 | |
-i | --inode | 显示每个文件的索引值(inode)(见#1 ) |
-L | --dereference | 对于链接文件,显示原文件信息 |
-n | --numeric-uid-gid | 显示数字类型的userid和groupid以替代名字 |
-o | 长列表输出格式下,不要显示组信息(like -l, but do not list group information) | |
-S | --sort=size | 按文件大小排序输出 |
-U | --sort=none | 不要将输出排序 |
-v | --sort=version | 按文本版本排序 |
-x | 按行而非列输出条目 | |
-X | --sort=extension | 按文件扩展名排序输出 |
创建文件(touch) (见#1 )
复制文件(cp) (见#1 )
cp命令参数
参数 | 描述 |
-a | 归档文件,并保留他们现有的属性 |
-b | 创建已存在目标文件的备份,而非覆盖它 |
-d | 保留 |
-f | 强制覆盖已存在的目标文件,不提示 |
-i | 在覆盖目标文件之前提示 |
-l | 创建文件链接而非复制文件 |
-p | 如果可能,保留文件属性 |
-r | 递归复制文件 |
-R | 递归复制目录 |
-s | 创建一个符号链接而非复制文件 |
-S | 覆盖默认的备份文件的后缀(默认为~) |
-u | 仅在源文件比目标文件新的情况下复制 |
-v | 详细模式,解释到底发生了什么 |
-x | 仅限于当前文件系统的复制 |
(见#1 )
链接文件 (见#1 )
硬链接会创建一个独立的文件,其中包含源文件的信息以及位置。引用硬链接文件等同于引用了源文件
只能在同种存储媒体上的文件之间建立硬链接。不能在不同挂载点下的文件之间创建硬链接,但是可以创建软链接
如果用cp复制一个链接到另一个源文件的文件,那么复制的是源文件的另一个副本,而不是链接文件
可以创建一个指向源文件的新链接,而不用复制链接文件
可以创建指向同一文件的多个链接,但不要创建指向其他符号链接文件的多个符号链接(这样会生成一个链接文件链,容易混淆、断掉)
删除文件(rm) (见#1 )
当删除所有此文件的硬链接时,此文件才会被删除
删除软链接指向的文件后,软链接指向无效的文件
创建目录(mkdir) (见#2 )
删除目录(rmdir) (见#2 )
查看文件统计信息(stat) (见#1 )
查看文件类型(file) (见#2 )
查看整个文件(cat、more、less) (见#16 ,#21 )
cat -T:制表符用^I代替
more
语法
more [-s ] [file ...]
-s(squeeze,挤压) :将多个空白行压缩成一个
基本命令 | ||||||||||||||||||||||||||
| ||||||||||||||||||||||||||
高级命令 | ||||||||||||||||||||||||||
|
查看部分文件(head、tail) (见#16 )