MySQL 8常用SQL之SELECT

  SELECT语法:

SELECT
    [ALL | DISTINCT | DISTINCTROW ]
    [HIGH_PRIORITY]
    [STRAIGHT_JOIN]
    [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
    [SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr [, select_expr] ...
    [into_option]
    [FROM table_references
      [PARTITION partition_list]]
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
    [HAVING where_condition]
    [WINDOW window_name AS (window_spec)
        [, window_name AS (window_spec)] ...]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [into_option]
    [FOR {UPDATE | SHARE}
        [OF tbl_name [, tbl_name] ...]
        [NOWAIT | SKIP LOCKED]
      | LOCK IN SHARE MODE]
    [into_option]

into_option: {
    INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        export_options
  | INTO DUMPFILE 'file_name'
  | INTO var_name [, var_name] ...
}

  实际工作中,来看看几个SELECT,示例1,统计某项目在活动期间的一些指标:

mysql> select count(*)祝福总数,min(wid)起始号码,max(wid)截止号码 
	from tb_bllottery_msg a 
	where not EXISTS
	( select 1 from tb_lottery_prize b 
	where a.wid=b.wid) and FROM_UNIXTIME(a.insert_time,'%Y-%m-%d %H:%i:%S')<'2019-09-18 00:00:00';

  默认情况下,UNION结果集删除重复的行,与UNION DISTINCT具有相同的效果,UNION ALL不删除重复行,并且结果包括所有SELECT语句中的所有匹配行。

  示例2,通过UNION、UNION ALL来获取某活动的获奖信息表,这里SELECT字段列包括常量列,有not EXISTS、ORDER BY、LIMIT以及SUBSTRING、IFNULL函数的使用:

mysql> (select openid,'wish','4','1','Iphone X',wid,nickname,sex,headimgurl,country,city,province,unionid,
	privilege,nicknameutf8 from tb_bllottery_msg a where not EXISTS
	( select 1 from tb_lottery_prize b where a.wid=b.wid) and SUBSTRING(a.wid,-4)=0128 and
	 a.wid<=156856 order by a.wid limit 0,3)
	union
	(select openid,'wish','5','2','戴森吹风机',wid,nickname,sex,headimgurl,country,city,province,unionid,
	privilege,nicknameutf8 from tb_bllottery_msg a where
	not EXISTS ( select 1 from tb_lottery_prize b where a.wid=b.wid) and SUBSTRING(a.wid,-3)=128 
	and a.wid<=156856 order by a.wid limit 0,30)
	union
	(select openid,'wish','6','3','电饭煲',wid,nickname,sex,headimgurl,country,city,province,unionid,
	privilege,nicknameutf8 from tb_bllottery_msg a where
	not EXISTS ( select 1 from tb_lottery_prize b where a.wid=b.wid) and SUBSTRING(a.wid,-2)=28
	and a.wid<=156856 order by a.wid limit 0,300);

################################################################

mysql> SELECT mr.openid,IFNULL(p.gamedesc,'拼图')gamedesc,IFNULL(p.gift,'未中奖')gift,mr.playdate FROM tb_ac_record mr 
	LEFT JOIN tb_ac_prize p 
	ON(mr.openid=p.openid and mr.playdate=p.prizedate and p.gametype='map') WHERE mr.openid='200282510' 
	UNION ALL
	SELECT qr.openid,IFNULL(p.gamedesc,'答题')gamedesc,IFNULL(p.gift,'未中奖')gift,qr.playdate FROM tb_ac_record qr 
	LEFT JOIN tb_ac_prize p 
	ON(qr.openid=p.openid and qr.playdate=p.prizedate and p.gametype='qa') WHERE qr.openid='200282510'
	ORDER BY gamedesc,playdate;

  示例3,SELECT多表左连接:

mysql> select o.cnsino,o.npsqueryno,oi.title,oi.prcode,oi.payprice,ra.refundamount 
	from tb_order_refundapply ra 
	left join tb_order_orderitem oi on ra.orderitemid = oi.oiid
	left join tb_order_orderinfo o on o.orderid = oi.orderid 
	where to_char(ra.createtime,'yyyyMMdd') >'20180800' 
	and to_char(ra.createtime,'yyyyMMdd') < '20190901'
	and ra.status >0;

  示例4,SELECT分组排序:

mysql> select a.cid,c.cName,a.log,a.logDate,a.createDate 
	from (select f.cId,f.log,f.createDate,f.logDate
	 from tb_kh_followlog f order by f.logDate desc
	)a, tb_kh_customer c where c.Id=a.cid GROUP BY a.cId;

1. SELECT INTO

SELECT … INTO是SELECT将查询结果存储在变量或将其写入文件:

  • SELECT … INTO var_list:选择列值并将其存储到变量中;
  • SELECT … INTO OUTFILE:将选定的行写入文件,可以指定列和行终止符以产生特定的输出格式;
  • SELECT … INTO DUMPFILE:将单行写入文件而没有任何格式。
      示例:
mysql> SELECT id, data INTO @x, @y FROM test.t1 LIMIT 1;

mysql> select p.nickname,concat(u.provinceName,u.cityName,u.addr),u.mobile,p.prizedesc,p.gift 
	from tb_ac_prize p,tb_ac_userinfo u 
	where p.openid=u.openid order by p.prizedesc 
	INTO OUTFILE '/home/mysql/export/jjb20191227.txt';
		
mysql> SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM test_table;

  如果使用INTO DUMPFILE而不是INTO OUTFILE转储数据,则MySQL仅将一行写入文件,没有任何列或行终止符,也没有执行任何转义处理,这对于转储BLOB类型数据很有用;另外,如果表包含多个行,要使用INTO DUMPFILE需使用LIMIT 1将输出限制为单行。

2. JOIN

  MySQL环境下,JOIN,CROSS JOIN和INNER JOIN是等效的(它们可以彼此替换),但在标准SQL中,它们的使用存在差异,JOIN、INNER JOIN与ON子句联合使用,CROSS JOIN是笛卡尔连接,不使用WHERE子句时,结果集是两个关联表的行的乘积。

mysql> select * from t1;
+-----+-----------+
| tid | tname     |
+-----+-----------+
|   1 | 钱锺书    |
|   2 | 杨绛      |
|   3 | 路遥      |
|   6 | 鲁迅      |
|   8 | 三毛      |
+-----+-----------+
5 rows in set (0.00 sec)

mysql> select * from t2;
+-----+-----+--------------------+
| bid | tid | bookname           |
+-----+-----+--------------------+
|   1 |   1 | 围城               |
|   2 |   1 | 写在人生边上       |
|   3 |   2 | 我们仨             |
|   4 |   3 | 平凡的世界         |
|   5 |   3 | 人生               |
|   6 |   4 | 挪威的森林         |
|   7 |   5 | 家书               |
+-----+-----+--------------------+
7 rows in set (0.00 sec)
mysql> SELECT * FROM t1 INNER JOIN t2 ON t1.tid = t2.tid;
+-----+-----------+-----+-----+--------------------+
| tid | tname     | bid | tid | bookname           |
+-----+-----------+-----+-----+--------------------+
|   1 | 钱锺书    |   1 |   1 | 围城               |
|   1 | 钱锺书    |   2 |   1 | 写在人生边上       |
|   2 | 杨绛      |   3 |   2 | 我们仨             |
|   3 | 路遥      |   4 |   3 | 平凡的世界         |
|   3 | 路遥      |   5 |   3 | 人生               |
+-----+-----------+-----+-----+--------------------+
5 rows in set (0.00 sec)

mysql> SELECT * FROM t1 JOIN t2 ON t1.tid = t2.tid;
+-----+-----------+-----+-----+--------------------+
| tid | tname     | bid | tid | bookname           |
+-----+-----------+-----+-----+--------------------+
|   1 | 钱锺书    |   1 |   1 | 围城               |
|   1 | 钱锺书    |   2 |   1 | 写在人生边上       |
|   2 | 杨绛      |   3 |   2 | 我们仨             |
|   3 | 路遥      |   4 |   3 | 平凡的世界         |
|   3 | 路遥      |   5 |   3 | 人生               |
+-----+-----------+-----+-----+--------------------+
5 rows in set (0.00 sec)

mysql> SELECT * FROM t1 CROSS JOIN t2 ON t1.tid = t2.tid;
+-----+-----------+-----+-----+--------------------+
| tid | tname     | bid | tid | bookname           |
+-----+-----------+-----+-----+--------------------+
|   1 | 钱锺书    |   1 |   1 | 围城               |
|   1 | 钱锺书    |   2 |   1 | 写在人生边上       |
|   2 | 杨绛      |   3 |   2 | 我们仨             |
|   3 | 路遥      |   4 |   3 | 平凡的世界         |
|   3 | 路遥      |   5 |   3 | 人生               |
+-----+-----------+-----+-----+--------------------+
5 rows in set (0.00 sec)

  两个表间NATURAL [LEFT] JOIN语义上等效于一个INNER JOIN或一个LEFT JOIN带有USING条件;RIGHT JOIN类似于 LEFT JOIN,为了使代码可跨数据库移植,建议使用LEFT JOIN代替RIGHT JOIN。

mysql> SELECT * FROM t1 NATURAL LEFT JOIN t2;
+-----+-----------+------+--------------------+
| tid | tname     | bid  | bookname           |
+-----+-----------+------+--------------------+
|   1 | 钱锺书    |    2 | 写在人生边上       |
|   1 | 钱锺书    |    1 | 围城               |
|   2 | 杨绛      |    3 | 我们仨             |
|   3 | 路遥      |    5 | 人生               |
|   3 | 路遥      |    4 | 平凡的世界         |
|   6 | 鲁迅      | NULL | NULL               |
|   8 | 三毛      | NULL | NULL               |
+-----+-----------+------+--------------------+
7 rows in set (0.00 sec)

mysql> SELECT * FROM t1 LEFT JOIN t2 ON t1.tid = t2.tid;
+-----+-----------+------+------+--------------------+
| tid | tname     | bid  | tid  | bookname           |
+-----+-----------+------+------+--------------------+
|   1 | 钱锺书    |    2 |    1 | 写在人生边上       |
|   1 | 钱锺书    |    1 |    1 | 围城               |
|   2 | 杨绛      |    3 |    2 | 我们仨             |
|   3 | 路遥      |    5 |    3 | 人生               |
|   3 | 路遥      |    4 |    3 | 平凡的世界         |
|   6 | 鲁迅      | NULL | NULL | NULL               |
|   8 | 三毛      | NULL | NULL | NULL               |
+-----+-----------+------+------+--------------------+
7 rows in set (0.00 sec)

mysql> SELECT * FROM t1 RIGHT JOIN t2 ON t1.tid = t2.tid;
+------+-----------+-----+-----+--------------------+
| tid  | tname     | bid | tid | bookname           |
+------+-----------+-----+-----+--------------------+
|    1 | 钱锺书    |   1 |   1 | 围城               |
|    1 | 钱锺书    |   2 |   1 | 写在人生边上       |
|    2 | 杨绛      |   3 |   2 | 我们仨             |
|    3 | 路遥      |   4 |   3 | 平凡的世界         |
|    3 | 路遥      |   5 |   3 | 人生               |
| NULL | NULL      |   6 |   4 | 挪威的森林         |
| NULL | NULL      |   7 |   5 | 家书               |
+------+-----------+-----+-----+--------------------+
7 rows in set (0.00 sec)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章