只有两个对象 + 休息计数

Only two objects + rest the count

我想显示以下字符串:

苹果、香蕉、腰果、甜甜圈、大象、鱼

转换成这种格式:

苹果、香蕉 + 其他 4 个

我只想显示前两个对象,然后再计数!

正如其他人所说,这不是 SQL 服务器的工作,而是您的表示层。根据您的预期结果,我 假设 您的逗号表示您在数据库中存储分隔数据;一个致命的缺陷。如果您规范化您的设计,您可能很容易在您的应用程序层中实现这一点。

由于您使用的是非规范化数据,因此您需要先对其进行规范化,然后再重新聚合。我使用任意 TOP(每次 运行 查询时行可能不同),因为序号参数仅(当前)在 Azure SQL 数据库中可用;希望序数参数将在 SQL Server 2022 中。

无论如何,这 有效 ,但再次修正您的设计,并在应用程序层执行此操作。如果您没有使用 SQL Server 2017,那么这是必须的,不是一个非常强烈的建议。

DECLARE @Values int = 2; --parameterised, but you could hard code

WITH Split AS(
    SELECT SS.[value],
           COUNT(*) OVER () AS [Rows]
    FROM (VALUES('Apple,Banana,Cashew,Doughnut,Elephant,Fish'))V(YourDenormalisedData)
         CROSS APPLY STRING_SPLIT(V.YourDenormalisedData,',') SS),
ArbitraryTop AS(
    SELECT TOP (@Values)
           value,
           [Rows]
    FROM Split)
SELECT STRING_AGG(value,', ') +
       CASE WHEN MAX([Rows]) > @Values THEN CONCAT(' + ',MAX([Rows])-@Values,' others') ELSE '' END
FROM ArbitraryTop;

正如其他人所说,这不是 SQL 服务器的工作,而是您的表示层

如果你必须在sql中完成,那么也许你可以这样做。
我确实假设您在多行中有这些值,并且需要通过一些分组将它们连接起来,如果没有,那么请在您的问题中更清楚地说明

select o.id,
       ( select top 2 string_agg(o2.name, ', ')
         from   ( select top 2 o2.name, 
                         o2.id 
                  from   object o2 
                  where  o2.id = o.id
                ) o2
         where  o2.id = o.id
       ) + ' and ' + convert(varchar(50), count(o.name) - 2) + ' others'
from   object o
group by o.id

看看这个 DBFiddle here 看看它是否有效

结果是这样的

id (No column name)
1 Apple, Banana and 4 others
2 Peer, Catfish and 0 others
3 Dog, Whale and 1 others

如果您不想显示 'and x others' 您可以像这样更改查询

select o.id,
       ( select top 2 string_agg(o2.name, ', ')
         from   ( select top 2 o2.name, o2.id 
                  from   object o2 
                  where  o2.id = o.id
                ) o2
         where  o2.id = o.id
       ) + case when count(o.name) > 2 then ' and ' + convert(varchar(50), count(o.name) - 2) + ' others'
                else ''
           end     
from   object o
group by o.id
id (No column name)
1 Apple, Banana and 4 others
2 Peer, Catfish
3 Dog, Whale and 1 others

编辑 sql 服务器不支持 string_agg

如果您有不支持 string_agg 函数的旧版本 sql 服务器,您可以使用 XML PATH 连接值和 stuff 删除多余的 ,

select o.id,
       stuff(( select top 2 ', ' + o2.name
               from   ( select top 2 o2.name, 
                               o2.id 
                        from   object o2 
                        where  o2.id = o.id
                      ) o2
               where  o2.id = o.id
               for XML PATH('')
            ), 1, 2, ''  
       ) + case when count(o.name) > 2 then ' and ' + convert(varchar(50), count(o.name) - 2) + ' others'
                else ''
           end     
from   object o
group by o.id

DBFiddle using XML Path

结果还是一样

这个任务可以用cursor, by dividing the line by the delimenter using function split_string的力量解决。

  --@string - our input string
DECLARE @string NVARCHAR(MAX) = 'Apple,Banana,Cashew,Doughnut,Elephant,Fish';

--@count - the number of words in @string
DECLARE @count INT = 0;

--@countrestwords - count of rest words
DECLARE @countrestwords INT = 0;

--@resultstring - result string
DECLARE @resultstring NVARCHAR(MAX) = '';

        DECLARE stringcursor CURSOR FOR 
        SELECT 
            VALUE 
        FROM string_split(@string,',')

        OPEN stringcursor 

        FETCH FROM stringcursor INTO @string
        WHILE @@FETCH_STATUS = 0
            BEGIN
                IF @count = 0
                    BEGIN
                        SET @resultstring = @string;

                    END
                ELSE IF @count = 1
                    BEGIN
                        SET @resultstring = @resultstring +',' +@string ;
            
                    END
                ELSE 
                    BEGIN
                        SET @resultstring = @resultstring;
                        SET @countrestwords = @countrestwords + 1;

                        --SELECT @countrestwords
                    END


                SET @count = @count + 1;


                FETCH NEXT FROM stringcursor INTO @string

            END

        CLOSE stringcursor
        DEALLOCATE stringcursor

SELECT @resultstring + ' + ' + CONVERT(NVARCHAR(MAX),@countrestwords)+' others' ;

GO

这是我创建的,它对我有用。但是,它需要优化。

Declare @test_count int = 0, @test1_pos int = 0, @test2_pos int = 0, @test_product varchar(500), @test_product2 varchar(500),@tests varchar(500); 
--select distinct top 1 product,CHARINDEX(',',product,1),  CHARINDEX(',',product,CHARINDEX(',',product,1)+1) from ReportDB..wo_result_detail  where CustomerId=@LAB_CODE 

select distinct top 1 @test_product = product,@test1_pos=CHARINDEX(',',product,1), @test1_pos = CHARINDEX(',',product,CHARINDEX(',',product,1)+1)
from [table name]  where [condition] 

select distinct top 1 @test_product = product, @test_product2 =
case when @test1_pos <> 0 or  @test2_pos <> 0  then ( 
                select top 1 left(product,CHARINDEX(',',product,CHARINDEX(',',product,1)+1)-1) from [table name]  where [condition] 
                )
                else @test_product
                end from [table name]  where [condition] 

select @test_count = (len(replace(@test_product,',',', '))+1) - len(@test_product)

select top 1 @tests= case when @test_count> 2 then  concat ( @test_product2 ,' + ',@test_count-2 ,' Others') 
else @test_product end