2

我正在使用 SQL SERVER 2008 R2。我想获取多个值并同时逐行显示在单列中,如果存在值,否则它会显示一些值,并且可能在单列上显示“12 个值”。

示例截图 2

例如,下面的屏幕截图,它显示了相同数据的记录,但评论除外。我想显示为单个记录,注释应显示ASN Timeliness、ASN Accuracy、问题报告这两个值。这三个值使用同一船厂“0096a”逐行显示。

示例截图 1

我的示例查询,

SELECT 
    D30.SPGD30_SHIP_SITE_C AS SHIPSITE,  
    D30.SPGD30_RATING_MONTH_Y AS RATINGMONTH,  
    D30.SPGD30_PRIOR_SCORE_R AS PRIOR, 
    D30.SPGD30_REVISED_SCORE_R AS REVISED,  
    CASE WHEN (CHARINDEX('-',D30.SPGD30_TRACKED_ADJUSTMENT_X) > 0 ) THEN CONVERT( VARCHAR(8), CAST(D30.SPGD30_TRACKED_ADJUSTMENT_X AS DATETIME) , 1) ELSE D30.SPGD30_TRACKED_ADJUSTMENT_X END ADJUSTMENTS,  
    J02.SPGJ02_MSG_CODE_X AS COMMENTS,  
    D30.SPGD30_LAST_TOUCH_Y AS LASTUPDATED,  
    D30.SPGD30_LAST_TOUCH_C AS LASTUPDATEDCDSID   
FROM  
    CSPGD30_TRACKING D30, 
    CSPGD31_TRACKING_RATING_ELEMNT D31,  
    CSPGA04_RATING_ELEMENT_MSTR A04 , 
    CSPGJ02_MSG_OBJ J02  
WHERE  
    D30.SPGA02_BUSINESS_TYPE_C = D31.SPGA02_BUSINESS_TYPE_C  
AND 
    D30.SPGA03_REGION_C = D31.SPGA03_REGION_C  
AND 
    D30.SPGD30_SHIP_SITE_C = D31.SPGD30_SHIP_SITE_C  
AND 
    D30.SPGD30_RATING_MONTH_Y = D31.SPGD30_RATING_MONTH_Y  
AND 
    D30.SPGD30_TRACKED_ADJUSTMENT_X = D31.SPGD30_TRACKED_ADJUSTMENT_X  
AND 
    D30.SPGD30_LAST_TOUCH_Y = D31.SPGD30_LAST_TOUCH_Y  
AND 
    D31.SPGA04_RATING_ELEMENT_D = A04.SPGA04_RATING_ELEMENT_D  
AND 
    A04.SPGJ02_MSG_K = J02.SPGJ02_MSG_K  
AND 
    D30.SPGA02_BUSINESS_TYPE_C = 'serv'  
AND 
    D30.SPGA03_REGION_C = 'ap'  
AND 
    D30.SPGD30_SHIP_SITE_C = '0134a'  
ORDER BY   
    D30.SPGD30_SHIP_SITE_C ASC  ,
    D30.SPGD30_RATING_MONTH_Y DESC  ,
    D30.SPGD30_LAST_TOUCH_Y DESC 
4

3 回答 3

7

我看到两种方法可以做到这一点。

首先,您可以在相关子查询中使用FOR XML PATH和。STUFF这会将 中的值连接CSPGJ02_MSG_OBJ成一个字符串:

