sql的常用拼接
最近过得不好,失恋,转行,靠雅思一大堆事情都过来;弄得人没有心思
搞开发,不过还好,总算熬过来了;
最近在搞sql,感觉原先对一些sql原理不是很懂,现阶段可以重新温习下.
常用sql拼接
group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator '分隔符'])
-- 表结构
CREATE TABLE `t2` (
`uid` bigint(20) DEFAULT NULL,
`vv` varchar(50) DEFAULT NULL,
`bid` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`bid`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
-- 数据
insert into `t2`(`uid`,`vv`,`bid`) values (1,'m1',1),(1,'m2',2),(1,'m3',3),(2,'n1',4),(3,'l1',5);
-- 执行的sql
SELECT uid ,GROUP_CONCAT( vv ORDER BY bid DESC SEPARATOR "@@" ) AS vv FROM t2 GROUP BY uid;
left join inner join on 位置的区别对结果造成的影响
-
对于left join,不管on后面跟什么条件,左表的数据全部查出来,因此要想过滤需把条件放到where后面
-
对于inner join,满足on后面的条件表的数据才能查出,可以起到过滤作用。也可以把条件放到where后面。
left join inner join 遇到一对多情况
关于distinct 去重复
distinct 去重复是对于相同结果的 ,如果多个字段结果不一致,不会达到去重的效果
子查询
我们进行数据查询的时候极少有可能就在一张表里就能得到想要的数据,不可避免得会用到子查询或者连接查询,很多时候我们很轻松自然得会想到子查询的方法,但是子查询往往效率比较低,而转换成连接查询是一种很好的优化方式。
- 当一个查询是另一个查询的条件时,称之为子查询。
- 子查询都可以使用连接查询来替换
union all 和 union 区别
- UNION 操作符用于合并两个或多个 SELECT 语句的结果集
- UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL
- 理论上单纯的union all应该比union速度快,因为union还要去除相同的记录
sql执行顺序以及on和where的区别
T-SQL在查询各个阶级分别干了什么:
(1)FROM 阶段
FROM阶段标识出查询的来源表,并处理表运算符。在涉及到联接运算的查询中(各种join),主要有以下几个步骤:
a. 求笛卡尔积。不论是什么类型的联接运算,首先都是执行交叉连接(cross join),求笛卡儿积,生成虚拟表VT1-J1。
b.ON筛选器。这个阶段对上个步骤生成的VT1-J1进行筛选,根据ON子句中出现的谓词进行筛选,让谓词取值为true的行通过了考验,插入到VT1-J2。
c.添加外部行。如果指定了outer join,还需要将VT1-J2中没有找到匹配的行,作为外部行添加到VT1-J2中,生成VT1-J3。
经过以上步骤,FROM阶段就完成了。概括地讲,FROM阶段就是进行预处理的,根据提供的运算符对语句中提到的各个表进行处理(除了join,还有apply,pivot,unpivot)
(2)WHERE阶段
WHERE阶段是根据<where_predicate>中条件对VT1中的行进行筛选,让条件成立的行才会插入到VT2中。
(3)GROUP BY阶段
GROUP阶段按照指定的列名列表,将VT2中的行进行分组,生成VT3。最后每个分组只有一行。
(4)HAVING阶段
该阶段根据HAVING子句中出现的谓词对VT3的分组进行筛选,并将符合条件的组插入到VT4中。
(5)SELECT阶段
这个阶段是投影的过程,处理SELECT子句提到的元素,产生VT5。这个步骤一般按下列顺序进行
a.计算SELECT列表中的表达式,生成VT5-1。
b.若有DISTINCT,则删除VT5-1中的重复行,生成VT5-2
c.若有TOP,则根据ORDER BY子句定义的逻辑顺序,从VT5-2中选择签名指定数量或者百分比的行,生成VT5-3
(6)ORDER BY阶段
根据ORDER BY子句中指定的列明列表,对VT5-3中的行,进行排序,生成游标VC6.
如果On和where只能选其一的话:
先进行on的过滤, 而后才进行join, 这样就避免了两个大表产生全部数据的笛卡尔积的庞大数据.
这些步骤执行时, 每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应用程序或者外部查询)不可用。只是最后一步生成的表才会返回 给调用者。
如果没有在查询中指定某一子句,将跳过相应的步骤。
那 on 和where 那个更高效呢
如果是inner join, 放on和放where产生的结果一样, 但没说哪个效率速度更高? 如果有outer join (left or right), 就有区别了, 因为on生效在先, 已经提前过滤了一部分数据, 而where生效在后.
综合一下, 感觉还是放在on里更有效率, 因为它先于where执行.
先笛卡尔积, 然后再on过滤, 如果join是inner的, 就继续往下走, 如果join 是left join, 就把on过滤掉的左主表中的数据再添加回来; 然后再执行where里的过滤;
on中不是最终过滤, 因为后面left join还可能添加回来, 而where才是最终过滤.
只有当使用外连接(left, right)时, on 和 where 才有这个区别, 如果用inner join, 在哪里制定都一样, 因为on 之后就是where, 中间没有其它步骤.
总的说来
- 先进行on的过滤, 而后才进行join, 这样就避免了两个大表产生全部数据的笛卡尔积的庞大数据.
- 最后都是要最后的结果,on where 放在那里都是一样的 ;不存在inner join 和 left join 因为位置的不同而造成结果的不同