简体   繁体   English

如何在SQL SERVER 2008 R2中逐行显示单个列中的多个值?

[英]How to display the multiple values in a single column with line by line in SQL SERVER 2008 R2?

I'm using SQL SERVER 2008 R2. 我正在使用SQL SERVER 2008 R2。 I want to get the multiple values and show it in the single column with line by line at the same time, if the values present otherwise it shows some values and might be the possibility of '12 values' on a single column. 我想获取多个值并同时逐行显示在单个列中,如果值存在,则显示某些值,并且可能是单个列上'12值'的可能性。

截图示例2

For Example, The screen Shot below, it shows records for the same data except the comments. 例如,下面的屏幕截图显示了除注释之外的相同数据的记录 I want to display as the single record, but the comments should show the both values that is ASN Timeliness, ASN Accuracy, problem reports . 我想显示为单个记录,评论应显示ASN及时性,ASN准确性,问题报告这两个值。 The three values are displayed line by line using the same shipsite "0096a". 使用相同的船舶“0096a”逐行显示这三个值

截图示例1

My sample query, 我的样本查询

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 

I see two ways that you can do this. 我看到有两种方法可以做到这一点。

First you can use FOR XML PATH and STUFF in a correlated subquery. 首先,您可以在相关子查询中使用FOR XML PATHSTUFF This will concatenate the values from the CSPGJ02_MSG_OBJ into a single string: 这会将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;

The second method is to use a CROSS APPLY with FOR XML PATH : 第二种方法是使用带有FOR XML PATHCROSS APPLY

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;

Note: You will notice that I changed your query to use JOIN syntax instead of the comma separated tables with the joins in the WHERE clause. 注意:您会注意到,我将查询更改为使用JOIN语法,而不是用WHERE子句中的联接使用逗号分隔的表。 This is standard ANSI syntax. 这是标准的ANSI语法。

Using XML PATH('') 使用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 

This one will make a comma separated list of comments. 这个将以逗号分隔的注释列表。

If you want to display multiple columns in one, you can write like this: 如果要在一个中显示多个列,可以这样编写:

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

If you want to group by multiple columns to single column as a string - this article should help you: 如果要按字符串将多列分组为单个列,那么本文将为您提供帮助:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM