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)