sql的书写操作

创建数据库

create database <数据库名>

创建表

create table <表名>(
<列名1> <数据类型> <该列的约束><列名2> <数据类型> <该列的约束>...
<该表的约束1>,<该表的约束2>,...
);

数据类型

-字符串:定长char,可变长度varchar

-数字:int/integer

-日期:date

约束:

-null

-not null

-primary key

create table student
(sid  int(4)  primary key auto_increment comment '学生id',
sname char(20) not null comment '学生名字',
ssex char(3) not null comment '学生性别',
sage integer not null comment '学生年龄');

增加表的列

alter table <表名> add <列名>

alter table tableName add columnName varchar(30)  

删除表的列

alter table <表名> drop <列名>

删除表

1)如果想删除表,当然用drop;

如果想保留表而将所有数据删除,如果和事务无关,用truncate即可;

如果如果想保留表而将所有数据删除,如果和事务有关,或者想触发trigger,还是用delete;

2)执行速度:drop>truncate>delete

3)drop、truncate是立即执行,不能回滚

4)drop、truncate不能加where条件

drop table student;

truncate table 表名;

delete from  student where  T_name = "张三";

插入数据

可以只插入所需要的列,但其他未被写入的列必须可以为空,如果设置成不为null那将报错

insert into <表名> (<列名1><列名2>...values(<1>,<2>...)

更新数据

UPDATE <列名> SET1=value1,2=value2,WHERE conditions

为列设置别名

select name as s_name from student;

删除重复数据

//distinct 放在列名前
select distinct name from student;

mysql的执行顺序

select
    catid,
    count(orderid) as sales
from
    t
where 
    catid <> "c666"
group by 
    catid
having
    count(orderid) > 10
order by 
    count(orderid) desc
limit 3

执行顺序是:from-on-join-where-groupby-having-select-orderby-limit

如果是单表就根据这个执行顺序来套入,order by里的字段前面必须出现,group by出现或者select出现都可以

https://www.nowcoder.com/practice/e00bbac732cb4b6bbc62a52b930cb15e?tpId=199&tqId=1975672&ru=/exam/oj&qru=/ta/sql-quick-study/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3DSQL%25E7%25AF%2587%26topicId%3D199

运算符

+、-、*、/、=、<>、 >、 >= <、 <=

select 姓名,出生日期 from student where 出生日期<>'1990-01-01';

查出null和not null值

select 教师号,教师姓名 from teacher where 教师姓名 is null;

select 教师号,教师姓名 from teacher where 教师姓名 is not null;

逻辑运算符

not、and、between、or、in

select 学号,成绩 from course where not 成绩<60;

-- 60<=成绩<=90
select 学号,成绩 from course where 成绩 between 60 and 90;

select 姓名,性别 from student where 姓名 in ('猴子','马云');

select 姓名,性别 from student where 姓名 not in('猴子','马云');

%跟_

%表示任意字符串,_表示任意一个字符

select * from student where 姓名 like '%猴%';

select * from student where 姓名 like '王__';

汇总函数

count(),参数写列名则不包括空值,写*则包括空值

sum(),对某列求和

avg(),求某列的平均值

max(),求某列的最大值

min(),求某列的最小值

分组

使用group by分组时,会将相同字段的记录归并成一条记录,这时那些不是在group by后那些字段就可能会出现多个值

分组前:
在这里插入图片描述
分组后:
在这里插入图片描述
如果使用name分组的话,返回应该是虚拟表3,可以看到id跟number一个单元格里有多个值,这样查询出来的结果是错误的;但name每个单元格只有一个数据,因此select name是不会报错的

既然一个单元格有多个值,若使用聚合函数把多个值合并起来,再查询,这样是允许的

例如使用count(id),sum(number)等等

偶尔也会出现多个字段分组,例如group by name,number,我们可以把它看成一个整体字段,用整体来分组

在这里插入图片描述
这也解释了为什么order by出现的字段group by里必须要有

排序

使用order by,默认是asc即升序,desc是倒序

可以根据多个列排序,order by 成绩 asc,课程号 desc;

常见错误

-在groupby和having里不要使用select 里的别名,因为先后顺序问题

-在where中使用聚合函数,都还没根据条件筛选出来,怎么使用聚合函数

视图

可以将查询出来的结果存放在一张虚拟表上,这张虚拟表叫做视图,可以对这张表进行增删改查,但一般不会增删改,因为会影响原表,而原表修改对视图也有影响

create view viewName as select语句

视图列名跟select子句的列名是一一对应的

视图的作用

当经常需要使用到一个比较复杂的sql查询时,通过sql可以避免每次都写很多的语句,因此具有简单性

视图可以只显示某些数据,它可以保证某些敏感数据不被增删改查,因此具有安全性

子查询

子查询是一次性的视图,可以放在from、in、any(任意一个,有一个满足即可)、all(所有都需要满足)语句中

select 性别,人数 from( select 性别,count(*) as 人数 from student group by 性别 )as 按性别汇总;

select 学号,成绩 from course where 成绩>any(select 成绩 from course where 课程号='0002');

偶尔使用sql语句:子查询

频繁使用sql语句:视图

子查询的执行顺序

看是关联子查询还是非关联子查询

如果是关联子查询,即外部查询返回的每一行数据子查询都要执行一次,然后子查询再将结果返回给外部查询,外部查询根据结果做出决策

select * from dept d where exists(select * from emp e where e.deptno = d.deptno); 

这样执行顺序是先执行外层再执行内层

如果是非关联子查询,即子查询是独立于太不查询的查询,子查询执行完毕后将结果传给外部查询

select * from emp where sal = (select max(sal) from emp);

执行顺序是先执行内层查询再执行外层查询

关联子查询有什么用

在每个组里进行比较的时候,使用关联子查询

联合查询,也叫组合查询

-union,删除重复行

-union all,保留重复行

联合查询select必须拥有相同数量的列且具有相同类型的列

//相同名字不会被查出来
SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2
//相同名字会被查出来
SELECT column_name(s) FROM table_name1 UNION ALL SELECT column_name(s) FROM table_name2

https://www.nowcoder.com/practice/979b1a5a16d44afaba5191b22152f64a?tpId=199&tqId=1975677&ru=/exam/oj&qru=/ta/sql-quick-study/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3DSQL%25E7%25AF%2587%26topicId%3D199

连接查询

连接:表和表之间通过列产生关系,联结就是根据表和表之间的关系将两个表合并在一起的操作

常用的联结:交叉连接、内连接、左连接、右连接、全连接

例如在这里插入图片描述
交叉连接

交叉连接也称笛卡尔积,即将表1的每一行数据和表2的每一行数据合并在一起

行数的3*2
在这里插入图片描述
内连接

查找两张表里共同存在的数据,即交集
在这里插入图片描述
步骤:

-分别从两张表里查出符合条件的行,两张表都需要存在某些数据
在这里插入图片描述
这就解释了https://www.nowcoder.com/practice/88aa923a9a674253b861a8fa56bac8e5?tpId=199&tqId=1975674&ru=/exam/oj&qru=/ta/sql-quick-study/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3DSQL%25E7%25AF%2587%26topicId%3D199为什么需要用distinct

select a.学号,a.姓名,b.课程号 from student as a inner join course as b on a.学号=b.学号;

左连接

左表全部查询,右表只查出两张表都存在的数据
在这里插入图片描述
步骤:

-左边表的数据全部取出,右边的表选择同时存在于两张表中的数据

-将两张表中取出的数据进行合并,即交叉联结

select a.学号,a.姓名,b.课程号 from student as a left join course as b on a.学号=b.学号;

查出A表里不在B表的数据

select a.学号,a.姓名,b.课程号 from student as a left join course as b on a.学号=b.学号 where b.学号 is null;

右连接
在这里插入图片描述
左连接跟右连接差不多,可以互换

全连接
在这里插入图片描述
连接图
在这里插入图片描述
self join

返回表与自己连接后符合条件的记录,一般用在表里有一个字段是用主键作为外键的情况
在这里插入图片描述
case表达式

case when <判断表达式> then <表达式>
     when <判断表达式> then <表达式>
     when <判断表达式> then <表达式>
     ...
     else <表达式>
end

注意事项:

-else语句可以省略不写,默认为空值,建议不要省略

-end不能省略

-case表达式可以写在sql的任意子句中

-- 查询出每门课程的及格人数和不及格人数
select 课程号,
sum(case when 成绩>=60 then 1
else 0
end) as 及格人数,
sum(case when 成绩<60 then 1
else 0
end) as 不及格人数
from score
group by 课程号;

书写sql的思路

-翻译成大白话

-写出分析思路

-写出对应的sql子句

例如查询所有学生的学号、姓名、选课数、总成绩

-大白话

1)学号、姓名(学生表student)

