Sql-Server

在 csv 數據上選擇不同的

  • September 12, 2017

一個表有 CSV 數據,我想SELECT DISTINCT ID在那個表上做一個,我應該怎麼做?

+-----------+
| id        |
+-----------+
| 111,1487  |
+-----------+
| 462       |
+-----------+
| 2492      |
+-----------+
| 3184      |
+-----------+
| 3181,3184 |
+-----------+
| 3181      |
+-----------+
| 440       |
+-----------+
| 1436      |
+-----------+

我有一個我通常使用的函式,它可以將 varchar csv 字元串拆分為一個單列表,我使用如下:

SELECT number from INTLIST_TO_TBL('123,234,345,4566')

它工作得很好,但在這種情況下我不能使用它,因為有很多行並且在某些情況下它會返回多行。

我是否應該嘗試使用插入臨時表的游標,然後通過查詢該臨時表繼續下一步?

有人告訴我游標是性能不佳的同義詞,這就是為什麼我總是在走這條路之前先在這裡詢問。

您應該可以使用CROSS APPLY

為了提供一個最小完整的可驗證範例,我包含了一個“簡單”的 SPLIT TVF,旨在模擬您的 INTLIST_TO_TBL 函式。這僅用於展示目的,並且有更有效的方法來拆分超出我的答案的字元串。

IF EXISTS ( SELECT  *
           FROM    sys.objects
           WHERE   object_id = OBJECT_ID(N'[dbo].[Split]')
                   AND type IN (N'FN', N'IF', N'TF', N'FS', N'FT') ) 
   DROP FUNCTION [dbo].[Split] ;
GO
CREATE FUNCTION [dbo].[Split](@String varchar(8000), @Delimiter char(1))        
returns @temptable TABLE (element int,items varchar(8000))        
as        
begin        
   declare @element int=1
   declare @idx int        
   declare @slice varchar(8000)        

   select @idx = 1        
       if len(@String)<1 or @String is null  return        

   while @idx!= 0        
   begin        
       set @idx = charindex(@Delimiter,@String)        
       if @idx!=0        
           set @slice = left(@String,@idx - 1)        
       else        
           set @slice = @String        

       if(len(@slice)>0)
           begin   
               insert into @temptable(Element,Items) values(@element,@slice)        
               set @element=@element+1
           end 

       set @String = right(@String,len(@String) - @idx)        
       if len(@String) = 0 break        
   end    
return        
end


GO

現在我們有了拆分 TVF,讓我們看一個如何合併它的範例。

DECLARE @tbl TABLE (id VARCHAR(100))

INSERT @tbl
VALUES ('111,1487')
   ,('462')
   ,('2492')
   ,('3184')
   ,('3181,3184')
   ,('3181')
   ,('440')
   ,('1436')

SELECT DISTINCT b.items
FROM @tbl a
CROSS APPLY [dbo].[Split](a.id, ',') b

引用自:https://dba.stackexchange.com/questions/185712