【问题标题】:Dynamic SQL pivot returning only NULLs仅返回 NULL 的动态 SQL 数据透视表
【发布时间】:2016-05-09 22:11:31
【问题描述】:

我对动态 SQL 非常陌生,我正在尝试构建一个查询来报告我们的工作人员、他们拥有哪些证书以及他们存在的最后一个证书的到期日期。我的临时表包含正确的数据,我的动态列字符串似乎是正确的。当一切运行时,列标题按预期显示,人员姓名正确分组,但没有显示任何日期,值全部为 NULL。前两个部分的具体代码我没有放,因为选择标准有点啰嗦。

对于动态列变量,SELECT STUFF(@columns, 1, 1, '') 返回下面的单个值。

 [Air Supervisor - AODC], [Air Supervisor - IMCA], [ALST - Certificate of Achievement], [ALST - IMCA], [Competence - A1/A2 Competent Assessor], [Competence - Air Diver-Surface Supplied], etc...

数据本身保存在一个临时表中,SELECT * FROM #results 给出了以下(示例)输出。这是与最近到期日期的相关人员 ID 匹配的每个证书。

id      cert                            date
3484    [ALST - Banksman and Slinging]  28/07/2029
3648    [ALST - Banksman and Slinging]  05/11/2099
3701    [ALST - Banksman and Slinging]  27/05/2029
3740    [ALST - Banksman and Slinging]  20/01/2055
1181    [ALST - Crane Operators]        31/12/2029
1137    [ALST - Crane Operators]        31/12/2029
1072    [ALST - Crane Operators]        31/12/2029

以下是实际的数据透视查询。我需要上面的 [cert] 字段成为列标题,日期(它们存在的地方)成为值和与正确名称匹配的人员 ID。

SET @dynamicpivot =
        N'SELECT  pd.name, ' + STUFF(@columns, 1, 1, '') + '
        FROM #results 
                PIVOT (MAX([date]) FOR [cert] IN (' + STUFF(@columns, 1, 1, '') + ')) as ce
        JOIN dbo.personnel as pd
        ON pd.person_id = ce.id
        ORDER BY pd.name'

EXEC sp_executesql @dynamicpivot

查询运行没有错误,列名显示正确,人员姓名按顺序和分组显示,但没有显示日期,全为 NULL。

我尽量保持简洁,如果您需要更多信息,请告诉我。

【问题讨论】:

    标签: sql-server dynamic pivot


    【解决方案1】:

    你需要初始化@columns。默认值为 NULL,不能在字符串连接中使用。这是因为 NULL 不能与任何其他值组合。例如,NULL + 1 返回 NULL,NULL + 'Some Text' 也返回 NULL。您可以使用以下查询对此进行测试。

    NULL 连接示例

    -- NULL cannot be concatenated.
    SELECT
        NULL + 'ABC'
    ;
    

    这将返回 NULL。实际上,您的查询正在做同样的事情。

    在第二个示例中,我使用了一个初始化变量。缺少 NULL 允许我将值连接到字符串。

    初始化变量示例

    DECLARE @columns VARCHAR(255) = '';
    
    -- Will return: 'ABC'.
    SELECT
        @columns + 'ABC'
    ;
    

    您也可以使用ISNULL 获得相同的结果。这次变量以 NULL 开始。这在连接过程中被替换为空白字符串。

    ISNULL 示例

    DECLARE @columns VARCHAR(255) = NULL;
    
    -- Using ISNULL returns: 'ABC'.
    SELECT
        ISNULL(@columns, '') + 'ABC'
    ;
    

    【讨论】:

    • 感谢您的回复。我不确定这是不是旋转列标题正确显示的问题。只是缺少表值(日期)。我在创建@columns 变量的代码块的开头有set @columns = N'' select @columns += N', ' + quotename((cty.CType + ' - ' + cty.desc)),我认为它涵盖了上述内容,除非我遗漏了什么
    猜你喜欢
    • 2010-11-04
    • 2022-08-16
    • 2010-12-28
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多