我是动态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。
我试图保持这个相当简洁,如果您需要更多信息,请告诉我。
答案 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'
;