SQLServer中的交叉查询

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQLServer中的交叉查询相关的知识,希望对你有一定的参考价值。

数据
货号 品名
1 A
1 AB
1 ABB

2 B
2 BC
转化为
货号 品名1 品名2 品名3(可能有品名4等,但不会超过10个)
1 A AB ABB

2 B BC

Access中可以通过transform和dsum的配合来做,不知道SQLServer中怎么比较简单的来完成这个转换呢。
这是样本数据,实际数据是十万的级别,游标我知道可以用,但不知道有没有更简单的方法,比如类似于access transform函数和dsum函数综合运用然后几行语句即可算出.

没有直接的转换方法,建议这样:

select 货号,品名=dbo.shfcoltostr(货号) from TABLENAME

输出结果

货号    品名
1        A ,           AB,         ABB    
2        B ,           BC

前题条件:在查询分析器中执行建立以下自定义函数

CREATE function shfColToStr
(@HH varchar(18))
returns varchar(5000)
begin
declare @result varchar(5000)
select @result=isnull(@result+',','')+品名 from TABLENAME where 货号=@HH 
return @result
end
go

 OK 了没有啊?

好吧,再给你一个方法,与你的要求分毫不差:


需要先根据品名或品名ID生成一个按货号分组的序号,存到临时表,以最多10个品名为例:

临时表生成:

SELECT *,SN=(SELECT COUNT(1) FROM TABLENAME A WHERE A.品名>=tablename.品名 and a.货号=tablename.货号) into #tablename FROM TABLENAME

看看这个临时表,多出了一个SN(序号),然后用下面的语句查询:

select DISTINCT t.货号,
品名1=isnull((select top 1 a.品名 from #tablename a where a.货号=t.货号 and a.sn=1),''),
品名2=isnull((select top 1 a.品名 from #tablename a where a.货号=t.货号 and a.sn=2),''),
品名3=isnull((select top 1 a.品名 from #tablename a where a.货号=t.货号 and a.sn=3),''),
品名4=isnull((select top 1 a.品名 from #tablename a where a.货号=t.货号 and a.sn=4),''),
品名5=isnull((select top 1 a.品名 from #tablename a where a.货号=t.货号 and a.sn=5),''),
品名6=isnull((select top 1 a.品名 from #tablename a where a.货号=t.货号 and a.sn=6),''),
品名7=isnull((select top 1 a.品名 from #tablename a where a.货号=t.货号 and a.sn=7),''),
品名8=isnull((select top 1 a.品名 from #tablename a where a.货号=t.货号 and a.sn=8),''),
品名9=isnull((select top 1 a.品名 from #tablename a where a.货号=t.货号 and a.sn=9),''),
品名10=isnull((select top 1 a.品名 from #tablename a where a.货号=t.货号 and a.sn=10),'')
from #tablename t

看上去复杂,写起来容易,只需复制  复制 <品名n=....sn=n>10次,然后改品名后缀和SN值即可。

结果:

货号 品名1 品名2 品名3 品名4 品名5 品名6 品名7 品名8 品名9 品名10 
1    A     AB    ABB    
2    B     BC

参考技术A

--楼下的 不知道 就说没有 误导人啊

select 货号,(select '   '+品名 from tbname b where a.货号=b.货号 for XMl path('')) newcol

from tbname a

group by 货号


--刚才看错问题了 再修正一下 不明白可以随时问我

with tt as(select *,ROW_NUMBER() over (PARTITION by 货号 order by 品名) bz from tbname)

select 货号,MAX(品名1) 品名1,MAX(品名2) 品名2,MAX(品名3) 品名3 from (

select 货号, case when bz=1 then 品名 else '' end as 品名1

, case when bz=2 then 品名 else '' end as 品名2

, case when bz=3 then 品名 else '' end as 品名3 from tt) bb

group by 货号

追问

因为我这里只是举个例子,实际的货号数据达数十万条,所以无法用case语句来这样去做的。

追答

那就用游标啊 可以遍历

如何使用sqlserver 2012 空间查询(geometry及 geography)

---恢复内容开始---

介绍

SQL Server 2008为大地测量空间数据提供了geography数据类型为平面空间数据提供了geometry数据类型。这两个都是Microsoft .NET Framework通用语言运行时(CLR)类型,并且可以用来存储不同种类的地理元素,例如点、线和多边形。这两个数据类型都提供了你可以用来执行空间操作的属性和方法,例如计算位置间的距离和找出两者间交叉的地理特性(例如一条河流经一个城镇。)

geography 数据类型

geography数据类型为空间数据提供了一个由经度和纬度联合定义的存储结构。使用这种数据的典型用法包括定义道路、建筑、或者地理特性如可以覆盖到一个光栅图上的向量数据,它考虑了地球的弯曲性,或者计算真实的圆弧距离和空中传播轨道,而这些在一个平面模型中所存在的固有失真引起的错误程度是不可接受的。

 

geometry数据类型

geometry数据类型为空间数据提供了一个存储结构,它是由任意平面上的坐标定义的。这种数据通常是用在区域匹配系统中的,例如由美国政府制定的州平面系统,或者是不需要考虑地球弯曲性的地图和内层布置图。

 

geometry 数据类型提供了与开放地理空间联盟(OGC)Simple Features Specification for SQL标准结合的属性和方法,使得你可以对geometry数据执行操作以产生行业标准的行为。

 

使用(sql语句)

geography 数据类型使用

将数据(wkt)直接转换geography 字段类型

DECLARE @bigGeo geography = geography::STPointFromText(‘POINT (120.280994531787670 36.193256972700624)‘,4326);

将数据(wkt)直接转换geometry字段类型

DECLARE @bigGeo geometry= geometry::STPointFromText(‘POINT (120.280994531787670 36.193256972700624)‘,4326);

进行空间查询

table1:表一

table2:表二

a.Geom 表一中geometry类型字段

b.location 表二中geometry类型字段

select * from table1 a,table2 b where a.Geom.STContains(b.location)=1

 

geography 类型相同

 

---恢复内容结束---

以上是关于SQLServer中的交叉查询的主要内容,如果未能解决你的问题,请参考以下文章

sqlserver 的交叉连接和内部连接有啥区别吗?

关于sqlserver 的一个查询, 解决再加50分

如何使用sqlserver 2012 空间查询(geometry及 geography)

关联两个表有几种方法,比如说是sqlserver数据库的关联方式

sqlserver 交叉去重

SQLServer连接查询之Cross Apply和Outer Apply的区别及用法