2

我正在使用SQL SERVER 2008 R2。我想要获取多个值,并在同一行中逐行显示它,如果值存在,则显示一些值,并且可能是单列上的'12值'的可能性。如何在SQL SERVER 2008 R2中逐行显示多个值?

Sample screenshot 2

对于实施例,下面的屏幕截图,它示出了用于除了注释相同的数据记录。我想显示为单个记录,意见应显示两个值是ASN及时性,准确性ASN,问题报告。这三个值使用相同的船厂“0096a”逐行显示。

Sample screenshot 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 
+0

你想要的结果是什么?有很多列,你想展示哪些列? – 2013-02-18 09:39:23

+0

我想在单个列中显示多个值(12个评分元素)。例如,如果存在8个评级要素,我们在单个列中只显示8个评级要素。 – 2013-02-18 09:42:36

+2

你应该看看这个:[http://stackoverflow.com/questions/1574407/how-to-concatenate-n-columns-into-one](http://stackoverflow.com/questions/1574407/how-to -concatenate-n-columns-into-one) – Dalex 2013-02-18 15:45:15

回答

0

使用

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 

这人会做一个逗号分隔的评论列表XML PATH( '')。

+0

这不是老板的工作。 – 2013-03-26 13:13:46

+0

我写了一个0而不是一个O.很高兴有人给我一个这样的投票...(是的,我猜这个有趣的部分不是CROSS APPLY或XML PATH,而是Oes和Zeroes .. ) – Serge 2013-03-26 15:16:16

+4

我没有投票,但你能解释为什么你在WHERE子句中使用CROSS JOIN和连接条件,而不是适当的,现代的和更直观的INNER JOIN语法? – 2013-03-26 15:38:00

7

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

首先,您可以在相关子查询中使用FOR XML PATHSTUFF。这将串连从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 APPLYFOR 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语法。

+0

它不适合我。它不逐行显示。所以我能做些什么。它显示了两条记录(使用SQL Server 2008 R2) – 2013-03-27 13:27:06

+0

@Adalarasan_Serangulam我的建议是用你的表和一些示例数据创建一个SQL小提琴或用每个表的完整表结构和示例数据编辑你的文章。 – Taryn 2013-03-27 13:49:01

+0

好吧,我会尽我最好的谢谢 – 2013-03-27 14:31:25

0

如果你想在一个显示多列,你可以这样写:

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

如果你想通过多列单列为一个字符串组 - 这article应该可以帮助您: