我有一个“datadump”表,其中包含一堆混合性能相关的数据。 类似的东西:
MachID TestDate MachType Value1 Value2 ...
00001 01/01/09 Server 15 48
00001 01/02/09 Server 16 99
19999 01/01/09 Switch 32 4.9880
19999 01/02/09 Switch 32 5.8109
技巧是“值”列 MEAN 不同类型的机器不同的东西。所以我们有一个“xRef”表,看起来像:
MachType Column Description
Server Value1 Users Connected
Server Value2 % CPU _total
Switch Value1 Number of Ports
Switch Value2 packets/ms
...
我知道,奇怪的结构,但我没有成功,也无法改变它。
我想以某种方式“内连接”这些,以便我可以根据数据类型查询相应的列标题。对于服务器来说是这样的:
MachID TestDate MachType Users Connected % CPU _total Total RAM
00001 01/01/09 Server 15 48 4096
00001 01/02/09 Server 16 99 4096
这对于开关:
MachID TestDate MachType Number of Ports packets/ms Total Cumulative kb
19999 01/01/09 Switch 32 4.9880 1024547
19999 01/02/09 Switch 32 5.8109 1029450
有没有办法在不对每种类型进行单独的硬编码查询的情况下执行此操作?
注意:我一次只需要查询一个类型的对象。最有可能的是,我只会查看单个MachID的特定日期之间的所有结果,如果这有帮助的话。这是MS SQL 2000。
谢谢!
答案 0 :(得分:1)
这将完成所有这些操作 - 如果您希望将它们全部拆分,您可以根据需要进行修改。
DECLARE @template AS varchar(max)
DECLARE @sql AS varchar(max)
DECLARE @column_list AS varchar(max)
SELECT @column_list = COALESCE(@column_list + ', ', '')
+ QUOTENAME([Description])
FROM xRef
SET @template = ';
WITH up
AS (
SELECT MachID
,TestDate
,MachType
,[COLUMN]
,[Value]
FROM datadump UNPIVOT ( [Value] FOR [Column] IN ([Value1], [Value2]) ) AS unpvt
)
,ready AS (
SELECT machID
,TestDate
,up.MachType
,[Description]
,up.[Value]
FROM up
INNER JOIN xRef
ON xRef.machType = up.MachType
AND xRef.[Column] = up.[Column]
)
SELECT * FROM ready
PIVOT (SUM([Value]) FOR [Description] IN ({@column_list})) AS pvt
'
machID TestDate MachType Users Connected % CPU _total Number of Ports packets/ms
------ ----------------------- -------- --------------------------------------- --------------------------------------- --------------------------------------- ---------------------------------------
00001 2009-01-01 00:00:00.000 Server 15.000000000000000 48.000000000000000 NULL NULL
00001 2009-01-02 00:00:00.000 Server 16.000000000000000 99.000000000000000 NULL NULL
19999 2009-01-01 00:00:00.000 Switch NULL NULL 32.000000000000000 4.988000000000000
19999 2009-01-02 00:00:00.000 Switch NULL NULL 32.000000000000000 5.810900000000000
答案 1 :(得分:1)
动态sql选项将(作为查询写出而不是作为proc):
declare @machtype varchar(40) --stored proc parameter?
set @machtype = 'Switch' --or 'Server'
declare @sql nvarchar(4000)
set @sql = 'select
MachID,
TestDate,
MachType,
Value1 as ''' + (select [Description] from dbo.xref where machtype = @machtype and [Column] = 'Value1') + ''',
Value2 as ''' + (select [Description] from dbo.xref where machtype = @machtype and [Column] = 'Value2') + ''',
Value3 as ''' + (select [Description] from dbo.xref where machtype = @machtype and [Column] = 'Value3') + '''
from
dbo.datadump
where
machtype = ''' + @machtype + ''''
exec sp_executesql @sql
如果您觉得这对您来说太难看了,那么在函数中包装获取列名的逻辑会整理它:
create function dbo.ColNameForDataDump(
@machtype varchar(40),
@column varchar(40)
)
RETURNS varchar(40)
as
begin
declare @col_desc varchar(40)
select
@col_desc = [description]
from
dbo.xref
where
machtype = @machtype
and [column] = @column
return @col_desc
end
然后您的动态SQL看起来更像:
declare @machtype varchar(40) --stored proc parameter?
set @machtype = 'Switch' --or 'Server'
declare @sql nvarchar(4000)
set @sql = 'select
MachID,
TestDate,
MachType,
Value1 as ''' + dbo.ColNameForDataDump(@machtype, 'Value1') + ''',
Value2 as ''' + dbo.ColNameForDataDump(@machtype, 'Value2') + ''',
Value3 as ''' + dbo.ColNameForDataDump(@machtype, 'Value3') + '''
from
dbo.datadump
where
machtype = ''' + @machtype + ''''
exec sp_executesql @sql
最后一个关于上面代码的传递点/注释:你提到你在SQL Server 2000上,所以确保你必须编写一些动态sql来定义它为nvarchar并使用sp_executesql来调用它...从而否定了必须动态的一些表演痛苦。
答案 2 :(得分:0)
创建一个表,存储该单个查询类型的每个值的header-name。
然后,创建一个存储过程并使用Dynamic SQL填写从该表中绘制的列名。
答案 3 :(得分:0)
由于您无法更改数据模型,我建议将演示文稿代码放入应用程序的表示层。有一个表格,根据请求的结果为您提供列标题,并从那里开始。