一个1年前的T-SQL问题
还记得年前的一个SQL问题,当时对SQL刚接触,因此绕开了它。用了别的办法。昨天看SQL突然想起了这个问题。百思不得其解,然后去SQL Server技术交流群,也请教了,大神高文佳,何志勇提示我因为先分组然后再链接。但由于小弟技术是在是太菜,因此没能弄出我想要的结果来。后来由于太晚的原因或者是问题太简单(当然大神们实在是很热情),大神们都睡觉了。今天还是在纠结这个问题的解决方法。
先给出测试用的初始化表和数据:
CREATE TABLE [dbo].tab_1(
[Id] [int] NOT NULL,
[SkillId] [int] NOT NULL
) ON [PRIMARY] CREATE TABLE [dbo].tab_2(
[Id] [int] NOT NULL,
[SkillId] [int] NOT NULL
) ON [PRIMARY] GO insert into tab_1 values(1,1)
insert into tab_1 values(1,2)
insert into tab_1 values(2,1)
insert into tab_1 values(2,3)
insert into tab_1 values(2,6) insert into tab_2 values(5,1)
insert into tab_2 values(5,2)
insert into tab_2 values(5,4)
insert into tab_2 values(7,1)
insert into tab_2 values(7,3)
insert into tab_2 values(7,6)
查询表数据如下:
tab_1
tab_2
问题1:现在的问题是想查出这部分数据(语言表达能力不好,我就直接给图了^_^):

也就是每组根据Id分组后,取tab_1和tab_2有完全相同的SkillId分组项。
开始就一直思考如何用分组、联接来实现。后来发现有各种不同的问题(当然是我的问题),最终换了思路,将每个表根据主键分组(为了测试方便我没有设主键),然后使用合并列的方法来曲线实现了一下:
with cte1 as(
select Id, stuff((select ','+ CONVERT(varchar,SkillId) from tab_1 t where t.Id=t1.Id for xml path('')),1,1,'') as Skills from tab_1 t1
group by Id
),
cte2 as(
select Id, stuff((select ','+ CONVERT(varchar,SkillId) from tab_2 tt where tt.Id=tt1.Id for xml path('')),1,1,'') as Skills from tab_2 tt1
group by Id
)select * from cte1 join cte2 on cte1.Skills=cte2.Skills
但是我想这个方法是不好的。因为如果此时我给表tab_1添加一列:
insert into tab_1 values(2,5)
问题2:我想取出这部分数据:

