动态 SQL - 如何使用结果中的值作为列名?

Dynamic SQL - How to use a value from a result as a column name?

我正在对 MsSQL 存储过程进行动态 SQL 查询。

有一个tablesearch.ProfileFields包含了我需要查询的table中实际的列名。

我的目标是 SQL select table 中的特定列,动态地从其父查询..

有点混乱,举个例子:

DECLARE @sql nvarchar(max)

SELECT @sql = '
    SELECT 
           pfs.SectionID, 
           pfs.SectionName, 
           pfs.Link,
           (
                SELECT 
                        pf.FieldID,
                        pf.FieldTitle,
                        pf.FieldSQL,
                        pf.Restricted,
                        pf.Optional,
                        (
                            SELECT 
                                pf.FieldSQL
                            FROM 
                                Resources.emp.EmployeeComplete as e
                            WHERE
                                e.QID = @QID
                        ) as Value
                FROM 
                    search.ProfileFields as pf
                WHERE 
                    pf.SectionID = pfs.SectionID
                ORDER BY
                    pf.[Order]
                FOR    XML PATH (''field''), ELEMENTS, TYPE, ROOT (''fields'')
           ) 
    FROM 
        search.ProfileFieldSections as pfs
    WHERE
        pfs.Status = 1
    FOR    XML PATH (''data''), ELEMENTS, TYPE, ROOT (''root'')'

PRINT @sql
EXECUTE sp_executesql @sql, N'@QID varchar(10)', @QID = @QID

在最里面select。我正在查询 pf.FieldSQL。我正在寻找父 select.

收到的实际值

search.ProfileFields 有一个名为 FieldSQL 的列,其中包含一些结果,例如 NameAgeLocation.

这就是我想让我内心深处 select 去做的事情。

SELECT Name FROM ... - 本例中的名称来自 pf.FieldSQL.

的值

在这种情况下如何查询动态列名?

查看 this answer 以获得一些建议。如果您的 table 定义很复杂或偶尔会发生变化,您可能应该使用数据透视表。这是一个可能适合您的方法,只要 FieldSQL 列中的列名定义明确,它们不会太多,并且永远不会更改或添加到:

DECLARE @sql nvarchar(max)

SELECT @sql = '
    SELECT 
       pfs.SectionID, 
       pfs.SectionName, 
       pfs.Link,
       (
            SELECT 
                pf.FieldID,
                pf.FieldTitle,
                pf.FieldSQL,
                pf.Restricted,
                pf.Optional,
                (
                    SELECT case pf.FieldSQL 
                        when 'Name' then e.Name
                        when 'DOB' then convert(nvarchar(10), e.DOB, 126)
                        -- ... etc.
                        -- NOTE: may need to aggregated depending on uniqueness of QID:
                        -- when 'Name' then min(e.Name)
                        -- when 'DOB' then convert(nvarchar(10), min(e.DOB), 126)
                        end
                    FROM 
                        Resources.emp.EmployeeComplete as e
                    WHERE
                        e.QID = @QID
                ) as Value
            FROM 
                search.ProfileFields as pf
            WHERE 
                pf.SectionID = pfs.SectionID
            ORDER BY
                pf.[Order]
            FOR    XML PATH (''field''), ELEMENTS, TYPE, ROOT (''fields'')
       ) 
    FROM 
        search.ProfileFieldSections as pfs
    WHERE
        pfs.Status = 1
    FOR    XML PATH (''data''), ELEMENTS, TYPE, ROOT (''root'')'

PRINT @sql
EXECUTE sp_executesql @sql, N'@QID varchar(10)', @QID = @QID

在此处查看 "PIVOT" 运算符 PIVOT 这应该会给你一些如何使用它们的想法。