SQL语法快速回顾
Posted ztytoby
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL语法快速回顾相关的知识,希望对你有一定的参考价值。
学习及整理来源:
做了些笔记快速记忆
以下为示例表(在\'People\'数据库中创建了\'Friends\'表)
DATABASE NAME: People
TABLE NAME: Friends
id | name | location | item | SorN |
1 | zty | CN | switch | Y |
2 | ter | CA | xbox | Y |
3 | jo5 | CN | ps5 | N |
4 | ada | CA | pc | N |
0. 首先。。
比如mysql:
mysql> use People; (打开数据库\'People\')
mysql> set names utf8;(编码啥的)
1. SELECT
SELECT id,name, ...
FROM Friends;
或
SELECT id, name, ... FROM Friends;
如果
SELECT * FROM Friends;
就会显示整个表
2. SELECT DISTINCT
只会显示不重复的,比如说第3列
SELECT DISTINCT location FROM Friends;
会输出 cn和ca(当然是以表格形式)
3. WHERE
其实就是加了\'条件\',比如
SELECT * FROM Friends WHERE id=1;
或
SELECT * FROM Friends WHERE name=\'zty\';
注意数值字段不要用引号
以上例子中"="就是运算符,常用运算符有
= 等于 <> 不等于(有时能够被换成!=) >大于 <小于 >=大于等于 <=小于等于
BETWEEN 在某个范围内,一般接AND用 这里范围边缘是包括的(比如SELECT * FROM Friends WHERE id BETWEEN 2 AND 4,那么就是输出id为2,3,4的各个数)
LIKE 模糊搜索(好玩的部分,比如 SELECT * FROM Friends WHERE item LIKE \'p%\', 那么会输出带有ps5的第三行和带有pc的第四行。假如是SELECT * FROM Friends WHERE item LIKE \'p_\',那么只会输出带有pc的第四行。因为 %表示多个字值,_表示一个字符)
关于通配符:
% 替代0个或多个字符
- 替代一个字符
[charlist]字符列中的任何单一字符
[^charlist]或[!charlist]不在字符列中的任何单一字符
IN 精确查询(可查多个),比如
SELECT * FROM Friends WHERE id IN (3,2,4); 且并不需要按顺序。
空值 is null
SELECT * FROM Friends WHERE id is null; 这条没结果的,我这个表没有空值。
逻辑运算优先级: () not and or
4. AND和OR运算符
SELECT * FROM Friends WHERE location=\'CN\' AND id<3
SELECT * FROM Friends WHERE location=\'CN\' or item=\'pc\'
通过括号还能变更复杂
SELECT * FROM Friends WHERE location=\'CN\' AND (id<3 OR id>4) 当然这句意义不大,只是做个例子
5.排序 ORDER BY
ASC升序 DESC降序
SELECT * FROM Friends ORDER BY id DESC 按照id降序排整个表
多个列也可以排,具体参考例子(因为懒)。总结就是谁在前面就先排谁
SQL ORDER BY 关键字 | 菜鸟教程 (runoob.com)
6.插入INSERT INTO 注意id列自动更新且唯一,不用管
不指定 INSERT INTO Friends VALUES (\'zyc\',\'CA\',\'ps4\',\'N\');
指定列 INSERT INTO Friends (\'name\',\'location\',\'SorN\') VALUES (\'zyc\',\'CA\',\'N\')
还不清楚如果不填的话是空值还是0
7.更新UPDATE
UPDATE Friends SET location=\'CA\' WHERE name=\'zty\';
把zty的location更新成CA
注意!!如果没有WHERE语句,会把所有location的值都变成CA(坏)
在MySQL中,可以设置set sql_safe_updates=1; 这样没写WHERE就会报错
8. 删DELETE
DELETE FROM Friends WHERE name=\'zty\' AND location=\'CA\';
同样,不加WHERE就会删除所有行
9.SELECT TOP,LIMIT,ROWNUM
TOP:前百分之多少的子句显示,是SQL SERVER/MS Access语法
SELECT TOP 10 name
From Friends;
LIMIT:前面几条数据,是MySQL语法:
SELECT * FROM Friends LIMIT 5;
ROWNUM: 同上,但是是Oracle的语法:
SELECT name FROM Friends WHERE ROWNUM <=3;
未完。。。
基础知识(C#语法数据库SQL Server)回顾与总结
前言
已经有大概一个多月没有更新博客,可能是开始变得有点懒散了吧,有时候想写,但是又需要额外投入更多的时间去学习,感觉精力完全不够用啊,所以为了弥补这一个多月的潜水,决定写一篇,衔接9月未写博客的空缺。
无需定义实体,返回object类型,如何获取属性值?
这样的场景在下拉列表中很常见,在下拉列表中我们只需要Id和Name两个字段,无需其他字段,同时也是为了节约流量,例如实体和数据如下:
public class Department { public int Id { get; set; } public string Name { get; set; } public DateTime CreatedTime { get; set; } public string Contact { get; set; } public string ContactUser { get; set; } }
var deparments = new List<Department>() { new Department(){ Id=1,Name="department1",CreatedTime=DateTime.Now,Contact="13682687787",ContactUser="Tom"}, new Department(){ Id=2,Name="department2",CreatedTime=DateTime.Now,Contact="13682687788",ContactUser="Jeffcky"}, new Department(){ Id=3,Name="department3",CreatedTime=DateTime.Now,Contact="13682687783",ContactUser="Lily"}, new Department(){ Id=4,Name="department4",CreatedTime=DateTime.Now,Contact="13682687782",ContactUser="Jim"}, new Department(){ Id=5,Name="department5",CreatedTime=DateTime.Now,Contact="13682687781",ContactUser="Allen"}, };
此时为了再额外定义另外的实体,我们通过匿名类型来进行转换
static IEnumerable<object> Change(List<Department> departments) { var changeDepartments = departments.Select(d => new { id = d.Id, name = d.Name }); return changeDepartments; }
将上述集合传入到该Change方法中则返回集合中包含id和name的列,这样在下拉列表就能很好的显示,但是如果用户选择了所在部门,下一次再次进行编辑时需要在该转换集合中得到用户的id和name,此时集合返回类型为object,我们如何得到其中的属性id和用户id进行比对呢,我们来看看以下两种方法。
反射
反射应该是我们首先能够想到的方式了,获取该实体类型的属性并获取其值。例如我们要在上述Change方法返回的集合中获取到id=1的对象,我们通过如下反射来获取。
var changes = Change(deparments); var specialDepartment = changes.FirstOrDefault(d => Convert.ToInt32(d.GetType().GetProperty("id").GetValue(d)) == 1);
dynamic关键字
上述实现是最原始的方式,当dynamic关键字出世之后,我们可以直接将集合中的object类型转换为dynamic动态对象,在运行时让编译器自己去计算,如此一来上述的实现可以更加简洁实现。
var changes = Change(deparments); var specialDepartment = changes.FirstOrDefault(d => ((dynamic)d).id == 1);
虽然上述利用dynamic关键字实现看似很简洁但是也有其缺点,类似于JavaScript中动态类型,它是区分大小写的,要是我们将id写成Id直接抛出异常,如下:
var specialDepartment = changes.FirstOrDefault(d => ((dynamic)d).Id == 1);
为了这样避免出错,而且我们还是需要有智能提示,那就老老实实写一个专门针对下拉列表的转换类,也未尝不可。
public class SelectItem { public int Id { get; set; } public string Name { get; set; } }
数据排名
排名这个也是常见不能再常见的场景了,例如在微信运动中就有截止到每天到十点每天所走步数好友的排名,场景有几种对应的实现方式也有几种,我们来看看。建立如下简单示例表。
不同等分数排名
不同等分数即分数都不一样,如下
首先我们利用Row_Number()函数来实现排名。
SELECT UserId,Score, ROW_NUMBER() OVER(ORDER BY Score DESC) AS [Rank] FROM dbo.Ranks
这样我们就可以获取到某个用户所在排名为多少,这只是针对没有同样的分数而言,要是分数有一样的呢,Row_Number函数还适用?
同等分数并列排名
我们将数据修改成如下:
再来利用Row_Number来进行排名。
此时分数同样为90则排名一个为第三名,另个却为第四名,用户表示我不服,分数不一样,而且没有其他维度的判断逻辑,怎么我就变成第四名了呢,不应该是并列第三名么。这是程序员小哥的bug。我不听,我不听。下面再来设计一个课程得分的表ExamResult。
并列分数排名又分为两种场景,比如上述学生Sam的数学和科学都是为90,则并列第一名,到了社会这门学科是第三名,还是第二名呢,这就看实际应用场景,若是第三名我们就需要用RANK函数来排名。
SELECT Name , Subject , Marks , RANK() OVER (PARTITION BY name ORDER BY Marks DESC ) Rank FROM ExamResult ORDER BY name , subject
若是没有空缺排名则利用DENSE_RANK函数来实现。
SELECT Name , Subject , Marks , DENSE_RANK() OVER ( PARTITION BY name ORDER BY Marks DESC ) Rank FROM ExamResult ORDER BY name
由上我们知道关于SQL Server中RANK和DENSE_RANK函数的区别在于DENSE_RANK函数没有排名空缺。在大部分场景下都需要考虑并列排名的情况,其ROW_NUMBER函数不再适用,除非明确知道排名中不会存在分数并列的情况,否则谨慎适用。
删除数据重复
如果数据库表设计不够合理,或者说出现并发很容易导致插入重复情况,此时我们去尝试删除数据重复的表。我们首先创建如下测试表。
CREATE TABLE DuplicateRows ( Id INT , Name VARCHAR(20) ) INSERT INTO DuplicateRows VALUES ( 1, ‘Andy‘ ) INSERT INTO DuplicateRows VALUES ( 1, ‘Andy‘ ) INSERT INTO DuplicateRows VALUES ( 2, ‘Bill‘ ) INSERT INTO DuplicateRows VALUES ( 2, ‘Bill‘ ) INSERT INTO DuplicateRows VALUES ( 2, ‘Bill‘ ) INSERT INTO DuplicateRows VALUES ( 3, ‘Chris‘ )
我们看到如上数据Name为Andy的数据重复两次,同时Name为Bill的数据重复三次。关于数据重复删除方式总结起来有四种方式,我们一起来总结下。
借助临时表(方式一)
SELECT DISTINCT * INTO #tmp FROM [dbo].[DuplicateRows] DELETE FROM [dbo].[DuplicateRows] INSERT INTO [dbo].[DuplicateRows] SELECT * FROM #tmp DROP TABLE #tmp
上述逻辑很简单,我们查询出不重复的删除并插入到临时表中,然后删除表中数据将临时表中不重复的数据插入到表中即可。
RANK() OVER( PARTITION BY)(方式二)
上述是最简单的方式,若是我们表中有一列和另外一行列不同,此时利用DISTINCT关键字过滤数据将不再起作用。在这种情况下,我们可以添加一列,作为行唯一标识符(自动递增升序)。然后获取每个Id的名称。 如果Rank大于1,则表示它是重复行然后删除。 删除重复的行后,删除唯一列标识。 如下:
添加唯一标识列且自增长。
ALTER TABLE [dbo].[DuplicateRows] ADD sNo INT IDENTITY(1,1)
利用RANK函数对名称进行分区并进行sNo排序。
SELECT * , RANK() OVER ( PARTITION BY Id, Name ORDER BY sNo ) [rank] FROM [dbo].[DuplicateRows]
此时再删除rank大于1即重复的数据。
DELETE E FROM [dbo].[DuplicateRows] E INNER JOIN ( SELECT * , RANK() OVER ( PARTITION BY Id, Name ORDER BY sNo DESC ) [rank] FROM [dbo].[DuplicateRows] ) T ON E.sno = t.sno WHERE T.[rank] > 1
最后删除唯一标识列sNo.
ALTER TABLE [dbo].[DuplicateRows] DROP COLUMN sNo
完整代码如下:
ALTER TABLE [dbo].[DuplicateRows] ADD sNo INT IDENTITY(1,1) DELETE E FROM [dbo].[DuplicateRows] E INNER JOIN ( SELECT * , RANK() OVER ( PARTITION BY Id, Name ORDER BY sNo DESC ) [rank] FROM [dbo].[DuplicateRows] ) T ON E.sno = t.sno WHERE T.[rank] > 1 ALTER TABLE [dbo].[DuplicateRows] DROP COLUMN sNo
DELELTE TOP(2)(方式三)
如果我们想删除特定重复的数据,通过DELETE TOP语句来完成,例如删除上述id = 2的重复数据。
DELETE TOP ( 2 ) FROM [dbo].[DuplicateRows] WHERE Id = 2
HAVING COUNT(*) >1(方式四)
如果我们需要将所有重复的数据都删除,只保留未被删除的数据,利用HAVING COUNT(*) >1完成,若是查询到重复个数大于1则删除。
DELETE FROM [dbo].[DuplicateRows] WHERE Id IN ( SELECT Id FROM [dbo].[DuplicateRows] GROUP BY Id HAVING COUNT(*) > 1 )
上述讲到了删除数据重复的四种方式,若是需要查询并过滤数据重复情况,举一反三同样大部分也适用。
总结
本节讲述一点基础知识,回顾了一下,十一期间有时间会讲讲vue。see u.
以上是关于SQL语法快速回顾的主要内容,如果未能解决你的问题,请参考以下文章