果断的面包 · SQL server插入子查询结果 ...· 6 天前 · |
烦恼的黑框眼镜 · Oracle数据库入门之多表连接与子查询 ...· 6 天前 · |
憨厚的冲锋衣 · Fun0nydg的博客 - 个人随笔· 6 天前 · |
读研的充电器 · mysql日期只比较年月日 ...· 6 天前 · |
大力的松鼠 · Mysql比较日期和时间 - · 6 天前 · |
粗眉毛的伏特加 · 批量查询实例详情_云数据库 ...· 1 月前 · |
求醉的长颈鹿 · 蓝奏云lsp软件合集网站· 2 月前 · |
爱笑的草稿纸 · 沈阳西站新民北站高铁与公交将无缝换乘· 4 月前 · |
想旅行的烤土司 · 主向門徒第三次顯現 主的託付 - 台北靈糧堂· 6 月前 · |
幸福的开水瓶 · Creating and running ...· 7 月前 · |
爱健身的眼镜
5 月前 |
|
|
数据源(From) —— 条件(Where) —— 列/表达式 (col/exp) —— Order by — 谓词
From,查询 首先组装初始数据集 。
Where,筛选;筛选过程实际上是 选择符合标准的行的where子句 。
Group by,组合数据的子集 [若要分组, 先对数据排序 ,然后根据排序后的数据进行聚合]
聚合, Aggregations,选择性地对数据进行 聚合 ;如求平均值,按列中的值对数据分组以及筛选组;
Having,筛选数据的子集
列表达式 :处理Select列,并计算任何表达式 [ 这个时候才涉及到列 ]
Order by,排序
Over,窗口函数和排名函数通过与其他聚合函数一起提供结果的 单独排序的视图
Distinct,从结果集中删除任何重复的行
Top, 选定行后 ,执行计算, 并按所需的顺序排序
Insert,Update,Delete,最后一个逻辑步骤是将数据修改操作应用到查询结果。
Output,选择插入和删除的虚拟表,并返回给客户端
Union,堆叠或合并多个查询的结果
Not > 算术运算符(+-) > 条件运算符(where) > And > Or
电脑中字符优先级: 数字>字母
1a > a1 > a11 > aa1
|
|
|
|
使用 “ + ” 连接多个字段, 合并成一列
如果+连接数值类型,结果是数值之和
如果+连接字符串类型,结果是字符串的连接
|
|
|
|
|
|
惊叹号! ,不是ANSI标准的SQL;
|
|
不能在Where 子句中使用聚合函数。此时应用 子查询 来进行限定
|
|
|
|
|
|
if语句之后没有分号 ; if语句实际上是后面语句的提前;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
若要重新定义主键,则必须首先删除与现有主键之间的任何关系,然后才能创建新主键。 此时,将显示一条消息警告您:作为该过程的一部分,将自动删除现有关系。
|
|
|
|
|
|
SQL中合并列,只要选择对应的列即可
Select a.*, b.* From a Full Join b
|
|
|
|
truncate 、delete与drop区别
truncate 和 delete 只删除数据 不删除表的结构(定义) ; drop 语句将删除表的结构 被依赖的约束(constrain)、触发器(trigger)、索引(index);依赖于该表的存储过程/函数将保留,但是变为 invalid 状态。
delete 语句是数据库操作语言(dml),这个操作会放到 rollback segement 中,事务提交之后才生效;如果有相应的 trigger,执行的时候将被触发。 truncate、drop 是数据库定义语言(ddl),操作立即生效,原数据不放到 rollback segment 中,不能回滚,操作不触发 trigger。
delete 语句不影响表所占用的 extent,高水线(high watermark)保持原位置不动。drop 语句将表所占用的空间全部释放。truncate 语句缺省情况下见空间释放到 minextents个 extent,除非使用reuse storage;truncate 会将高水线复位(回到最开始)。
速度:drop> truncate > delete
|
|
|
|
Output子句有一个较为高级的应用,可以把输出数据传输到外查询。
|
|
|
|
|
|
|
|
|
|
|
|
reverse
和
charindex
|
|
|
|
|
|
|
|
length: nchar、nvarchar、char、varchar、binary 或 varbinary 数据类型的可选参数。
style: 日期格式样式,借以将 datetime 或 smalldatetime 数据转换为字符数据(nchar、nvarchar、char、varchar、nchar 或 nvarchar 数据类型);或者字符串格式样式,借以将 float、real、money 或 smallmoney 数据转换为字符数据(nchar、nvarchar、char、varchar、nchar 或 nvarchar 数据类型)。
|
|
Data_type : INT / DECIMAL(10,2) / CHAR() / VARCHAR() /
|
|
可选的参数match_option字符串说明默认的匹配选项。match_option的取值如下:
‘c’ 说明在进行匹配时区分大小写(缺省值);
‘i’ 说明在进行匹配时不区分大小写;
‘n’ (.)点号能表示所有单个字符,包括换行(俺还不知道什么地方有用到换行.只知道sql里面可以用chr(10)表示换行.
‘m’ 字符串存在换行的时候当作多行处理.这样$就可匹配每行的结尾.不然的话$只匹配字符串最后的位置.
|
|
avg( ) $\ge$ $sum( ) \over count(*)$
Count(*),计数时也将NULL计入;Count(Null) 返回0;所有与NULL的计算,都返NULL
其他所有聚合函数,包括Count(col_name)的形式,计算时均已排除了NULL
表a,观测值10行,其中2个NULL;
Count(*) # 返回10;
Count(列名) # 返回8
除非,可用 isnull() 函数进行转换,来计算;
例如,对表a求平均值,若直接用avg() ,其分母为8;
若想使得其分母变成10,应添加 case when isnull(col_name,0) then col_name else end
DATEDIFF | 返回两个日期的 差值 ; datediff(datepart,startdate,endate) | SELECT DATEDIFF(dd, ‘02/05/2003’, ‘02/09/2005’) 返回:735 | DATEPART | 返回指定日期 部分 的整数(整数形式) | SELECT DATEPART(dd, ‘01/09/2003’) 返回:9 | DATENAME | 返回指定日期部分的字符串(字符串形式);工作日(dw)、周(wk)、日(dd)、月(mm) | SELECT DATENAME(dw, ‘02/02/2009’) 返回: 星期一 | Eomonth | 返回针对指定开始日期的月份的最后一天 | Select Eomonth(‘5/27/1998’) | 返回指定日期“年”部分整数 | SELECT YEAR(GETDATE()) 返回:当前年份整数 | MONTH | 返回指定日期“月”部分整数 | SELECT MONTH(GETDATE()) 返回:当前月份整数 | 返回指定日期“日”部分整数 | SELECT DAY(GETDATE()) 返回:当前日期整数 |
|
|
时间戳就是一个从1970-01-01 08:00:00到时间的相隔的秒数
|
|
注解:北京时间与GMT时间关系
1.GMT是中央时区,北京在东8区,相差8个小时
2.所以北京时间 = GMT时间 + 八小时
|
|
|
|
|
|
要注意的是 SET DATEFIRST 只在 当前执行中有效 ,也就说比如新开一个查询页面继续查询 SELECT @@DATEFIRST 则还是显示默认值 7。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在窗口内 分区:Partition by
|
|
ntile函数的分组依据(约定):
首先系统会去检查能不能对所有满足条件的记录进行平均分组,若能则直接平均分配就完成分组了;若不能,则会先分出一个组,这个组分多少条记录呢?就是 (总记录数/总组数)+1 条,之所以分配 (总记录数/总组数)+1 条是因为当不能进行平均分组时,总记录数%总组数肯定是有余的,又因为分组约定1,所以先分出去的组需要+1条。
分完之后系统会继续去比较余下的记录数和未分配的组数能不能进行平均分配,若能,则平均分配余下的记录;若不能,则再分出去一组,这个组的记录数也是(总记录数/总组数)+1条。
举个例子,将53条记录分配成5组,53%5 = 3不能平均分配,则将余数3平均分配到前3组 (余数 = 分配的组数),然后比较余下的 53-(11*3)=20 条记录能否平均分配给未分配的2组,能平均分配,则剩下的2组,每组各20/2=10 条记录,分配完成,分配结果为:11,11,11,10,10。
|
|
case when
最大的优点是可以与Select语句“内联”
若else缺失,表示其他值返回NULL
Case函数只返回第一个符合条件的值,剩下的Case部分将会被自动忽略;
|
|
|
|
|
|
what:将两个数据集相乘,并对结果进行限制。这样只返回两个数据集的交集。
why :横向合并两个数据集,并通过匹配一个数据源的行与另一个数据源的行,从组合中产生新的数据集。
在连接条件中使用等于号(=)运算符,其查询结果中列出被连接表中的所有列, 包括其中的重复列 。
在连接条件中使用除等于号之外运算符(>、<、<>、>=、<=、!>和!<)
|
|
SQL内在处理逻辑:(按照排列顺序进行联接)
可 多条件连接 ;即在原来连接的基础上再进行连接
|
|
what:以一个表为基准表,进行联接;
on a.id <> b.id
,因为会对每一条记录a无法匹配的b表中的行生成一条记录,最后会生成 $a \times b$ 行
|
|
how :无论是否匹配,外联接都包含所有数据
How :数据库在通过连接两张或多张表来返回记录时,都会生成一张 中间的临时表,然后再将这张临时表返回给用户 。
中间表 是 左表与右表的 所有字段
on 与 where 的区别
select * form tab1 left join tab2 on (tab1.size = tab2.size and tab2.name=’AAA’)
表示
同时满足
这两个条件
才能匹配
到记录
(必须用括号
()
括起来)
,但条件不为真也会返回左表中的记录;
关于 “A LEFT JOIN B ON 条件表达式” 的一点提醒
ON 条件( “A LEFT JOIN B ON 条件表达式” 中的 ON )用来决定如何从 B 表中检索数据行。
如果 B 表中没有任何一行数据匹配 ON 的条件,将会额外生成一行所有列为 NULL 的数据
在匹配阶段 WHERE 子句的条件都不会被使用。仅在匹配阶段完成以后, WHERE 子句条件才会被使用。它将从匹配阶段产生的数据中检索过滤。
|
|
其实以上结果的关键原因就是 left join,right join,full join 的特殊性,不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。 而inner jion没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。
当涉及多个联接时
一定要用较小规模的数据对查询进行单元测试;
并坚持使用左外联接
外联接中的条件设置(执行逻辑)
|
|
Left [Outer] Join
必须要表基准表放在左侧,非常重要!否则会产生大量NULL值。
Right [Outer] Join
建议左/右外联接不要混合使用
Full [Outer] Join
涉及where子句,
or的条件子句
一定要用括号
()
括起来
|
|
|
|
注意 Where 之后 没有限定列名 , 条件限定在 子查询中
|
|
|
|
列的xml数据类型必须为等效。
所有的列必须类型化为 XML 架构或是非类型化的。 如果要类型化,这些列必须类型化为相同的 XML 架构集合。
what:子查询是独立运作的;
how :运行逻辑
|
|
,
;并且后面的CTE可以引用在它之前定义的任何CTE
|
|
|
|
|
|
|
|
UNPIVOT 并不完全是 PIVOT 的逆操作。PIVOT 会执行一次聚合,从而将多个可能的行合并为输出中的单个行。而 UNPIVOT 不会重现原始表值表达式的结果,因为行已经被合并了。另外,UNPIVOT 的输入中的空值不会显示在输出中,而在执行 PIVOT 操作之前,输入中可能有原始的空值。
数据清洗
去重复值
12 --Distinct # 去除完全重复的值SELECT DISTINCT 机构 FROM allzjb ;
1234567 --Row_number() over(partation by col1 order by col2) 某个字段有重复值--【先根据某相同字段分组,根据其他字段排序,创建临时表;在提取排序=1的信息】# 对于相同的交易账号,取激活时间最前面的那一个账户的相关信息;Select *, Row_number() Over(partition by 交易账号 order by 激活时间) as 排序 Into #11From exchange.ytx.ext_激活客户归属表;Select * Into #2 From #11 where 排序 = '1';- what:空值NULL表示 不存在的值,是一个未知值 ;并不表示0;
- how :包含 空值的任何表达式结果均是一个未知值
- Null + 1 = Null
Count( * ) 会计算空值;但Count( col )会排除空值
123456 # 测试空值 - IS NULLSELECT * FROM allzjb where 机构 is null ;-------------------------------------------------------# ISNULL 将NULL替换为某个值SELECT AVG(ISNULL(Weight, 50)) FROM Production.Product; # 将Weight中的NULL替换为50- isnull(col, 0 ):将col列中NULL值替换为0
12345678910111213 ## 处理空值# Isnull() --将NULL替换为某个值Select Isnull(col, 0) -- 对col列进行搜索,并将空值NULL转换为0;也可以是其他任意值/字符串--isnull(soucre_expression, prlacement_value) # isnull是T-SQL特有的函数-----------------------------------------------------------------------------# Coalesce()Select Coalesce(Null, Null+1, 1+2, "abc") 返回3--Coalesce(expression, expression,... ) # 接受一系列表达式或列,返回第一个非空值-----------------------------------------------------------------------------# Nullif()NULL :未定义的值 / 不存在
NA :缺失数据
NaN :无意义的数,比如sqrt(-2), 0/0。
Inf :正无穷大
-Inf :负无穷大表是否存在
123456789101112 # SQL SERVER中查询某个表或某个索引是否存在IF OBJECT_ID(N'表名称', N'U') IS NOT NULLDROP TABLE 表名称;--注意,普通表和临时表的使用差别:--若希望删除TEST库中的dbo.TestTable表,直接将dbo.TestTable作为表名即可。--若希望删除临时表dbo.#temp_table,需要以tempdb.dbo.#temp_table作为表名。# 查询表上的某个索引是否存在SELECT 1 FROM sys.indexes WHERE object_id=OBJECT_ID(@tname, N'U') and NAME=@iname其中:@tname表示建索引的表名,@iname表示索引名。在每一个数据库中都有sys.sysobjects用于包括在数据库中创建的每个对象(例如约束、默认值、日志、规则以及存储过程)。详细的说明信息参看MSDN上的帮助文档:sys.sysobjects
OBJECT_ID 的作用是 返回架构范围内对象的数据库对象标识号 。如果找不到数据库或对象的名称,例如相应名称不存在或拼写不正确,则会返回NULL。
sys.indexes 用于保存每 个表格对象 (例如,表、视图或表值函数)的 索引或堆 ,详细的说明信息参看MSDN上的帮助文档:sys.indexes
数据运算与其他
两行观测值相减
1234567 --根据某个字段先排序进行编号,创建为#a1;复制为另一个表#a2;通过联合,使得联合的条件为 #a1.rank+1 = #a2.rankSelect *, order by 成交时间 as rank --报错into #a1 From [exchange].[YTX].[v_allcj] as cj;Select * into #a2 From #a1;Select a1.*, datediff(ss,#a1.成交时间,#a2.成交时间) s [交易间隔(s)] From #a1Left join #a2 On #a1.rank = #a2.rank +1
12345678910111213 ----根据某个字段【分组】后排序编号;再通过唯一列联接,再设置条件 a.rank+1=b.rank 进行相减 【理论上应该是 a.rank=b.rank+1】--若a.rank=b.rank+1, 表示a表的rank=1 与b表的rank=2比较;--若a.rank+1=b.rank,表示a表的rank=1 变更为rank=2 与表b进行比较Select *, Row_number() over(partition by 交易账号 order by 成交时间) as [rank] into #a1From [exchange].[YTX].[v_allcj] as cj;Select * into #a2 From #a1;Select #a1.*, datediff(ss,#a1.成交时间,#a2.成交时间) as [交易间隔(s)] From #a1Left join #a2 On #a1.交易账号 = #a2.交易账号where #a1.rank+1 = #a2.rankand datediff(ss,#a1.成交时间,#a2.成交时间) < '60'已知交易日计算差值
123456 # 已知交易日,计算未交易的交易日间隔;Select Max(结算日期) As 最后交易日期 FromSelect Count(1) From -----------计数Inner Join b On 最后交易日 < 结算日期判断表单存在并删除
12 If Object_id(N'tempdb.dbo.#b1',N'U') Is Not Null Drop table #b1--若非临时表,无需加 数据库名计算累加和
12 Select Sum([求和列]) Over(Partition by [分组列] Order by [排序列])From ...选取重复值
- 通过
group by
之后having count(*)>1
来进行筛选
123456789101112131415161718 --1.查某一列(或多列)的重复值(只可以查出重复记录的值---查找stuid,stuname重复的记录Select stuid,stunamefrom stuinfogroup by stuid,stunamehaving(count(*))>1--2.查某一列有重复值的记录 (所有重复的记录,如果有两条记录重复的,就查出两条))--查找stuid重复的记录select * from stuinfowhere stuid in (select stuid from stuinfo group by stuid having(count(*))>1 )/*--3.查某一列有重复值的记录(只显示多余的记录,也就是说如果有三条记录重复的,就显示两条) —— 实际意义??--查找stuid重复的记录; 前提:需有一个不重复的列,此示例为recno。select * from stuinfo s1where recno not in (select max(recno) from stuinfo s2 where s1.stuid=s2.stuid)*/取出一个字符串中最后一个特殊字符右边的字符
- 涉及 翻转
reverse
和charindex
12345678 DECLARE @aa VARCHAR(30)SET @aa = '10*20*300'-- 取最后一个*后的所有字符SELECT RIGHT(@aa, CHARINDEX('*',REVERSE(@aa)) - 1)-- 取定长字符串,如*后的3个字符SELECT SUBSTRING(@aa, LEN(@aa) - CHARINDEX('*',REVERSE(@aa)) + 2, 3)问题 - 函数的长度参数无效
- 用逗号的位置得到的参数-1后是负数,不能做 LEFT和SUBSTRING的参数。
通过排序来进行查看,并且用Where进行限定
12345 Select *, Convert(varchar(10), createTime, 120) As createTime2, left(department, charindex('后', department,1)-1) As 老师From [crm].[YTX].[t_wx_contact_monitor]where tag = 'v11.JY.JY-QH-WECHAT-QY.0' and error_code= 0and charindex('后', department,1)-1 >0问题 - 遇到 “遇到以零作除数错误”
- 屏蔽了“遇到以零作除数错误” 的错误信息,这样的话,遇到0是除数的情况,就是赋值为Null
12345678910 SET ANSI_WARNINGS OFF;SET ARITHIGNORE ON;SET ARITHABORT OFF;GOSELECT 1 / 0SELECT Total/CountNr FROM dbo.TmpA1-----------NULL系统查询相关
通过字段找表名
1234 ------SELECT sb.nameFROM syscolumns s JOIN sysobjects sb ON s.id=sb.idWHERE s.name='你的字段名'--
双连字符;从开始到行尾均为注释; 对于多行注释,必须在每一个开头多使用/*……*/
正斜杠 星号;
憨厚的冲锋衣 · Fun0nydg的博客 - 个人随笔 6 天前 |
大力的松鼠 · Mysql比较日期和时间 - 6 天前 |
求醉的长颈鹿 · 蓝奏云lsp软件合集网站 2 月前 |
爱笑的草稿纸 · 沈阳西站新民北站高铁与公交将无缝换乘 4 月前 |
想旅行的烤土司 · 主向門徒第三次顯現 主的託付 - 台北靈糧堂 6 月前 |