Java养成计划----学习打卡第六十九天
内容导航
Java(打卡第六十九天)
MySQL合并UNION,LIMIT限制,分页 ,DDL创建表
> 昨天已经分析过多表查询和子查询了,再来分析一下SELECT子查询的缺点
其实SELECT子查询就和多表查询是相似的,之所以执行,就是FROM a,a表中的数据都可以用,所以
所以就可以SELECT 加上一个WHERE条件过滤
SELECT
> f.fruits_name,(SELECT c.language FROM culture c WHERE c.location = f.fruits_origin) AS language
>FROM
>fruits f
这里的缺点就是如果数据的行数不匹配就会报错
mysql> SELECT
-> f.fruits_name,(SELECT c.language FROM culture c) AS language
-> FROM
-> fruits f;
ERROR 1242 (21000): Subquery returns more than 1 row
Subquery returns more than 1 row
mysql> SELECT
-> c.language
-> FROM
-> culture c;
+----------+
| language |
+----------+
| 四川话 |
| 山东话 |
| 海南话 |
+----------+
报错就是子查询返回了多余一条结果,这里可以看出返回了3条结果
原因是什么呢?
- 其实是因为SELECT是一行一行选取结果,这里没有WHERE过滤,就是按行来处理的,这里比如先查找出第一行的name,之后就是返回的是子查询的结果,先查询的子查询【所以这里也只能是一条结果匹配】,所以一般条件下必须要加上限制过滤,类似于表连接
所以SELECT子查询使用很少
UNION 合并查询结果集
在union之前我们已经提到过OR和IN,这也类似于并集,但是还是提到UNION,当然是因为UNION的效率高
按照之前的两种写法来查询城市名称为Kabul和Herat的记录
mysql> SELECT
-> *
-> FROM
-> city
-> WHERE
-> Name = 'Kabul' OR Name = 'Herat';
+----+-------+-------------+----------+------------+
| ID | Name | CountryCode | District | Population |
+----+-------+-------------+----------+------------+
| 1 | Kabul | AFG | Kabol | 1780000 |
| 3 | Herat | AFG | Herat | 186800 |
+----+-------+-------------+----------+------------+
2 rows in set (0.01 sec)
mysql> SELECT
-> *
-> FROM
-> city
-> WHERE
-> Name IN('Kabul','Herat');
+----+-------+-------------+----------+------------+
| ID | Name | CountryCode | District | Population |
+----+-------+-------------+----------+------------+
| 1 | Kabul | AFG | Kabol | 1780000 |
| 3 | Herat | AFG | Herat | 186800 |
+----+-------+-------------+----------+------------+
2 rows in set (0.00 sec)
其实可以使用Union来合并查询 结果
1.查询城市名称为Kabul的城市
SELECT * FROM city WHERE Name = 'kabul';
2.查询城市名称为Herat的城市
SELECT * FROM city WHERE Name = 'Herat';
3.合并UNION
mysql> SELECT * FROM city WHERE Name = 'kabul'
-> UNION
-> SELECT * FROM city WHERE Name = 'Herat';
+----+-------+-------------+----------+------------+
| ID | Name | CountryCode | District | Population |
+----+-------+-------------+----------+------------+
| 1 | Kabul | AFG | Kabol | 1780000 |
| 3 | Herat | AFG | Herat | 186800 |
+----+-------+-------------+----------+------------+
2 rows in set (0.01 sec)
对于表连接来说,每连接一次表,匹配次数满足笛卡尔积,次数成倍增长,但是UNION可以减少匹配次数,并且还可以将查询结果合并
这里可以简单分析一下连接的效率
加入a表连接b再连接c,多表查询
a表10条记录
b表10条记录
c表10条记录
那么就是JOIN JOIN 那么整个即使一个函数的映射,路径就是有10* 10* 10 = 1000次
- 如果使用UNION来查询
a表连接b表一个结果 10*10 = 100次
a表连接c表一个结果 10*10 = 100次
UNION合并 一共就是200 次,UNION就是将乘法变成了加法
UNION的使用注意事项
UNION的结果拼接可以看出是在进行简单的数据拼接,自上而下
- UNION在进行结果合并的时候,要求两个结果集的列数相同
如果不相同就会报错
- 在MySQL中可以将两种数据类型不同的结果合并,但是ORACLE中不可以,严格要求两者的数据类型相同
LIMIT startIndex length
limit的作用就是只是将查询结果的一部分取出来,通常使用在分页查询之中【可以达到一页只是显示固定数量的数据】
分页的作用是为了提高用户的体验,因为如果一次全部查出来,用户的体验就很差,可以一页一页翻页看,比如百度的搜索就是一页只显示10条记录
LIMIT限制,就像Stream中限制数据的显示【截断数据操作】,这里也是截断部分的查询记录
用法和Stream相似,比如这里查询
- 人口数量前5的城市?
mysql> SELECT
-> *
-> FROM
-> city
-> ORDER BY
-> Population DESC
-> LIMIT
-> 5;
+------+-----------------+-------------+--------------+------------+
| ID | Name | CountryCode | District | Population |
+------+-----------------+-------------+--------------+------------+
| 1024 | Mumbai (Bombay) | IND | Maharashtra | 10500000 |
| 2331 | Seoul | KOR | Seoul | 9981619 |
| 206 | S?o Paulo | BRA | S?o Paulo | 9968485 |
| 1890 | Shanghai | CHN | Shanghai | 9696300 |
| 939 | Jakarta | IDN | Jakarta Raya | 9604900 |
+------+-----------------+-------------+--------------+------------+
5 rows in set (0.01 sec)
这里的执行顺序是
先执行FROM语句,之后执行SELECT语句,之后执行ORDER BY语句,如果不加限制就直接输出,这个时候执行LIMIT语句,限制输出前5个
- LIMIT的完整用法
limit startIndex,length
LIMIT是在ORDER BY之后执行
所以上面的例子也可以写成LIMIT 0,5; 所以这里的关键就是下标从0开始,和之前的substr之流从1开始不同
省略0就是取前length个数据
比如完整的例题,取出city表中人口排名3到5名的人口的城市
//第3名就是第三个记录,下标也就是3-1 = 2;3到5名一共5-3+1 = 3条记录,length为3
mysql> SELECT
-> *
-> FROM
-> city
-> ORDER BY
-> Population DESC
-> LIMIT
-> 2,3;
+------+-----------+-------------+--------------+------------+
| ID | Name | CountryCode | District | Population |
+------+-----------+-------------+--------------+------------+
| 206 | S?o Paulo | BRA | S?o Paulo | 9968485 |
| 1890 | Shanghai | CHN | Shanghai | 9696300 |
| 939 | Jakarta | IDN | Jakarta Raya | 9604900 |
+------+-----------+-------------+--------------+------------+
3 rows in set (0.05 sec)
可以看出结果是正确的,(可以和上面的前5名对比)
分页 【使用LIMIT】
这里可以模拟一下分页,假设每页显示10条记录
第一页 LIMIT 0,10 相当也是左闭右开,所以每次的就是倍数 【这样可以保证不重复】
第二页 LIMIT 10,10
第三页 LIMIT 20,10
那么就可以推导出通用的公式
假设每页显示pagesize条记录
*那么第pageNo页 : LIMIT (pageNo - 1)pagesize,pagesize
所以如果实现翻页,就可以使用java来编写代码了
public void paging(int pageNo, int pageSize) {
//用户提交一个页码,以及煤业显示的记录条数
int startIndex = (pageNo -1)*pageSize;
String sql = "SELECT …… LIMIT" + startIndex +","+pageSize;
}
那么到此就将DQL data query language学完了,其实就是以SELECT为主
整个语句的格式
SELECT …… FROM …… WHERE …… GROUP BY …… HAVING …… ORDER BY …… LIMIT……
执行顺序就是将SELECT放到ORDER BY之前就可以了,HAVING的作用是第一次过滤不满意,分组之后可以再次过滤,比如删除平均值小于400000的数据。WHERE中就不方便直接删去
DDL data definition language
上面已经基本上覆盖了DQL语句,其实对数据库来说最重要的就是表中数据的查询,但是其他的语言还是要学会
DDL语句主要就是包括CREATE DROP ATLTER
首先就学习表的创建
CREATE 建表
CREATE比如创建数据库的格式为
CREATE DATABASE basename; //创建一个数据库名称为basename的数据库
CREATE创建表格的格式
CREATE TABLE table_name(col1 数据类型,col2 数据类型,col3 数据类型 ……);
和之前为了结构清晰分行来书写,这里也是
CREATE TABLE table_name(
col1 数据类型,
col2 数据类型,
…… //最后一行不需要逗号,因为后面是括号
);
建表的取名【表名和字段名都属于标识符】
- 表名 : 建议以t_或者tb1 _开始,可读性强,同时要求见名知意
- 字段名: 见名知意
mysql的数据类型
mysql中有很多数据类型,我们只需要掌握一些常见的数据类型即可
-
varchar 最长255
可变长度的字符串,比较常用,比较智能,节省空间,会根据实际的数据长度动态分配空间
比如定义数据类型时为VARCHAR(10),当传入数据为JACK,实际分配的空间只是4
那么需要动态分配空间就有问题来了,效率问题
- 优点 : 节省空间
- 缺点 : 需要动态分配空间,速度慢
-
char 最长255 中文只算一中长度
定长字符串,不管实际长度为多少,空间都是最开始分配的那么多,比如CHAR(10),当传入JACK时,空间还是10,后面的空间就是空
- 优点: 不需要动态分配空间,空间固定,速度快
- 缺点: 使用不当会造成空间的浪费
那我们该如何选择使用char或者varchar呢?
当字段的长度固定不变时,选择CHAR,比如性别字段,直接CHAR(1),比如姓名不定长,所以选择VARCHAR variable char 可变
-
int 最长11
数字中的整型,相当于java的int
-
bigint
数字中的长整形,等同于java中的long
-
float
单精度浮点型数据
-
double
双精度浮点型数据
-
date
短日期类型
-
datetime
长日期类型
-
clob
字符大对象
最多可以存储4G的字符串
比如: 存储一篇文章,存储一段简介,说明
超过255个字符都要使用字符大对象来存储
Character large object :CLOB
可以直接插入,其实就可以看为一个庞大的字符串
-
blog
二进制大对象
Binary Large Object
专门用来存储图片,声音,视频等流媒体数据
向BLOG类型字段中插入数据必须使用IO流,因为图片,声音和视频都有相应的IO
这里可以模拟选用这些数据类型,比如这里使用电影表
t_movie 电影表
编号 名字 描述信息 上映日期 时长 海报 类型
no(BIGINT) name(VARCHAR) describe(CLOB) playtime(DATA) time(DOUBLE) image(BLOB) type(CHAR)
比如这里创建一个学生表
学生表所包含的字段colum学号,姓名,性别,年龄,邮箱地址
CREATE TABLE t_student(
no INT,
name VARCHAR(32),
sex CHAR(1),
age INT(3), //这里只是建议长度,可以不写
email VARCHAR(255)
);
//实操一下
mysql> CREATE TABLE t_student(
-> no INT,
-> name VARCHAR(32),
-> sex CHAR(1),
-> age INT(3),
-> email VARCHAR(255)
-> );
Query OK, 0 rows affected, 1 warning (0.04 sec)
mysql> SHOW WARNINGS;
+---------+------+------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------------------------------------+
| Warning | 1681 | Integer display width is deprecated and will be removed in a future release. |
+---------+------+------------------------------------------------------------------------------+
1 row in set (0.00 sec)
删除表 DROP
删除表也是改变表的结构,输入DDL语言,删除表或者数据库的格式
DROP TABLE table_name;
//但是如果表不存在会报错
mysql> DROP TABLE student;
ERROR 1051 (42S02): Unknown table 'cfengtest.student'
所以还有一种写法,就是加上if exists
DROP TABLE IF EXITS table_name; //注意顺序,IF EXISTS 在前
//实践一下
mysql> DROP TABLE stu IF EXISTS;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF EXISTS' at line 1
mysql> DROP TABLE IF EXISTS stu;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> SHOW WARNINGS;
+-------+------+-------------------------------+
| Level | Code | Message |
+-------+------+-------------------------------+
| Note | 1051 | Unknown table 'cfengtest.stu' |
+-------+------+-------------------------------+
1 row in set (0.00 sec)
这下不会报错了,只会给出警告warning
DML data manipulation language
上面既然已经创建好了一张表,接下来就是给表插入数据了
插入数据,增加数据 INSERT
在之前使用可视化图形界面来创建数据的时候,就自动生成过insert语句了,那么insert的使用格式是什么呢
INSERT INTO table_name(col1,col2……) VALUES(value1,value2……);
注意: 字段名和值要一一对应,对于一一对应,就是不仅仅是数量要相等,数据类型也要相等
mysql> INSERT INTO
-> t_student
-> (no,name,sex,age,email)
-> VALUES
-> (100,'JAMES','男',20,'james123456.com');
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM t_student;
+------+-------+------+------+-----------------+
| no | name | sex | age | email |
+------+-------+------+------+-----------------+
| 100 | JAMES | 男 | 20 | james123456.com |
+------+-------+------+------+-----------------+
1 row in set (0.00 sec)
这里可以再看一下另外的结果,比如这里将字段的顺序颠倒一下,只要对应就可以了,对于顺序没有要求
mysql> INSERT INTO
-> t_student
-> (no,sex,name,age,email)
-> VALUES
-> (101,'女','LINDA',23,'1345@LinDa.com');
Query OK, 1 row affected (0.00 sec)
如果字段少几个,那么就是不填,该项就是空
mysql> INSERT INTO
-> t_student
-> (no,sex,name,age)
-> VALUES
-> (102,'男','JIM',24);
Query OK, 1 row affected (0.01 sec)
不一定所有字段都要有
insert语句但凡是执行成功了,那么必然会增加一条记录,并且只要字段和值一一对应,那么就可以成功插入数据,不一定要求有所有的字段,或者固定的顺序
mysql> INSERT INTO
-> t_student
-> (name)
-> VALUES
-> ('LIPIN');
Query OK, 1 row affected (0.01 sec)
可以查询一下表中的记录
mysql> SELECT * FROM t_student;
+------+-------+------+------+-----------------+
| no | name | sex | age | email |
+------+-------+------+------+-----------------+
| 100 | JAMES | 男 | 20 | james123456.com |
| 101 | LINDA | 女 | 23 | 1345@LinDa.com |
| 102 | JIM | 男 | 24 | NULL |
| NULL | LIPIN | NULL | NULL | NULL |
+------+-------+------+------+-----------------+
4 rows in set (0.01 sec)
不指明值,那么默认值是空
通过创建的过程就可以知道NULL不是一个具体值,只是代表空,所以不能使用 = NULL,而要使用 IS NULL或者IS NOT NULL; 或者普通的函数或者运算遇到空的时候运算结果都是空,所以使用单行函数IFNULL来转换为值运算;但是分组函数是忽略空的;这里的NULL和定义一个字符串然后填入NULL是不一样的,后者代表的是值,是可以运算的,这也是为什么之前的fruits表的最后一行可以运算
不指明值,那么默认值是空 DEFAULT
指定默认值的格式
col_name 数据类型 DEFAULT 默认值, 默认值要符合数据类型
这里为什么是空呢,其实是因为表的结构
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| no | int | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
| sex | char(1) | YES | | NULL | |
| age | int | YES | | NULL | |
| email | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
5 rows in set (0.01 sec)
可以看出Default栏都是NULL,这就是不写的时候就是额外的情况
那么是否可以改变默认情况呢
mysql> CREATE TABLE t_preson(
-> name VARCHAR(25),
-> sex CHAR(1) DEFAULT '男'
-> );
mysql> INSERT INTO
-> t_preson
-> (name)
-> VALUES
-> ('Wang');
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM t_preson;
+------+------+
| name | sex |
+------+------+
| Wang | 男 |
+------+------+
1 row in set (0.00 sec)
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| name | varchar(25) | YES | | NULL | |
| sex | char(1) | YES | | 男 | |
+-------+-------------+------+-----+---------+-------+
可以看到这里将默认的性别设置为男,也即是当不输入数据的时候,默认为男,这样就要省事一些
INSERT语句中字段名可以省略,省略代表都写上
省略代表默认出现所有的字段名,并且顺序就是字段表中的顺序,为了INSERT语句的一一对应,那么所有的value都要写上
mysql> INSERT INTO
-> t_preson
-> VALUES
-> ('Liuhu');
ERROR 1136 (21S01): Column count doesn't match value count at row 1
这里即使字段和值不匹配,少写了值,报错就是doesn’t match
mysql> INSERT INTO
-> t_preson
-> VALUES
-> ('Liuhu','女');
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM t_preson;
+-------+------+
| name | sex |
+-------+------+
| Wang | 男 |
| Liuhu | 女 |
+-------+------+
2 rows in set (0.01 sec)
这里还是建议使用上面的不省略的写法,因为可读性更强
单行处理函数(续)
数据库中有一条命名规范:所有的标识符都要小写,单词与单词之间都要以下划线分隔,不是驼峰命名,是下划线命名
数字格式化FORMAT
数字格式化,format可以让数字更加规范,使用的格式
FROMAT(数字(字段), '格式')
格式的表示方法: $99999,999 //用9来表示数位 写成.页可以
注意这里的格式是字符串形式的
mysql> SELECT
-> eName,FORMAT(sal,'$9999.999')
-> FROM
-> emp
-> LIMIT 5;
+--------+-------------------------+
| eName | FORMAT(sal,'$9999.999') |
+--------+-------------------------+
| SMITH | 800 |
| ALLEN | 1,600 |
| WARD | 1,250 |
| JONES | 2,975 |
| MARTIN | 1,250 |
+--------+-------------------------+
5 rows in set, 5 warnings (0.00 sec)
STR_TO_DATE 字符串转date
该函数可以将字符串转化位日期类型,也即是varchar类型转化为日期类型
函数使用的格式
STR_TO_DATE(字符串日期,'日期格式')
这里就可以尝试以下
('Linda',STR_TO_DATE('01-09-1990','%d%m%y'));
ERROR 1411 (HY000): Incorrect datetime value: '01-09-1990' for function str_to_date
//这里就是要日期匹配,因为中间是-的,注意年Y是大写,其余是小写
mysql> INSERT INTO
-> t_person
-> (name,birth)
-> VALUES
-> ('Linda',STR_TO_DATE('01-09-1990','%d-%m-%Y'));
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM t_person;
+-------+------------+
| name | birth |
+-------+------------+
| Linda | 1990-09-01 |
+-------+------------+
1 row in set (0.00 sec)
DATE_FROMAT date转为一定格式varchar类型
日期比如 1990-10-11 一共是10个字符
mysql> CREATE TABLE t_person
-> (name VARCHAR(25),
-> birth DATE
-> );
Query OK, 0 rows affected (0.03 sec)
mysql> INSERT INTO
-> t_person
-> (name,birth)
-> VALUES
-> ('Lida','01-09-1990');
ERROR 1292 (22007): Incorrect date value: '01-09-1990' for column 'birth' at row 1
日期就是日期,这里给的确是字符串类型
mysql的日期格式
%Y 年 %m 月 %d 日 %h 时 %i 分 %s 秒 //注意年是大写的,其他是小写的
INSERT插入日期
就是使用STR_TO_DATE函数来讲varchar类型的字符串转化为date类型
mysql> INSERT INTO
-> t_person
-> (name,birth)
-> VALUES
-> ('Linda',STR_TO_DATE('01-09-1990','%d-%m-%Y'));
但是如果日期格式是标准格式,就不需要再写str_to_date了 格式是%Y-%m-%d
mysql> INSERT INTO
-> t_person
-> VALUES
-> ('Wang','1988-01-12');
Query OK, 1 row affected (0.01 sec)
mysql> SELECT * FROM t_person;
+-------+------------+
| name | birth |
+-------+------------+
| Linda | 1990-09-01 |
| Wang | 1988-01-12 |
+-------+------------+
2 rows in set (0.00 sec)
DQL题目
为了数据的简单性,这里就不采用world数据表了,毕竟一共有4079行,所以这里就使用简单的职工表了,只有14行
mysql> SHOW TABLES;
+---------------------+
| Tables_in_cfengtest |
+---------------------+
| dept |
| emp |
| salgrade |
+---------------------+
3 rows in set (0.03 sec)
mysql> SELECT * FROM dept;
+--------+------------+----------+
| DeptNo | Dname | Loc |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
4 rows in set (0.02 sec)
mysql> SELECT * FROM salgrade;
+-------+-------+-------+
| grade | losal | hisal |
+-------+-------+-------+
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
+-------+-------+-------+
5 rows in set (0.00 sec)
mysql> SELECT * FROM emp;
+-------+--------+-----------+------+------------+---------+---------+--------+
| empNo | eName | job | Mgr | hireDate | sal | comm | deptNo |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BALNK | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLANRK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
14 rows in set (0.02 sec)
这就是简单的数据,方便后面的理解,对于这里的题目,可以建表来尝试这些题目
查询每个部门最高薪资
- 查询每个部门最高薪资的姓名,同时这里包含最高薪资,薪资的名字,和部门
这里其实是可以理解为两步,首先查询出每个部门的最高薪资、
之后将该薪资临时表和原表内连接
SELECT MAX(sal) sal,deptNo From emp GROUP BY deptNo
因此完整的查询条件就是
mysql> SELECT
-> e.eName,t.deptNo,t.sal
-> FROM
-> (SELECT MAX(sal) sal,deptNo From emp GROUP BY deptNo ) t
-> JOIN
-> emp e
-> ON
-> t.sal = e.sal;
+-------+--------+---------+
| eName | deptNo | sal |
+-------+--------+---------+
| BALNK | 30 | 2850.00 |
| SCOTT | 20 | 3000.00 |
| KING | 10 | 5000.00 |
| FORD | 20 | 3000.00 |
+-------+--------+---------+
4 rows in set (0.00 sec)