SQL Server中的Join和Pivot语句
我想从3个表中选择透视和连接 表1:INT、VARCHAR、FLOAT 表2:INT、VARCHAR、FLOAT 表3:INT、VARCHAR、FLOAT 输出表: 我将3个不同表的列的“名称”替换为数字 如何做到这一点? 我想我得做两个支点?和 unpivot?。。。 我们不知道如何完成它SQL Server中的Join和Pivot语句,sql,sql-server,tsql,sql-server-2008,Sql,Sql Server,Tsql,Sql Server 2008,我想从3个表中选择透视和连接 表1:INT、VARCHAR、FLOAT 表2:INT、VARCHAR、FLOAT 表3:INT、VARCHAR、FLOAT 输出表: 我将3个不同表的列的“名称”替换为数字 如何做到这一点? 我想我得做两个支点?和 unpivot?。。。 我们不知道如何完成它 SELECT * FROM ( SELECT t1.a1, t1.a2, t2.x, t3.q
SELECT *
FROM (
SELECT
t1.a1,
t1.a2,
t2.x,
t3.q
FROM table1 t1
INNER JOIN table2 t2
ON t1.id = t2.id
...
) Output
PIVOT (
name IN (
...
PIVOT(name ... )
)
) PivotTable
更新
以前我有*,我把它改成了除法和和和法,*,只是一个例子,示例表
create table Table1(ID int, Name varchar(10), value float)
insert table1 select
1 ,'a1', 32116580 union all select
2 ,'a2', 50785384 union all select
3 ,'a3', 54327508 union all select
4 ,'a4', 61030844
create table Table2(ID int, Name varchar(10), value float)
insert Table2 select
1 ,'x11', 61326085092 union all select
2 ,'x12', 80368184260 union all select
3 ,'x13', 83023398776 union all select
4 ,'x14', 91144307692 union all select
5 ,'x22', 95486535484 union all select
6 ,'x23', 90357090612 union all select
7 ,'x24', 100588807668 union all select
8 ,'x33', 707811916752 union all select
9 ,'x34', 93128452928 union all select
10 ,'x44', 84566653668
create table Table3(ID int, Name varchar(10), value float)
insert Table3 select
1 ,'q1', 61326085092 union all select
2 ,'q2', 95486535484 union all select
3 ,'q3', 707811916752 union all select
4 ,'q4', 84566653668
您需要的查询,对于N=4。对于任何其他N,只需使用动态SQL构建查询,更改所需的2行,如**所示
动态版本
declare @Sql nvarchar(max)
select @Sql = ISNULL(@sql + ',', '') + QUOTENAME(RIGHT(number,10))
from master..spt_values
where type='P' and number between 1 and (select COUNT(*) From table1)
set @Sql = '
;with coords(i,row,col,total,N) as (
select 1,1,1,N.N*(N.N+1)/2, N.N
from (select count(*) N from table1) N
union all
select i+1,
case when col+1>N then row+1 else row end,
case when col+1>N then row+1 else col+1 end,
total, N
from coords
where i<total
)
select ' + @sql + '
from
(
select
c.row,
c.col,
cellvalue= ar.value*ac.value/(qr.value+qc.value+x.value)
from coords c
inner join table1 ar on ar.id = c.row
inner join table1 ac on ac.id = c.col
inner join table3 qr on qr.id = c.row
inner join table3 qc on qc.ID = c.col
inner join table2 x on x.ID = c.i
) p
pivot (max(cellvalue) for col in (' + @sql + ')) pv
order by row
option (maxrecursion 0) -- ! use with caution
'
exec(@sql)
这个网站能帮你吗?这是固定列输出吗?添加行时不添加列?嗯,输出是一个对称矩阵,当我们添加行时,我们可以添加列…您是否希望得到*系列的准确结果?给定您的示例,这些数字是天文数字,不适合任何SQL Server数据类型。事实上,它们可能是它们的总和。一个问题,我尝试将您的解决方案应用于B最大的表,n=25,我得到:Msg 530,级别16,状态1,第2行语句终止。在语句完成之前,已耗尽最大递归100。查询是正常的,它是按照您所说的生成的……所以这个递归不会被打败,对吗?@darkcminor-我添加了选项maxrecursion,它会绕过它。@Richard aka cyberkiwi:我知道这是另一种问题,但使用maxrecursion告诉SQL继续…??@darkcminor-递归是一种[通用编程]继续返回并重做类似事情的技术。如果您有一个糟糕的查询,它只是简单地说,dox,redox没有任何变化,那么您刚刚创建了一个无限循环。上面的代码实际上总是在达到N*N-1/2后终止,所以它是非常良性的,但是我总是在使用该选项时添加警告。如果N=100000,那么SQL Server将有一个非常大的任务要处理
column1 column2 column3 column4
--------------------------------------------------------------------------
a1*a1/(q1+q1+x11) a1*a2/(q1+q2+x12) a1*a3/(q1+q3+x13) a1*a4/(q1+q4+x14)
null a2*a2/(q2+q2+x22) a2*a3/(q2+q3+x23) a2*a4/(q2+q4+x24)
null null a3*a3/(q3+q3+x339 a3*a4/(q3+q4+x34)
null null null a4*a4/(q4+q4+x44)
SELECT *
FROM (
SELECT
t1.a1,
t1.a2,
t2.x,
t3.q
FROM table1 t1
INNER JOIN table2 t2
ON t1.id = t2.id
...
) Output
PIVOT (
name IN (
...
PIVOT(name ... )
)
) PivotTable
create table Table1(ID int, Name varchar(10), value float)
insert table1 select
1 ,'a1', 32116580 union all select
2 ,'a2', 50785384 union all select
3 ,'a3', 54327508 union all select
4 ,'a4', 61030844
create table Table2(ID int, Name varchar(10), value float)
insert Table2 select
1 ,'x11', 61326085092 union all select
2 ,'x12', 80368184260 union all select
3 ,'x13', 83023398776 union all select
4 ,'x14', 91144307692 union all select
5 ,'x22', 95486535484 union all select
6 ,'x23', 90357090612 union all select
7 ,'x24', 100588807668 union all select
8 ,'x33', 707811916752 union all select
9 ,'x34', 93128452928 union all select
10 ,'x44', 84566653668
create table Table3(ID int, Name varchar(10), value float)
insert Table3 select
1 ,'q1', 61326085092 union all select
2 ,'q2', 95486535484 union all select
3 ,'q3', 707811916752 union all select
4 ,'q4', 84566653668
;with coords(i,row,col,total,N) as (
select 1,1,1,N.N*(N.N+1)/2, N.N
from (select count(*) N from table1) N
union all
select i+1,
case when col+1>N then row+1 else row end,
case when col+1>N then row+1 else col+1 end,
total, N
from coords
where i<total
)
select [1],[2],[3],[4] -- **, e.g. ,[5],[6],etc
from
(
select
c.row,
c.col,
cellvalue= ar.value*ac.value/(qr.value+qc.value+x.value)
from coords c
inner join table1 ar on ar.id = c.row
inner join table1 ac on ac.id = c.col
inner join table3 qr on qr.id = c.row
inner join table3 qc on qc.ID = c.col
inner join table2 x on x.ID = c.i
) p
pivot (max(cellvalue) for col in ([1],[2],[3],[4])) pv -- **
order by row
1 2 3 4
---------------------- ---------------------- ---------------------- ----------------------
5606.50338459295 6876.83326310711 2047.51559459649 8269.17991568225
NULL 9003.55641750708 3087.36780924588 11044.2303130135
NULL NULL 1389.95405212248 3744.35614651666
NULL NULL NULL 14681.7678040306
declare @Sql nvarchar(max)
select @Sql = ISNULL(@sql + ',', '') + QUOTENAME(RIGHT(number,10))
from master..spt_values
where type='P' and number between 1 and (select COUNT(*) From table1)
set @Sql = '
;with coords(i,row,col,total,N) as (
select 1,1,1,N.N*(N.N+1)/2, N.N
from (select count(*) N from table1) N
union all
select i+1,
case when col+1>N then row+1 else row end,
case when col+1>N then row+1 else col+1 end,
total, N
from coords
where i<total
)
select ' + @sql + '
from
(
select
c.row,
c.col,
cellvalue= ar.value*ac.value/(qr.value+qc.value+x.value)
from coords c
inner join table1 ar on ar.id = c.row
inner join table1 ac on ac.id = c.col
inner join table3 qr on qr.id = c.row
inner join table3 qc on qc.ID = c.col
inner join table2 x on x.ID = c.i
) p
pivot (max(cellvalue) for col in (' + @sql + ')) pv
order by row
option (maxrecursion 0) -- ! use with caution
'
exec(@sql)