同一类型取1-N条记录
来源:互联网 发布:js取input输入框的值 编辑:程序博客网 时间:2024/04/27 21:04
/*================fcuandy========2008.1.23================*/CREATE TABLE ta(id INT IDENTITY(1,1),cid INT,name VARCHAR(10))GOINSERT ta SELECT 1,'a'UNION ALL SELECT 1,'b'UNION ALL SELECT 1,'c'UNION ALL SELECT 2,'d'UNION ALL SELECT 3,'e'UNION ALL SELECT 3,'f'GO/*示例 1同一分类中取1条或n条。单表及多表的写法*/-------------------------------------------------------------以ta为例,cid为分类id,每个id取一条,我以取最小id为约束条件SELECT a.* FROM ta a WHERE NOT EXISTS(SELECT 1 FROM ta WHERE cid=a.cid AND id<a.id)SELECT a.* FROM ta a WHERE 1>(SELECT COUNT(*) FROM ta WHERE cid=a.cid AND id<a.id)SELECT a.* FROM ta a WHERE id IN (SELECT TOP 1 ID FROM ta WHERE cid=a.cid ORDER BY id)SELECT a.* FROM ta a WHERE id = (SELECT TOP 1 ID FROM ta WHERE cid=a.cid ORDER BY id)SELECT a.* FROM ta a WHERE id IN (SELECT MIN(ID) FROM ta WHERE cid=a.cid)SELECT a.* FROM ta a WHERE id = (SELECT MIN(ID) FROM ta WHERE cid=a.cid)SELECT a.* FROM ta aINNER JOIN (SELECT MIN(id) mi FROM ta GROUP BY cid) b ON id = mi--etc.其它的组合写法再不累赘--以cid为分类,每个cid取id最小的2条记录,2可以适当修改SELECT a.* FROM ta a WHERE 2>(SELECT COUNT(*) FROM ta WHERE cid=a.cid AND id<a.id)SELECt a.* FROM ta a WHERE id IN (SELECT TOP 2 ID FROM ta WHERE cid=a.cid ORDER BY ID)SELECT a.* FROM ta aINNER JOIN (SELECT ID,CNT=(SELECT COUNT(*) FROM ta WHERE cid=x.cid AND id<x.id) FROM ta x) b ON a.id = b.id AND cnt<2--etc.其它的组合写法再不累赘--上面是针对ta单表。 如果多表,下面以二表为例CREATE TABLE tb(cid INT,className VARCHAR(10))GOINSERT tb SELECT 1,'A'UNION ALL SELECT 2,'B'UNION ALL SELECT 3,'C'GO--ta,tb以cid关联,取每个cid中id最小的一条记录,需要 tb.className,tb.cid,ta.id,ta.name列。SELECT b.*,a.* FROM tb bINNER JOIN ta a ON a.cid = b.cid WHERE NOT EXISTS(SELECT 1 FROM ta WHERE cid=a.cid AND id<a.id)GO--多表与单表取数思路一对致,多一次连表操作,可以照上面单表的把其它写法改出来.--同样,取每个cid中id最小的前n条记录,一样的方法--需要注意的是连表时,可以用内连,左连,或是老式的多表写法(from ta ,tb where ta.cid=tb.cid默认转换为内连),采用哪种方式依具你的业务需求。----------------------------------------------------------/*示例 2所谓的多行同组合并*/--以ta为例,以cid分组合并,产生如下的数据结果/*cid nameS1 a,b,c2 d3 e,f*/--函数实现CREATE FUNCTION myJoinSTR(@cid INT)RETURNS VARCHAR(1000)ASBEGIN DECLARE @s VARCHAR(1000) SELECT @s=ISNULL(@s+',','') + name FROM ta WHERE cid = @cid RETURN @sENDGOSELECT DISTINCT cid,dbo.myJoinSTR(cid) nameS FROM taGO/*示例 3列拆分为行.以上例生成的数据格式为示例表,将a,b,c以,分融成行,即上个示例的反操作*/SELECT DISTINCT cid,dbo.myJoinSTR(cid) nameS INTO tx FROM taGOSELECT * FROM txGO--以系统表构建identity列,并以连表方式来将列拆成行SELECT IDENTITY(INT,1,1) id INTO # FROM syscolumns,sysobjectsSELECT id,cid,RIGHT(STUFF(nameS+',',id,LEN(names),''),CHARINDEX(',',REVERSE(STUFF(','+nameS+',',id,LEN(names),'')))) name FROM tx aINNER JOIN # b ON SUBSTRING(names+',',id,1)=','ORDER BY cid--以动态语句或循环,或函数的方式略去/*示例 4行转列这是论坛上问的最多的,没啥好说的,照猫画虎。*/--单表,以ta为例. 静态行转列,设cid所有出现的可能值已知SELECT cid_1=MAX(CASE WHEN cid=1 THEN name ELSE NULL END), cid_2=MAX(CASE WHEN cid=2 THEN name ELSE NULL END), cid_3=MAX(CASE WHEN cid=3 THEN name ELSE NULL END) FROM ta --单表,以ta为例,动态行转列,设cid所有出现的可能值未知DECLARE @s VARCHAR(8000)SET @s=''SELECT @s=@s + ',cid_' + RTRIM(cid) + '= MAX(CASE WHEN cid=' + RTRIM(cid) + ' THEN name ELSE null END) ' FROM ta GROUP BY cidSELECT @s='SELECT ' + STUFF(@s,1,1,'') + ' FROM ta'--你可以在这里PRINT @s 看看,就知道跟上面的静态行转列一样的了。 会写静态行转列,就没理由写不出动态的。多表的同理,把多表的静态行转列写出来,那么动态的也就出来了EXEC(@s)GODROP TABLE tx,#GODROP TABLE ta,tbDROP FUNCTION myJoinSTRGO
- 同一类型取1-N条记录
- ORACLE同一次查询取同一字段的前(后)N条记录
- 数据库取n-m条记录
- SQL 取n到m条记录
- mysql分组取前n条记录
- Oracle取TOP N条记录
- db2取前n条记录
- oracle 取前N条记录
- 取N到M条记录 取中间几条记录
- 取客户端数据集中前N条记录
- 取数据库表前N条记录,对于的SQL
- 取n到m条记录的语句
- 关于取表的前N条记录
- 取n到m条记录的语句
- 取n到m条记录的语句
- 随机从oracle数据库取N条记录
- 分组取前n条记录的实现
- 分组取最大N条记录方法征集
- 展开和折叠GridView行
- 正式在CSDN安家了
- 关于为自驾游爱好者提供一个旅游景点查询网站的想法
- 可怕的骗局大荟萃——朋友们千万注意
- 你能够放弃吗
- 同一类型取1-N条记录
- C#编程获取IP地址、子网掩码、网关地址
- JAVA 异常中 throw 和 throws怎么用
- .NET中大写的Object和小写的object类有什么区别?
- 朋友之道
- 定时器是线程的一种
- 回头看看JAVA重载
- Ext中获取节点对象的方法分析
- js 替换链接函数