您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

mysql和mssql对比

bubuko 2022/1/25 20:05:55 mysql 字数 8617 阅读 786 来源 http://www.bubuko.com/infolist-5-1.html

由于工作原因,程序需要适配两种类型的数据,所以把一些sql语句写法对比总结一下本篇及后续随笔都将使用一个极其简单的场景(课室,学生,1对多)来演示,请先创建表mysql CREATE TABLE IF NOT EXISTS `class` ( `Id` int(11) NOT NULL, `Name ...

由于工作原因,程序需要适配两种类型的数据,所以把一些sql语句写法对比总结一下
本篇及后续随笔都将使用一个极其简单的场景(课室,学生,1对多)来演示,请先创建表
mysql

CREATE TABLE IF NOT EXISTS `class` (
  `Id` int(11) NOT NULL,
  `Name` varchar(50) NOT NULL DEFAULT ‘0‘,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `student` (
  `Id` int(11) NOT NULL,
  `ClassId` int(11) NOT NULL,
  `Name` varchar(50) NOT NULL DEFAULT ‘0‘,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

mssql

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Class](
	[Id] [int] NOT NULL,
	[Name] [nvarchar](10) NULL,
 CONSTRAINT [PK_Class] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Student](
	[Id] [int] NOT NULL,
	[ClassId] [int] NULL,
	[Name] [nvarchar](10) NULL,
 CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

数据的插入语句mysql和mssql一样

INSERT Class (Id, Name) VALUES (1, ‘1年3班‘);
INSERT Class (Id, Name) VALUES (2, ‘1年1班‘);
INSERT Class (Id, Name) VALUES (3, ‘1年4班‘);
INSERT Class (Id, Name) VALUES (4, ‘1年2班‘);
INSERT Student (Id, ClassId, Name) VALUES (1, 3, ‘小a‘);
INSERT Student (Id, ClassId, Name) VALUES (2, 1, ‘小b‘);
INSERT Student (Id, ClassId, Name) VALUES (3, 2, ‘小c‘);
INSERT Student (Id, ClassId, Name) VALUES (4, 1, ‘小d‘);
INSERT Student (Id, ClassId, Name) VALUES (5, 2, ‘小e‘);
INSERT Student (Id, ClassId, Name) VALUES (6, 3, ‘小f‘);
INSERT Student (Id, ClassId, Name) VALUES (7, 2, ‘小h‘);
INSERT Student (Id, ClassId, Name) VALUES (8, 3, ‘小i‘);
INSERT Student (Id, ClassId, Name) VALUES (9, 4, ‘小j‘);
INSERT Student (Id, ClassId, Name) VALUES (10, 3, ‘小k‘);
INSERT Student (Id, ClassId, Name) VALUES (11, 3, ‘小l‘);
INSERT Student (Id, ClassId, Name) VALUES (12, 3, ‘小m‘);
INSERT Student (Id, ClassId, Name) VALUES (13, 4, ‘小n‘);
INSERT Student (Id, ClassId, Name) VALUES (14, 1, ‘小o‘);
INSERT Student (Id, ClassId, Name) VALUES (15, 4, ‘小p‘);
INSERT Student (Id, ClassId, Name) VALUES (16, 2, ‘小q‘);

  

p.s. mysql和mssql的表名不区分大小写,但是避免混淆,演示时mssql会首字母大写

一、分页写法

假设一页5条数据,取第1页

1.1 主流写法

mysql

select * from student limit 0, 5

mssql(分页前必须要order by 一下,否则报错,mysql没有这限制)

select * from Student order by Id offset(5 * 0) rows fetch next 5 rows only

1.2 用行号来分页 

mysql:mysql通过自定义变量使用行号

SELECT * from (SELECT @row:=@row+1 AS row, student.* FROM student, (select @row := 0) r ORDER BY student.Id) student WHERE row > (0 * 5)  AND row <= ((0+1) * 5)

mssql:通过系统函数来使用行号

select * from (select ROW_NUMBER() over(order by Id) as row, * from Student) as Student where row > (0 * 5) and row <= ((0+1) * 5)

好像还有between and 的写法也行

 

二、top

取第一条数据

mysql没有top的写法,只能用limit 0, 1

select * from student limit 0, 1

mssql则有top

select top 1 * from Student

p.s. 鉴于mssql有top可以用,所以mssql可以改上面的行号分页方式,去掉row <= ((0+1) * 5)条件,使用top 5

 

三、插入数据时如果有条件,且数据源不来自旧表,mysql需要加上from dual而mssql则不用

给1年1班新增一个学生,但不要重复新增

mysql

INSERT INTO student(Id, ClassId, Name) SELECT 17, 1, ‘小r‘ FROM dual WHERE NOT EXISTS(SELECT 1 FROM student WHERE ClassId = 1 AND NAME = ‘小r‘)

 mssql

INSERT INTO student(Id, ClassId, Name) SELECT 17, 1, ‘小r‘ WHERE NOT EXISTS(SELECT 1 FROM student WHERE ClassId = 1 AND NAME = ‘小r‘)

 

四、判断结果是否为null,若为null则用别的代替

mysql:IFNULL

mssql:ISNULL

 

五、mysql不支持in查询里面分页,但是mssql支持

SELECT * FROM student WHERE Id IN (SELECT Id FROM class LIMIT 0, 1)

mysql会报错“This version of MariaDB doesn‘t yet support ‘LIMIT & IN/ALL/ANY/SOME subquery‘”

 

六、mysql和mssql都有distinct和group by来去重,但是mssql的order by 后面的字段必须是distinct或group by中出现的字段,而mysql无此限制

原因可能是mysql是先order by再distinct,而mssql则是先distinct再order by

SELECT DISTINCT class.* FROM class JOIN student ON class.Id = student.ClassId ORDER BY student.Name
SELECT class.* FROM class JOIN student ON class.Id = student.ClassId GROUP BY class.Id, class.Name ORDER BY student.Name

如上语句mysql正确执行,而mssql会报错“ORDER BY 子句中的列 "student.Name" 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中。”

mssql可以用以下语句实现同等效果

SELECT class.* FROM class JOIN student ON class.Id = student.ClassId GROUP BY class.Id, class.Name ORDER BY (select top 1 Name from Student where ClassId = class.Id)

注意,用distinct去重时(如下语句),连这样改排序条件都不行,会报错“如果指定了 SELECT DISTINCT,那么 ORDER BY 子句中的项就必须出现在选择列表中。”[mssql真坑]

SELECT DISTINCT class.* FROM class JOIN student ON class.Id = student.ClassId ORDER BY (select top 1 Name from Student where ClassId = class.Id)

这里总结为:多表查询只查主表,排序依据用子表的问题,mysql可以直接写,而mssql就必须转换一下,且用distinct还无法实现需求

*(代码场景)通常排序依据都是外部传入的,查询方法本身不能知道排序依据会不会有子表的,有多少个,这里若用mssql作为数据仓储就需要多这一步额外的判断,程序相对就复杂了。[mssql真坑]

 

七、多表查询,主表分页
查询学生名字排序,班级及班级所有学生的分页,假设分页大小是2,取第2页

查询出来的主表的数据应该是2条,但由于join了

mysql

SELECT class.*, student.* FROM 
(
SELECT DISTINCT class.* FROM class JOIN student ON class.Id = student.ClassId ORDER BY student.Name LIMIT 2, 2
) AS class JOIN student ON class.Id = student.ClassId

技术分享图片 

mssql

select Class.*, Student.* from
(
SELECT Class.* FROM Class JOIN Student ON Class.Id = Student.ClassId GROUP BY Class.Id, Class.Name ORDER BY (select top 1 Name from Student where ClassId = Class.Id) offset(1 * 2) rows fetch next 2 rows only 
) as Class join Student on Class.Id = Student.ClassId
ORDER BY (select top 1 Name from Student where ClassId = Class.Id)

结果为
技术分享图片

注意mssql外面那次不排序,结果就是这样
技术分享图片

 

这是默认排序的问题,建议是都给加上外面那层排序

 

八、多表更新
mysql的多表更新要把查询用到的表写在set前面,更新内容可以是任意一个表的字段

UPDATE class JOIN student ON class.Id = student.ClassId SET student.NAME = ‘小a‘, class.Name = ‘1年4班‘ WHERE student.name = ‘小a‘

mssql的多表更新则是只能更新其中一个表,查询用到的表写在set后面,还要有from

UPDATE Student SET NAME = ‘小a‘ from Class JOIN Student ON Class.Id = Student.ClassId WHERE Student.Name = ‘小a‘

总结:mysql在更新方面比mssql要灵活

 

p.s. 此随笔只要笔者踩到新坑就会更新

mysql和mssql对比

原文:https://www.cnblogs.com/ogurayui/p/12486699.html


如果您也喜欢它,动动您的小指点个赞吧

除非注明,文章均由 laddyq.com 整理发布,欢迎转载。

转载请注明:
链接:http://laddyq.com
来源:laddyq.com
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


联系我
置顶