SELECT D30.SPGD30_SHIP_SITE_C AS SHIPSITE,  
    D30.SPGD30_RATING_MONTH_Y AS RATINGMONTH,  
    D30.SPGD30_PRIOR_SCORE_R AS PRIOR, 
    D30.SPGD30_REVISED_SCORE_R AS REVISED,  
    CASE WHEN (CHARINDEX('-',D30.SPGD30_TRACKED_ADJUSTMENT_X) > 0 ) THEN CONVERT( VARCHAR(8), CAST(D30.SPGD30_TRACKED_ADJUSTMENT_X AS DATETIME) , 1) ELSE D30.SPGD30_TRACKED_ADJUSTMENT_X END ADJUSTMENTS,  
     STUFF((SELECT distinct '+ ' + J02.SPGJ02_MSG_CODE_X
            from CSPGJ02_MSG_OBJ J02
            where A04.SPGJ02_MSG_K = J02.SPGJ02_MSG_K 
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,2,'') COMMENTS,
    D30.SPGD30_LAST_TOUCH_Y AS LASTUPDATED,  
    D30.SPGD30_LAST_TOUCH_C AS LASTUPDATEDCDSID   
FROM CSPGD30_TRACKING D30
INNER JOIN CSPGD31_TRACKING_RATING_ELEMNT D31
    ON D30.SPGA02_BUSINESS_TYPE_C = D31.SPGA02_BUSINESS_TYPE_C  
    AND D30.SPGA03_REGION_C = D31.SPGA03_REGION_C  
    AND D30.SPGD30_SHIP_SITE_C = D31.SPGD30_SHIP_SITE_C  
    AND D30.SPGD30_RATING_MONTH_Y = D31.SPGD30_RATING_MONTH_Y  
    AND D30.SPGD30_TRACKED_ADJUSTMENT_X = D31.SPGD30_TRACKED_ADJUSTMENT_X  
    AND D30.SPGD30_LAST_TOUCH_Y = D31.SPGD30_LAST_TOUCH_Y  
INNER JOIN CSPGA04_RATING_ELEMENT_MSTR A04
    ON D31.SPGA04_RATING_ELEMENT_D = A04.SPGA04_RATING_ELEMENT_D  
WHERE D30.SPGA02_BUSINESS_TYPE_C = 'serv'  
    AND D30.SPGA03_REGION_C = 'ap'  
    AND D30.SPGD30_SHIP_SITE_C = '0134a'  
ORDER BY D30.SPGD30_SHIP_SITE_C ASC, D30.SPGD30_RATING_MONTH_Y DESC, D30.SPGD30_LAST_TOUCH_Y DESC;

第二种方法是使用CROSS APPLYwith FOR XML PATH

SELECT D30.SPGD30_SHIP_SITE_C AS SHIPSITE,  
    D30.SPGD30_RATING_MONTH_Y AS RATINGMONTH,  
    D30.SPGD30_PRIOR_SCORE_R AS PRIOR, 
    D30.SPGD30_REVISED_SCORE_R AS REVISED,  
    CASE WHEN (CHARINDEX('-',D30.SPGD30_TRACKED_ADJUSTMENT_X) > 0 ) THEN CONVERT( VARCHAR(8), CAST(D30.SPGD30_TRACKED_ADJUSTMENT_X AS DATETIME) , 1) ELSE D30.SPGD30_TRACKED_ADJUSTMENT_X END ADJUSTMENTS,  
    left(J02.comments, LEN(J02.comments)-1) AS COMMENTS,
    D30.SPGD30_LAST_TOUCH_Y AS LASTUPDATED,  
    D30.SPGD30_LAST_TOUCH_C AS LASTUPDATEDCDSID   
FROM CSPGD30_TRACKING D30
INNER JOIN CSPGD31_TRACKING_RATING_ELEMNT D31
    ON D30.SPGA02_BUSINESS_TYPE_C = D31.SPGA02_BUSINESS_TYPE_C  
    AND D30.SPGA03_REGION_C = D31.SPGA03_REGION_C  
    AND D30.SPGD30_SHIP_SITE_C = D31.SPGD30_SHIP_SITE_C  
    AND D30.SPGD30_RATING_MONTH_Y = D31.SPGD30_RATING_MONTH_Y  
    AND D30.SPGD30_TRACKED_ADJUSTMENT_X = D31.SPGD30_TRACKED_ADJUSTMENT_X  
    AND D30.SPGD30_LAST_TOUCH_Y = D31.SPGD30_LAST_TOUCH_Y  
INNER JOIN CSPGA04_RATING_ELEMENT_MSTR A04
    ON D31.SPGA04_RATING_ELEMENT_D = A04.SPGA04_RATING_ELEMENT_D  
CROSS APPLY
(
    select J02.SPGJ02_MSG_CODE_X  + ', '
    from CSPGJ02_MSG_OBJ J02
    where A04.SPGJ02_MSG_K = J02.SPGJ02_MSG_K  
    FOR XML PATH('')
) J02 (comments)
WHERE D30.SPGA02_BUSINESS_TYPE_C = 'serv'  
    AND D30.SPGA03_REGION_C = 'ap'  
    AND D30.SPGD30_SHIP_SITE_C = '0134a'  
ORDER BY D30.SPGD30_SHIP_SITE_C ASC, D30.SPGD30_RATING_MONTH_Y DESC, D30.SPGD30_LAST_TOUCH_Y DESC;

注意:您会注意到我将您的查询更改为使用JOIN语法而不是逗号分隔的表和WHERE子句中的连接。这是标准的 ANSI 语法。

于 2013-03-26T14:56:32.487 回答
0

如果要在一列中显示多列,可以这样写:

SELECT CAST([MyIntegerId] AS varchar(10)) + ' - ' + [Column1]+ ' - ' +CAST([MyDateTimeColumn] AS varchar(10)) + ' - ' + [Column2] AS 'My Merged Column'
FROM Mytable

如果您想将多列分组为单个列作为字符串 - 这篇文章应该可以帮助您:

于 2013-04-01T12:55:51.853 回答
0

使用 XML PATH('')

SELECT 
    D30.SPGD30_SHIP_SITE_C AS SHIPSITE,  
    D30.SPGD30_RATING_MONTH_Y AS RATINGMONTH,  
    D30.SPGD30_PRIOR_SCORE_R AS PRIOR, 
    D30.SPGD30_REVISED_SCORE_R AS REVISED,  
    CASE WHEN (CHARINDEX('-',D30.SPGD30_TRACKED_ADJUSTMENT_X) > 0 ) THEN CONVERT( VARCHAR(8), CAST(D30.SPGD30_TRACKED_ADJUSTMENT_X AS DATETIME) , 1) ELSE D30.SPGD30_TRACKED_ADJUSTMENT_X END ADJUSTMENTS,  
    STUFF(JO2.COMMENTS, 1, 1, '') AS COMMENTS,  
    D30.SPGD30_LAST_TOUCH_Y AS LASTUPDATED,  
    D30.SPGD30_LAST_TOUCH_C AS LASTUPDATEDCDSID   
FROM  
    CSPGD30_TRACKING D30 
CROSS JOIN CSPGD31_TRACKING_RATING_ELEMNT D31
CROSS JOIN CSPGA04_RATING_ELEMENT_MSTR A04
CROSS APPLY (
    SELECT
        ',' + ISNULL(JO2.SPGJ02_MSG_CODE_X, '')
    FROM CSPGJ02_MSG_OBJ JO2  
    WHERE A04.SPGJ02_MSG_K = JO2.SPGJ02_MSG_K  
    FOR XML PATH('')
) AS JO2 (COMMENTS)
WHERE  
    D30.SPGA02_BUSINESS_TYPE_C = D31.SPGA02_BUSINESS_TYPE_C  
AND 
    D30.SPGA03_REGION_C = D31.SPGA03_REGION_C  
AND 
    D30.SPGD30_SHIP_SITE_C = D31.SPGD30_SHIP_SITE_C  
AND 
    D30.SPGD30_RATING_MONTH_Y = D31.SPGD30_RATING_MONTH_Y  
AND 
    D30.SPGD30_TRACKED_ADJUSTMENT_X = D31.SPGD30_TRACKED_ADJUSTMENT_X  
AND 
    D30.SPGD30_LAST_TOUCH_Y = D31.SPGD30_LAST_TOUCH_Y  
AND 
    D31.SPGA04_RATING_ELEMENT_D = A04.SPGA04_RATING_ELEMENT_D  
AND 
    D30.SPGA02_BUSINESS_TYPE_C = 'serv'  
AND 
    D30.SPGA03_REGION_C = 'ap'  
AND 
    D30.SPGD30_SHIP_SITE_C = '0134a'  
ORDER BY   
    D30.SPGD30_SHIP_SITE_C ASC  ,
    D30.SPGD30_RATING_MONTH_Y DESC  ,
    D30.SPGD30_LAST_TOUCH_Y DESC 

这将制作一个逗号分隔的评论列表。

于 2013-03-25T15:33:14.710 回答