使用逗号或" AND"

时间:2017-02-13 16:34:52

标签: sql sql-server

我对SQL Server Reporting Services(SSRS)报告有以下要求:在一个字符串中显示数据库表中列的所有值,连接如下:

  1. 如果只有一个值,则显示

  2. 如果有两个值,请用逗号连接它们(",")

  3. 如果有两个以上的值,则用逗号(",")连接除最后两个以外的所有值,最后两个用",AND"

  4. 值应该是不同的,即不允许两个重复值

  5. 为了说明,如果相关列的值,我们称之为Column1,则为:

      

    列1

         

    苹果

         

    马铃薯

         

    马铃薯

         

         

    葡萄

    结果字符串应为:

      

    Apple,Potato,Pear和Grapes

    所以我的问题是,我怎么能在SQL语句中这样做?我可以使用以下SQL完成#1,#2和#4,但#3逃脱了我:

    SELECT Stuff(
      (SELECT DISTINCT
            N', ' + Table1.Column1
       FROM
            Table2
                    INNER JOIN Table ON Table1.Id = Table2.Table2ID_FK
       WHERE
        dbo.Table2.SomeId = 100
        FOR XML PATH(''),TYPE)
      .value('text()[1]','nvarchar(max)'),1,2,N'');
    

3 个答案:

答案 0 :(得分:2)

尝试这样的事情

SELECT CASE
         WHEN Len(intr) - Len(Replace(intr, ',', '')) > 1 THEN Stuff(intr, ( Len(intr) - Charindex(',', Reverse(intr)) ) + 2, 0, ' and ')
         ELSE intr
       END
FROM   (SELECT Stuff((SELECT DISTINCT N', ' + Table1.Column1
                      FROM   Table2
                             INNER JOIN Table
                                     ON Table1.Id = Table2.Table2ID_FK
                      WHERE  dbo.Table2.SomeId = 100
                      FOR XML PATH(''), TYPE) .value('text()[1]', 'nvarchar(max)'), 1, 2, N'') AS intr)a 

答案 1 :(得分:1)

使用with (common table expression),我们可以使用子查询轻松引用目标结果集,以查找列表中的最后一个值和值的数量。

使用case表达式在'and '最后一个值和子查询时添加col =以检查返回值的count(*)

rextester:http://rextester.com/QDTJ44637

with t as (
  select col 
  from (values ('Apple'),('Potato'),('Potato'),('Pear'),('Grapes')) t (col)
)

select stuff((
  select 
        N', ' 
      + case when col = (select top 1 col from t order by col desc)
               and (select count(*) from t)>2
             then 'and ' 
             else '' 
             end 
      + col
   from t
   group by col
   order by col for xml path(''),type)
  .value('text()[1]','nvarchar(max)'),1,2,N'');

要使其适应问题中的查询,请将公共表表达式with t as ()内的查询替换为

SELECT DISTINCT col = Table1.Column1 
FROM Table2 
  INNER JOIN Table1 ON Table1.Id = Table2.Table2ID_FK 
WHERE dbo.Table2.SomeId = 100

答案 2 :(得分:1)

单独保留您的代码(工作正常)。在该代码之外,修复问题。以下是......

暂时,为了清晰起见,我会使用文字。考虑一下:

    SELECT RIGHT('Apple, Potato, Pear, Grapes' , CHARINDEX (' ,' ,REVERSE('Apple, Potato, Pear, Grapes'))+1)

...产量:",葡萄"

到目前为止好吗?只需将其替换为"和Grapes"通过以下方式......

    SELECT REPLACE('Apple, Potato, Pear, Grapes', RIGHT('Apple, Potato, Pear, Grapes' , CHARINDEX (' ,' ,REVERSE('Apple, Potato, Pear, Grapes'))+1), REPLACE(RIGHT('Apple, Potato, Pear, Grapes' , CHARINDEX (' ,' ,REVERSE('Apple, Potato, Pear, Grapes'))+1),',',' and'))

所以,为了使这一切变得充满活力,只需更换文字' Apple,Potato,Pear,Grapes'使用原始查询的结果(您应该将其分配给变量)。

最终代码如下:

    DECLARE @OrigValue AS NVARCHAR(MAX)

    SELECT @OrigValue = 
      Stuff(
      (SELECT DISTINCT
            N', ' + Table1.Column1
       FROM
            Table2
                    INNER JOIN Table ON Table1.Id = Table2.Table2ID_FK
       WHERE
        dbo.Table2.SomeId = 100
        FOR XML PATH(''),TYPE)
      .value('text()[1]','nvarchar(max)'),1,2,N'');

    SELECT REPLACE(@OrigValue, RIGHT(@OrigValue , CHARINDEX (' ,',REVERSE(@OrigValue))+1), REPLACE(RIGHT(@OrigValue, CHARINDEX (' ,',REVERSE(@OrigValue))+1),',',' and'))