动态重命名SQL查询列名称

时间:2018-03-10 20:55:37

标签: sql sql-server

我有两个表:data和dataMAP。数据表的列名为MapID,Real_0,Real_2,Real_3,最多为Real_19。样本数据:

find

DataMAP具有MapID,Real_0_Name,Real_1_Name,以及Real_19_Name。样本数据:

SELECT * FROM v;

当我在数据表中查询给定的dataMAP ID时,我希望生成的列名称使用dataMAP中存储的值来表示该mapID号。

1,1.1,2.1,3.1,4.1
1,1.2,2.2,3.2,4.2
1,1.3,2.3,3.3,4.3

但我想:

MapID,forceW,forceX,forceY,forceZ(这些是列名)

1,'forceW','forceX','forceY','forceZ'
2,'distanceW','distanceX','distanceY','distanceZ'

服务器是Microsoft SQL 2012。

1 个答案:

答案 0 :(得分:1)

没有动态SQL,我无法理解:

DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX)

IF OBJECT_ID('tempdb..#values') IS NOT NULL
    DROP TABLE #values

SELECT
    vMapID, N, dm.ColName, [values].[value]
INTO #values
FROM (
    SELECT
        MapID AS vMapID,
        N,
        cn.ColName + '_Name' AS RealName,
        cn.value
    FROM
    (
        SELECT
            d.MapID,
            d.Real_0, d.Real_1, d.Real_2, d.Real_3,
            ROW_NUMBER() OVER(PARTITION BY d.MapID ORDER BY d.MapID, Real_0) AS N
        FROM [data] d
    ) AS piv
    UNPIVOT
    (
        [value] FOR ColName IN (Real_0, Real_1, Real_2, Real_3)
    ) AS cn
) [values]
INNER JOIN (
    SELECT
        MapID AS mMapID,
        cn.RealName,
        cn.ColName
    FROM DataMAP AS dm
    UNPIVOT
    (
        ColName FOR RealName IN (Real_0_Name, Real_1_Name, Real_2_Name, Real_3_Name)
    ) cn
) dm
    ON dm.mMapID = [values].vMapID
    AND dm.RealName = [values].RealName
WHERE [values].vMapID = 2

SELECT @cols = STUFF(
        (SELECT DISTINCT ',' + QUOTENAME(ColName) FROM #values FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),
        1, 1, '')

SET @query = 'SELECT MapID, ' + @cols + ' FROM 
             (
                SELECT
                    vMapID AS MapID,
                    N,
                    ColName,
                    [value]
                FROM #values
            ) v
            PIVOT
            (
                MIN([value])
                FOR ColName IN (' + @cols + ')
            ) p '

EXEC(@query)

两个表都是UNPIVOT-ed,以获取名称+值对的实际数字,添加ROW_NUMBER()以区分一行与另一行。