Sql 将1000列旋转/旋转到行
我继承了一个数据库,需要从中提取当前按行排列的列中的数据。检索数据的查询是:Sql 将1000列旋转/旋转到行,sql,sql-server,sql-server-2000,pivot,unpivot,Sql,Sql Server,Sql Server 2000,Pivot,Unpivot,我继承了一个数据库,需要从中提取当前按行排列的列中的数据。检索数据的查询是: select distinct LIMSNo, p250.*, p500.*, p750.*, p1000.* from results as r inner join Points250 as p250 on r.resultsid = p250.resultsid and p250.channel = 1 inner join Points500 as p500
select distinct
LIMSNo, p250.*, p500.*, p750.*, p1000.*
from
results as r
inner join Points250 as p250
on r.resultsid = p250.resultsid and p250.channel = 1
inner join Points500 as p500
on r.resultsid = p500.resultsid and p500.channel = 1
inner join Points750 as p750
on r.resultsid = p750.resultsid and p750.channel = 1
inner join Points1000 as p1000
on r.resultsid = p1000.resultsid and p1000.channel = 1
where
r.limsno between '120053698' and '120053704'
产生
LIMSNo P0001 P0002 P0003 ... P1000
120053698 251.6667 302.0196 302.2353 305.9608
120053699 291.6667 342.6545 347.9635 353.6236
120053700 243.3333 298.3206 296.7235 299.5342
120053701 308.3333 365.8397 365.4071 368.3206
120053702 315 363.4153 366.6052 373.1695
请注意,共有1000列P0001…P1000
我想旋转数据,以便获得以下输出:
120053698 120053699 120053700 120053701 120053702
P0001 251.6667 291.6667 243.3333 308.3333 315
P0002 302.0196 342.6545 298.3206 365.8397 363.4153
...
P1000 305.9608 353.6236 299.5342 368.3206 373.1695
如何构造SQL查询?数据库是SQL2000
我已经尝试了很多方法来解决这个问题。我最近的尝试是:
create table #tempCols
(
ColName nchar(15)
)
insert into #tempCols
select
column_name
from
information_schema.columns
where
table_name = 'Points250'
and column_name like 'P%'
insert into #tempCols
select
column_name
from
information_schema.columns
where
table_name = 'Points500'
and column_name like 'P%'
insert into #tempCols
select
column_name
from
information_schema.columns
where
table_name = 'Points750'
and column_name like 'P%'
insert into #tempCols
select
column_name
from
information_schema.columns
where
table_name = 'Points1000'
and column_name like 'P%'
create table #LIMSList
(
LIMSNumber nchar(9)
)
insert into #LIMSList
select LimsNo from results
where LimsNo between '100030460' and '100030500'
declare @colList varchar(max)
select @colList = COALESCE(@colList + ',' ,'') + ColName from #tempCols
declare @command varchar(max)
set @command =
'
select LimsNo, Point, Data
from (
select LimsNo, p250.*, p500.*, p750.*, p1000.*
from
results as r
inner join Points250 as p250
on r.resultsid = p250.resultsid and p250.channel = 1
inner join Points500 as p500
on r.resultsid = p500.resultsid and p500.channel = 1
inner join Points750 as p750
on r.resultsid = p750.resultsid and p750.channel = 1
inner join Points1000 as p1000
on r.resultsid = p1000.resultsid and p1000.channel = 1
where
limsno in (select LimsNo from #LIMSList)) d
unpivot (Data for Point in (' + @colList + ')) as unpvt
'
print @command
exec(@command)
drop table #tempCols
drop table #LIMSList
但我得到的错误是:
Msg 8156, Level 16, State 1, Line 1
The column 'ResultsID' was specified multiple times for 'd'.
Msg 8156, Level 16, State 1, Line 1
The column 'ResultsID' was specified multiple times for 'unpvt'.
在SQL Server 2000中,pivot和unpivot运算符不可用。因此,您必须使用其他技术来透视和解压数据 我列出了unpivot和pivot的静态方法,希望您可以将其转换为动态解决方案 假设已将查询的数据插入到表中,则可以使用UNION ALL取消插入数据,并将其插入到临时表中
SELECT
*
INTO dbo.temp
FROM
(
SELECT LIMSNo, P0001 AS [Point],'P0001' AS [ColName] FROM dbo.myTable
UNION ALL
SELECT LIMSNo, P0002 AS [Point],'P0002' AS [ColName] FROM dbo.myTable
UNION ALL
SELECT LIMSNo, P0003 AS [Point],'P0003' AS [ColName] FROM dbo.myTable
UNION ALL
SELECT LIMSNo, P0004 AS [Point],'P0004' AS [ColName] FROM dbo.myTable
....
....
UNION ALL
SELECT LIMSNo, P1000 AS [Point],'P1000' AS [ColName] FROM dbo.myTable
) AS t
然后您可以再次透视数据
SELECT
ColName
,MAX(CASE LIMSNo WHEN '120053698' THEN [Point] ELSE NULL END ) AS [120053698]
,MAX(CASE LIMSNo WHEN '120053699' THEN [Point] ELSE NULL END ) AS [120053699]
,MAX(CASE LIMSNo WHEN '120053700' THEN [Point] ELSE NULL END ) AS [120053700]
....
....
,MAX(CASE LIMSNo WHEN '120053704' THEN [Point] ELSE NULL END ) AS [120053704]
FROM dbo.temp
GROUP BY ColName
由于SQL Server 2000既没有UNPIVOT运算符也没有PIVOT运算符,因此必须对UNPIVOT使用UNION ALL,然后对PIVOT使用CASE语句。以下是一个动态解决方案:
DECLARE @query AS NVARCHAR(MAX),
@rowCount as int = 1,
@unpivotCount as int = 0,
@pivotCount as int,
@unRow as varchar(10) = '',
@pivotRow as varchar(10) = ''
select c.Name col
into #colsUnpivot
from sys.columns as C
where C.object_id = object_id('yourtable') and
C.name LIKE 'P%'
set @unpivotCount = (select count(*) from #colsUnpivot)
-- unpivot the data
while @rowCount <= @unpivotCount
begin
set @unRow = (select Top 1 col from #colsUnpivot)
set @query =' insert into unpivotData (LIMSNo, Val, Col)
select LIMSNo, ' + @unRow + ' as val, '''
+ @unRow + ''' as col
from yourtable'
exec(@query)
delete from #colsUnpivot where col = @unRow
if @rowCount <= @unpivotCount
set @rowCount = @rowCount + 1
end
--select *
--from unpivotData
-- pivot the data
select distinct LIMSNo
into #colsPivot
from yourtable
set @pivotCount= (select COUNT(*) from #colsPivot)
-- reset rowcount
set @rowCount = 1
set @query = ''
---- create the CASE string
while @rowCount <= @pivotCount
begin
set @pivotRow = (select Top 1 LIMSNo from #colsPivot)
set @query = @query + ', max(case when LIMSNo = ' + @pivotRow + ' then val end) as ''' + @pivotRow + ''''
delete from #colsPivot where LIMSNo = @pivotRow
if @rowCount <= @pivotCount
begin
set @rowCount = @rowCount + 1
print @rowCount
end
end
-- add the rest of the SQL Statement
set @query = 'SELECT col ' + @query + ' from dbo.unpivotData group by col'
exec(@query)
delete from dbo.unpivotData
drop table #colsUnpivot
drop table #colspivot
我创建了一个名为UnpivotData的表来保存数据,以便在PIVOT过程中使用
请参见我尝试了许多方法。查看我的编辑以了解我的最新尝试。您需要只执行一次透视还是定期执行透视?如果只是一次,您可以将其全部放在一个Excel工作表中,复制整个数据集,然后使用“粘贴特殊”转置将其粘贴到另一个工作表中。我怀疑这会不止一次,尽管不是经常发生。谢谢你的Excel建议。谢谢,@ClearLogic,我将尝试为你的查询开发一个动态版本。嗨,如何使用pivot和unpivot进行同样的操作?我也有类似的情况