必须明白的sql知识

一,两表外连接查询

现有两个表A,B内容如下

mysql> select * from A;
+------+------+
| id   | Col1 |
+------+------+
|    1 | AA   |
|    2 | BB   |
|    3 | CC   |
+------+------+
3 rows in set (0.00 sec)
mysql> select * from B;
+------+------+
| id   | Col2 |
+------+------+
|    2 | DD   |
|    3 | EE   |
|    4 | FF   |
+------+------+
3 rows in set (0.01 sec)

1,A表和B表左连接

先将左表(A)数据查出,然后根据on后面的条件,将右表中凡是id与左表id相等的记录都查出来,与匹配的左表记录依次排成一行或多行,若无匹配的记录,则显示null。

mysql> select * from A left join B on A.id=B.id;
+------+------+------+------+
| id   | Col1 | id   | Col2 |
+------+------+------+------+
|    1 | AA   | NULL | NULL |
|    2 | BB   |    2 | DD   |
|    3 | CC   |    3 | EE   |
+------+------+------+------+
3 rows in set (0.00 sec)
mysql> select A.id ID ,A.Col1 C1 ,B.Col2 C2  from A left join B on A.id=B.id;
+------+------+------+
| ID   | C1   | C2   |
+------+------+------+
|    1 | AA   | NULL |
|    2 | BB   | DD   |
|    3 | CC   | EE   |
+------+------+------+
3 rows in set (0.00 sec)

下面的结果也是一样的



2,A表和B表右连接

先将右表(B)数据查出,然后根据on后面的条件,将左表中凡是id与右表id相等的记录都查出来,与匹配的左表记录依次排成一行或多行,若无匹配的记录,则显示null

mysql> select * from A right join B on A.id=B.id;
+------+------+------+------+
| id   | Col1 | id   | Col2 |
+------+------+------+------+
|    2 | BB   |    2 | DD   |
|    3 | CC   |    3 | EE   |
| NULL | NULL |    4 | FF   |
+------+------+------+------+
3 rows in set (0.07 sec)
mysql> select A.id ID ,A.Col1 C1 ,B.Col2 C2  from A right  join B on A.id=B.id;
+------+------+------+
| ID   | C1   | C2   |
+------+------+------+
|    2 | BB   | DD   |
|    3 | CC   | EE   |
| NULL | NULL | FF   |
+------+------+------+
3 rows in set (0.00 sec)


3,A表和B表交叉连接

没有用where子句的交叉连接将产生连接所涉及的笛卡尔积第一个表的行数乘以第二个表的行数等于笛卡尔积和结果集的大小。 Cross join 后面不能跟on 只能用where 。但是如果带返回或显示的是匹配的行数。不带条件where。

mysql> select *   from A cross join B  ;
+------+------+------+------+
| id   | Col1 | id   | Col2 |
+------+------+------+------+
|    1 | AA   |    2 | DD   |
|    2 | BB   |    2 | DD   |
|    3 | CC   |    2 | DD   |
|    1 | AA   |    3 | EE   |
|    2 | BB   |    3 | EE   |
|    3 | CC   |    3 | EE   |
|    1 | AA   |    4 | FF   |
|    2 | BB   |    4 | FF   |
|    3 | CC   |    4 | FF   |
+------+------+------+------+
9 rows in set (0.00 sec)
mysql> select A.id ID,A.Col1 C1,B.Col2 C2  from A cross join B  where A.id=B.id ;
+------+------+------+
| ID   | C1   | C2   |
+------+------+------+
|    2 | BB   | DD   |
|    3 | CC   | EE   |
+------+------+------+
2 rows in set (0.01 sec)

这里还有一种交叉连接表示方法

mysql> select * from A,B ;
+------+------+------+------+
| id   | Col1 | id   | Col2 |
+------+------+------+------+
|    1 | AA   |    2 | DD   |
|    2 | BB   |    2 | DD   |
|    3 | CC   |    2 | DD   |
|    1 | AA   |    3 | EE   |
|    2 | BB   |    3 | EE   |
|    3 | CC   |    3 | EE   |
|    1 | AA   |    4 | FF   |
|    2 | BB   |    4 | FF   |
|    3 | CC   |    4 | FF   |
+------+------+------+------+
9 rows in set (0.02 sec)
mysql> select A.id ID,A.Col1 C1,B.Col2 C2  from A , B  where A.id=B.id ;
+------+------+------+
| ID   | C1   | C2   |
+------+------+------+
|    2 | BB   | DD   |
|    3 | CC   | EE   |
+------+------+------+
2 rows in set (0.00 sec)


4,A表和B表完整外部连接查询(mysql 目前不支持)

select * from A full join B on  A.id=B.id
+------+------+------+
| ID   | C1   | C2   |
+------+------+------+
|    1 | AA   |      |
|    2 | BB   | DD   |
|    3 | CC   | EE   |
|    4 |      | FF   |
+------+------+------+


二,group by if count sum

group by 将查询的结果按列或者多列的值分组,值相等的为一组

if if(表达式,value1,value2) 表达式成立时值是value1 否则是value2

count 计数

sum 求和

某表ps内容如下

mysql> select * from ps;
+------------+------+
| RQ         | SF   |
+------------+------+
| 2005-05-09 | s    |
| 2005-05-09 | s    |
| 2005-05-09 | f    |
| 2005-05-09 | f    |
| 2005-05-10 | s    |
| 2005-05-10 | f    |
| 2005-05-10 | f    |
+------------+------+
7 rows in set (0.00 sec)

希望求到如下结果

    RQ          s        f
| 2005-05-09 |  2    |   2    |
| 2005-05-10 |  1    |   2    |
mysql>  select  RQ,sum(if(SF="s",1,0)) s ,sum(if(SF="f",1,0)) f from ps group by RQ;
+------------+------+------+
| RQ         | s    | f    |
+------------+------+------+
| 2005-05-09 |    2 |    2 |
| 2005-05-10 |    1 |    2 |
+------------+------+------+
2 rows in set (0.00 sec)

sum(if(SF="s",1,0)) 可以求得s的出现次数