也就是每组根据Id分组后,判断tab_1的某个分组的SkillId是否完整包含tab_2的某个分组的SkillId。这个时候再用分组合并的办法就不管用了。
当然呢,大神们很快就发现了使用charindex来实现:
with cte1 as(
select Id, stuff((select ','+ CONVERT(varchar,SkillId) from tab_1 t where t.Id=t1.Id for xml path('')),1,1,'') as Skills from tab_1 t1
group by Id
),
cte2 as(
select Id, stuff((select ','+ CONVERT(varchar,SkillId) from tab_2 tt where tt.Id=tt1.Id for xml path('')),1,1,'') as Skills from tab_2 tt1
group by Id
)select * from cte1 join cte2 on CHARINDEX(cte2.Skills,cte1.Skills)=1
以上只是用到了SQL Server的for xml path()列转行,stuff()字符串函数截取以及charindex()字符串函数来比较字符串。
另外根据@小飞虾、@小不正经提供的思路:
1.对2各表分别根据主键字段组内排序计算出每组的总数
2.对结果1的2个表根据关联字段SkillId进行表联接,并根据1中2个表的主键字段进行组内排序,计算出此结果集的每组的总数
3.将2得出的结果集进行条件运算。如果问题1的要求则用等号计算;如果是问题2的要求则用>=计算。T-SQL如下:
with cte1 as(
select id,SkillId,count(1) over (partition by Id) as count1 from tab_1
),cte2 as(
select id,SkillId,count(1) over (partition by Id) as count2 from tab_2
),cte3 as(
select cte1.Id,cte1.Skillid,count1,cte2.Id as Id2,cte2.SkillId as SkillId2,cte2.count2,
COUNT(1) over (partition by cte1.Id,cte2.Id) as count3
from cte1 full join cte2
on cte1.SkillId=cte2.SkillId
)select Id,SkillId,Id2,SkillId2 from cte3
where count1 >=count2 and count3 >=count2
那么有什么更多的好的办法没有呢?肯定是有的对吧。请各抒己见,在此肯求大伙儿热心指教。不胜感激!
一个1年前的T-SQL问题的更多相关文章
- 如果一条SQL语句太长,我们可以通过回车键来创建一个新行来编写SQL语句,SQL语句的命令结束符为分号(;)。
1.如果一条SQL语句太长,我们可以通过回车键来创建一个新行来编写SQL语句,SQL语句的命令结束符为分号(;). 2.select查询的多个字段之间要用逗号“,”分割,如果查询涉及多个表,那多个表之 ...
- 为什么我要使用一个20年前的IBM老键盘
为什么我要使用一个20年前的IBM老键盘 发表在 心得体会 | 3条评论 几天前,我在网上发了一张图片,想炫耀了一下我的新MacBook Pro笔记本强悍的多屏功能.没人感兴趣.但图上的那个老键盘却得 ...
- 一个看似很简单的SQL却难倒了很多人
一个选课表,有学生id,课程id,老师id,要求选出同时选了语文和数学的学生 USE [tempschool] GO /****** 对象: Table [dbo].[SelectC] 脚本日期: 0 ...
- 通过一个小问题来学习SQL关联查询
原话题: 是关于一个left join的,没有技术难度,但不想清楚不一定能回答出正确答案来: TabA表有三个字段Id,Col1,Col2 且里面有一条数据1,1,2 TabB表有两个字段Id,Col ...
- 一个简单的ORM制作(SQL帮助类)
一个简单的ORM制作大概需要以下几个类: SQL执行类 CURD操作类 其他酱油类 先从SQL执行类说起,可能会涉及数据库的迁移等问题,所以需要定义一个接口以方便迁移到其他数据库, 事务没提供命名,若 ...
- 一个令人困惑的低效SQL
整理之前的优化案例,觉得下面这个应该是开发很难发现也会很困惑的一个低效SQL. 看下面这个SQL.你看到这个SQL会不会感觉很正常.其实我刚看到也觉得正常得不得了.但是测试后它确实效率很低.selec ...
- 一个能够编写、运行SQL查询并可视化结果的Web应用:SqlPad
SqlPad 是一个能够用于编写.运行 SQL 查询并可视化结果的 Web 应用.支持 PostgreSQL.MySQL 和 SQL Server.SqlPad 目前仅适合单个团队在内网中使用,它直接 ...
- 一个关于考勤统计的sql研究
在这里,我们要做一个简单的员工考勤记录查询系统的后台数据库.业务需求如下所示: 1.统计每天来的最早.来的最晚.走的最早.走得最晚的人的姓名 1.1 统计每天来得最早的人 ...
- mybatis前台传来一个String,后后台执行sql变成了true
实际上参数传来的是一个字符串 3 ,不知道为什么会变成true 最后当然是查不到信息了.. 我在mapper映射文件里面使用了动态的where查询,我觉得跟这个关系不太大, 现在不知道怎么办,希望有思 ...
随机推荐
- Windows Phone & Windows App应用程序崩溃crash信息抓取方法
最近有用户反馈,应用有崩溃的情况,可是本地调试却无法重现问题,理所当然的,我想到了微软的开发者仪表盘,可以查看一段时间内的carsh记录,不过仪表盘生成carsh记录不是实时的,而且生成的报告查看非常 ...
- PHP Yii1.1.13(一):命令行创建应用~shop
第一节 初始目录结构 (1)初识目录结构 在创建应用之前,我们来看一下Yii 1.x版本的目录结构:将yii-1.1.13安装文件解压到网站根目录下,打开framework目录,其目录如下图所示 (2 ...
- Bootstrap3.0学习第二十六轮(JavaScript插件——图片轮播)
详情请查看http://aehyok.com/Blog/Detail/32.html 个人网站地址:aehyok.com QQ 技术群号:206058845,验证码为:aehyok 本文文章链接:ht ...
- HTML5开发注意事项及BUG解决
1.点透Q:元素A上定位另外一个元素B,点击元素B,如果元素A有事件或链接,会触发元素A上的事件或链接,即点透A:在元素B的touchend中增加ev.preventDefault();阻止默认事件即 ...
- Spring-事物配置
Spring框架支持事务管理的核心是事务管理器抽象,对于不同的数据访问框架(如Hibernate)通过实现策略接口PlatformTransactionManager,从而能支持各种数据访问框架的事务 ...
- 【bzoj1502】 NOI2005—月下柠檬树
http://www.lydsy.com/JudgeOnline/problem.php?id=1502 (题目链接) 今天考试题,从来没写过圆的面积之类的东西..GG 题意 一颗树由n个圆台组成,现 ...
- IIS7部署项目时提示:"错误消息 401.2。: 未经授权: 服务器配置导致登录失败。"的解决办法
这个错误的定位:你的站点使用了Forms验证,而且在部署在生产环境的时候,设置错误,或者注释了. 解决方法如下: 1.检查Forms配置是否屏蔽. 2.有权限访问的资源是否已经开发. 基本就围绕以上两 ...
- make xconfig时,出现“Unable to find any QT installation"错误
在make menuconfig的时候,提示是找不到libncurses,最后其实是找不到libncurses-dev,又因为debian系统装的是libncurses5,所以装了libncurses ...
- Oracle DBA从小白到入职实战应用
现如今Oracle依然是RDBMS的王者,在技术上和战略上,Oracle仍然一路高歌猛进,并且全面引领行业迈入了云时代,伴随着12cR2即将在2016年正式发布,学习Oracle之路依旧任重道远,目前 ...
- MySQL 中 where id in (1,2,3,4,...) 的效率问题讨论
MySQL ACMAIN_CHM06-26 16:36 等级 84次回复 [求证&散分]MySQL 中 where id in (1,2,3,4,...) 的效率问题讨论 庆祝本月大版得 ...