2)选课数(每个学生的选课数目:成绩表score,按学号分组,对课程号计数count)

3)总成绩(每个学生的总成绩:成绩表score,按学号分组,对成绩求和sum)

-思路

1)select 查询结果:[学号,姓名,选课数,总成绩]

2)from 从哪张表查找数据:[学生表student,成绩表score;两个表如何连接?通过学号;用哪种连接?左连接)

3)where 查询条件:[没有]

4)group by 分组:[每个学生的选课数目:按学号分组,对课程号计数count;每个学生的总成绩:按学号分组,对成绩求和sum]

5)having 对分组结果指定条件:[没有]

6)order by 对查询结果排序:[没有]

7)limit 从查询结果中取出指定行:[没有];

select a.学号,a.姓名,count(b.课程号) as 选课数,sum(b.成绩) as 总成绩
from student as a left join score as b
on a.学号=b.学号
group by a.学号;

ID自动编号的数据库当中删除了一条记录后,如何才能使编号仍然保持连续

Delid = 26
delete from tablename where id = Delid
update tablename set id = id-1 where id > Delid

有一个前提条件,id不能为标识列(唯一值),如果是标识列先取消自动标识,然后执行update 语句,执行完毕再把id设置成自动标志

sql 里的计数方式

count(*),count(1),count(主键),count(普通字段)

