只有两个对象+休息

发布于 2025-01-24 04:15:11 字数 132 浏览 2 评论 0原文

我想显示以下字符串:

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

苹果,香蕉 + 4其他

我只想展示前两个对象并休息计数!

I want to show the below string:

Apple,Banana,Cashew,Doughnut,Elephant,Fish

into this format:

Apple, Banana + 4 others

I only want to show first two objects and rest the count !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清风无影 2025-01-31 04:15:11

就像其他人所说的那样,这不是SQL Server的工作,而是您的演示层。根据您的预期结果,我假设您的逗号意味着您正在数据库中存储划界数据;致命的缺陷。如果您使设计归一化,则很可能在应用程序层中很容易实现这一目标。

当您使用不规范数据时,您需要首先将其归一化,然后再重新审核它。我使用任意top(每次运行查询时行都可能有所不同),因为Azure SQL数据库中的序数参数仅(当前);希望序数参数将在SQL Server 2022中。

无论如何,此 works ,但再次修复您的设计,并在应用程序层中执行此操作。如果您不在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;

This, like others have said, isn't a job to SQL Server, but your presentation layer. Based on your expected results, I assume that your commas mean you are storing delimited data in your database; a fatal flaw. If you normalised your design, you could likely easily achieve this in your application layer.

As you are using denormalised data, then you need to first normalise it, then reaggregate it too. I use an arbitrary TOP (the rows could be different every time you run the query), as the ordinal parameter is only (currently) available in Azure SQL Database; hopeful the ordinal parameter will be in SQL Server 2022.

Anyway, this works, but again, fix your design, and do this in the application layer. If you aren't on SQL Server 2017, then that is a must, not a very strong suggestion.

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;
久光 2025-01-31 04:15:11

就像其他人所说的那样,这不是SQL Server的工作,但是

如果您必须在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> dbfiddle在这里看到它的工作

结果看起来像这个

ID(无列名称(无列名称)
1Apple,Banana和其他4个
苹果,Banana和其他2Peer,catfish
,catfish and catfish and catfish and catfish,whale,Whale,Whale,Whale,Whale,Whale,Whale,Whale Whale,Whale Whale, WhaleWhale,Whale,Whale, Whale,Whale,Whale,Whale,Whale whale还有1其他人,

如果您不想显示“和X其他”,则可以更改此查询,例如此

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名)
1苹果,香蕉和其他4个
2对等,cat鱼
3狗,鲸鱼和1其他

(无列 >编辑不支持String_agg 的SQL Server,

以防您拥有不支持string_agg函数的SQL Server的较旧版本,则可以使用XML PATH < /code>串联值和stuff以删除Extra

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

使用XML路径 dbfiddle

结果将再次相同

This, like others have said, isn't a job to SQL Server, but your presentation layer

If you must do it in sql, then maybe you can do it like this.
I do assume you have these values in multiple rows and need to concatenate them by some grouping, if not then make that more clear in your question

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

Look at this DBFiddle here to see it working

The result looks like this

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

If you don't want to show the 'and x others' you can alter the query like this

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)
1Apple, Banana and 4 others
2Peer, Catfish
3Dog, Whale and 1 others

EDIT for sql server that does not support string_agg

In case you have an older version of sql server that does not supports the string_agg function, you can do it with XML PATH to concatinate the values and stuff to remove the extra ,

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

The outcome will be the same again

南风起 2025-01-31 04:15:11

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

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

I have created this, and it works for me. However, it needs optimising.

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
吃颗糖壮壮胆 2025-01-31 04:15:11

可以用光标,通过使用函数 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

This task can be solved with the power of the 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文