动态SQL数据透视仅返回NULL

时间:2016-02-01 12:44:53

标签: sql-server dynamic pivot

我是动态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。

我试图保持这个相当简洁,如果您需要更多信息,请告诉我。

1 个答案:

答案 0 :(得分:0)

您需要初始化@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'
;