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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章