首先 count(字段)表示的就是该字段里值不为null的数据行有多少行

count(*)其实就是count(0),无论是count(0)还是count(1),0跟1都永远不为null,因此会把为null的行也统计进来

性能比较,count(*)=count(1)>count(主键)>count(普通字段)

count(主键)跟count(普通字段),当拿到行数据之后,还要判断拿到的主键/普通字段是否为null值,因此性能相对会差一点

但为什么count(主键)>count(普通字段),因为主键值比较容易拿到,如果存在二级索引,那么count(主键)不需要回表操作,但是count(普通字段)需要回表操作

而count(*)跟count(1)不需要判断值是否为null值,因此相对性能会快一点

如果存在二级索引,那么innodb遍历数据将会使用二级索引,因为二级索引占的内存小一点,性能会好一点

mysql里的判断

-case函数

SELECT
    t.NAME,
    (
        CASE t.sex
        WHEN 1 THEN
            '男'
        WHEN 2 THEN
            '女'
        ELSE
            '未知'
        END
    ) 性别
FROM
    t_customer t

UPDATE salary
SET
    sex = CASE sex
        WHEN 'm' THEN 'f'
        ELSE 'm'
    END;

-if函数

使用CASE函数可以实现非常复杂的逻辑判断,可是若只是实现“如果符合条件则返回A,否则返回B”这样简单的判断逻辑的话,使用CASE函数就过于繁琐。MYSQL提供了IF()函数用于简化这种逻辑判断,其语法格式如下:IF(expr1,expr2,expr3)

如果 expr1 为真&&expr1 <> 0 && expr1 <> NULL),那么 IF() 返回 expr2,否则返回expr3。IF()返回一个数字或字符串,这取决于它被使用的语境

select t.name,if(t.weight<80,'正常','肥胖') 体重 from t_customer t

where1=1的意义


<select id="queryBookInfo" parameterType="com.ths.platform.entity.BookInfo" resultType="java.lang.Integer">
 select count(id) from t_book t where 1=1
<if test="title !=null and title !='' ">
 AND title = #{title} 
</if> 
<if test="author !=null and author !='' ">
 AND author = #{author}
</if> 
</select>

这里where1=1的意义是为了后面if标签为true时给这条sql语句添加一个where

那么where1=1对性能是否有影响,是否会让索引失效

通过explain语句可以可知使用where1=1同样是能走索引的,因此对性能并不会影响。不仅如此,mysql在执行sql的时候会优化sql,自动把1=1这个条件去掉

但是如果数据量大的话,那么mysql优化还是有影响的,建议使用标签,这个标签可以自动把第一个and或者or去掉

<select id="queryBookInfo" parameterType="com.ths.platform.entity.BookInfo" resultType="java.lang.Integer">
 select count(*) from t_book t
<where>
<if test="title !=null and title !='' ">
 title = #{title} 
</if>
<if test="author !=null and author !='' "> 
 AND author = #{author}
</if>
</where> 
</select>

where跟having的区别

where针对的是一条记录,例如当一条数据id=1时

having针对的是多条记录,例如说求语文平均成绩大于80的班级

where 后面不能接聚合函数,如果需要用聚合函数可以使用having

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当使用Java来编SQL插入语句时,可以通过使用JDBC(Java Database Connectivity)来与数据库交互。下面是一个示例,展示如何使用Java编一个简单的SQL插入语句: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class InsertExample { public static void main(String[] args) { // 数据库连接信息 String url = "jdbc:mysql://localhost:3306/mydatabase"; String username = "root"; String password = "password"; // SQL插入语句 String sql = "INSERT INTO users (id, name, age) VALUES (?, ?, ?)"; try { // 加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); // 建立数据库连接 Connection conn = DriverManager.getConnection(url, username, password); // 创建预编译的SQL语句对象 PreparedStatement statement = conn.prepareStatement(sql); // 设置参数值 statement.setInt(1, 1); statement.setString(2, "John"); statement.setInt(3, 25); // 执行SQL插入语句 int rowsInserted = statement.executeUpdate(); System.out.println("插入成功,影响行数:" + rowsInserted); // 关闭连接和资源 statement.close(); conn.close(); } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } } } ``` 在这个示例中,我们首先加载MySQL数据库驱动,并通过`DriverManager.getConnection()`方法建立与数据库的连接。然后,我们创建一个预编译的SQL语句对象,并设置参数值。最后,我们使用`executeUpdate()`方法执行插入操作,并获取受影响的行数。 需要注意的是,这只是一个简单的示例,实际情况中可能需要更复杂的逻辑和错误处理。此外,还需要根据实际情况修改数据库连接信息、SQL语句和参数设置等部分。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值