2013-07-05 44 views

Trả lời

29

Tạo chức năng này (sqlserver 2005+)

CREATE function [dbo].[f_split] 
(
@param nvarchar(max), 
@delimiter char(1) 
) 
returns @t table (val nvarchar(max), seq int) 
as 
begin 
set @param += @delimiter 

;with a as 
(
select cast(1 as bigint) f, charindex(@delimiter, @param) t, 1 seq 
union all 
select t + 1, charindex(@delimiter, @param, t + 1), seq + 1 
from a 
where charindex(@delimiter, @param, t + 1) > 0 
) 
insert @t 
select substring(@param, f, t - f), seq from a 
option (maxrecursion 0) 
return 
end 

sử dụng tuyên bố này

SELECT * 
FROM yourtable 
WHERE account in (SELECT val FROM dbo.f_split(@account, ',')) 

Compar ing chức năng phân chia của tôi để XML split:

TestData:

select top 100000 cast(a.number as varchar(10))+','+a.type +','+ cast(a.status as varchar(9))+','+cast(b.number as varchar(10))+','+b.type +','+ cast(b.status as varchar(9)) txt into a 
from master..spt_values a cross join master..spt_values b 

XML:

SELECT count(t.c.value('.', 'VARCHAR(20)')) 
FROM (
    SELECT top 100000 x = CAST('<t>' + 
      REPLACE(txt, ',', '</t><t>') + '</t>' AS XML) 
      from a 
) a 
CROSS APPLY x.nodes('/t') t(c) 

Elapsed time: 1:21 seconds 

f_split:

select count(*) from a cross apply clausens_base.dbo.f_split(a.txt, ',') 

Elapsed time: 43 seconds 

này sẽ thay đổi từ chạy để chạy, nhưng bạn sẽ có được ý tưởng

+0

điều gì sẽ xảy ra nếu '' '@ param''' là null, tôi nghĩ đặt' '' @param + = @ delimiter''' phải được đặt '' '@param = ISNULL (@param, '') + @ delimiter''' –

+0

@SuryaPratap đơn giản và đơn giản - không. Điều đó sẽ không tạo ra sự khác biệt nào cho kết quả. –

3

Hãy thử điều này một -

DDL:

CREATE TABLE dbo.Table1 (
     [EmpId] INT 
    , [FirstName] VARCHAR(7) 
    , [LastName] VARCHAR(10) 
    , [domain] VARCHAR(6) 
    , [Vertical] VARCHAR(10) 
    , [Account] VARCHAR(50) 
    , [City] VARCHAR(50) 
) 

INSERT INTO dbo.Table1 ([EmpId], [FirstName], [LastName], [Vertical], [Account], [domain], [City]) 
VALUES 
    (345, 'Priya', 'Palanisamy', 'DotNet', 'LS', 'Abbott', 'Chennai'), 
    (346, 'Kavitha', 'Amirtharaj', 'DotNet', 'CG', 'Diageo', 'Chennai'), 
    (647, 'Kala', 'Haribabu', 'DotNet', 'DotNet', 'IMS', 'Chennai') 

Query:

DECLARE @Account VARCHAR(200) 
SELECT @Account = 'CG,LS' 

SELECT * 
FROM Table1 
WHERE [Vertical] = 'DotNet' AND (ISNULL(@Account, '') = '' OR Account IN (
    SELECT t.c.value('.', 'VARCHAR(20)') 
    FROM (
     SELECT x = CAST('<t>' + 
       REPLACE(@Account, ',', '</t><t>') + '</t>' AS XML) 
    ) a 
    CROSS APPLY x.nodes('/t') t(c) 
)) 

Output:

proff

thống kê Extended:

stat

SSMS SET THỐNG KÊ THỜI GIAN + IO:

XML:

(3720 row(s) affected) 
Table 'temp'. Scan count 3, logical reads 7, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

SQL Server Execution Times: 
    CPU time = 187 ms, elapsed time = 242 ms. 

CTE:

(3720 row(s) affected) 
Table '#BF78F425'. Scan count 360, logical reads 360, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 
Table 'temp'. Scan count 1, logical reads 7, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

SQL Server Execution Times: 
    CPU time = 281 ms, elapsed time = 335 ms. 
+0

Hãy thử thực hiện việc này: 'WHERE [Vertical] = @Vertical AND (@Account IS NULL HOẶC Tài khoản IN (...))' – Devart

+0

Cảm ơn bạn đã phản hồi Tôi đã thử nhưng 2 bản ghi phải được trả về kết quả ở đây 0 bản ghi chỉ trở về – user2514925

+0

[EmpId], [FirstName], [LastName], [Domain], [Vertical], [Tài khoản] 345, 'Priya', 'Palanisamy', 'DotNet' , 'LS', 'Abbott' 346, 'Kavitha', 'Amirtharaj', 'DotNet', 'CG', 'Diageo' 647, 'Kala', 'Haribabu', 'DotNet', 'DotNet', 'IMS' tôi muốn nhận được kết quả của "select * từ Bảng nơi vertical = 'DotNet' và Tài khoản trong ('CG', 'LS')" truy vấn này bằng cách sử dụng Storedprocedure (bằng cách chuyển Vertical, Giá trị tài khoản động) – user2514925

2

T cách hiệu quả nhất là sử dụng hàm CLR cho chuỗi phân tách.Xem this article để biết ví dụ và so sánh hiệu suất

+0

chức năng CTE được mô tả trong bài viết đó thực sự yếu (so với mô tả tôi đã mô tả). Ông chọn tất cả các giá trị bên trong trong CTE thay vì tìm vị trí của dấu phân cách. Đây là chi phí của rất nhiều tài nguyên máy tính hơn là cần thiết và không thực sự cho CTE một cơ hội công bằng. –

Các vấn đề liên quan