2009-09-21 34 views
5

Tôi có tình huống hiển thị bản ghi trên một trang và tôi cần một cách để người dùng chọn một tập hợp con các bản ghi đó được hiển thị trên một trang khác. Các bản ghi này không được lưu trữ ở bất cứ nơi nào sau đó, nó là một thứ được tạo động. Tôi biết tôi có thể sử dụng jquery để vượt qua trong một giá trị phân cách bằng dấu phẩy để trang web khác của tôi, nhưng tôi không chắc chắn cách tốt nhất để trong sql nói là nơi uniqueid là trong danh sách các id không có trong một bảng vv. biết tôi có thể tự động xây dựng sql với một loạt các ors, nhưng điều đó có vẻ giống như một hack. Bất cứ ai khác có bất cứ lời đề nghị?so sánh một cột với danh sách các giá trị trong t-sql

+1

http://stackoverflow.com/questions/878833/ –

Trả lời

3

đây là nguồn tốt nhất:

http://www.sommarskog.se/arrays-in-sql.html

tạo một hàm tách, và sử dụng nó như:

SELECT 
    * 
    FROM YourTable y 
    INNER JOIN dbo.splitFunction(@Parameter) s ON y.ID=s.Value 

I prefer the number table approach

Đối với phương pháp này để làm việc, bạn cần phải làm một thời gian bảng thiết lập này:

SELECT TOP 10000 IDENTITY(int,1,1) AS Number 
    INTO Numbers 
    FROM sys.objects s1 
    CROSS JOIN sys.objects s2 
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number) 

Khi những con số bảng được thiết lập, tạo ra chức năng này:

CREATE FUNCTION [dbo].[FN_ListToTable] 
(
    @SplitOn char(1)  --REQUIRED, the character to split the @List string on 
    ,@List  varchar(8000)--REQUIRED, the list to split apart 
) 
RETURNS TABLE 
AS 
RETURN 
(

    ---------------- 
    --SINGLE QUERY-- --this will not return empty rows 
    ---------------- 
    SELECT 
     ListValue 
     FROM (SELECT 
        LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue 
        FROM (
          SELECT @SplitOn + @List + @SplitOn AS List2 
         ) AS dt 
         INNER JOIN Numbers n ON n.Number < LEN(dt.List2) 
        WHERE SUBSTRING(List2, number, 1) = @SplitOn 
      ) dt2 
     WHERE ListValue IS NOT NULL AND ListValue!='' 

); 
GO 

Bây giờ bạn có thể dễ dàng chia một CSV chuỗi vào một bảng và tham gia vào nó:

select * from dbo.FN_ListToTable(',','1,2,3,,,4,5,6777,,,') 

OUTPUT:

ListValue 
----------------------- 
1 
2 
3 
4 
5 
6777 

(6 row(s) affected) 

của bạn có thể vượt qua trong một chuỗi CSV vào một thủ tục và quy trình chỉ hàng cho các ID đưa ra:

SELECT 
    y.* 
    FROM YourTable y 
     INNER JOIN dbo.FN_ListToTable(',',@GivenCSV) s ON y.ID=s.ListValue 
0

Bạn có thể sử dụng giải pháp Joel Spolsky recently gave cho sự cố này.

SELECT * FROM MyTable 
WHERE ',' + 'comma,separated,list,of,words' + ',' 
    LIKE '%,' + MyTable.word + ',%'; 

Giải pháp đó thông minh nhưng chậm. Các giải pháp tốt hơn là để phân chia các chuỗi bằng dấu phẩy, và xây dựng một truy vấn SQL động với IN() vị, thêm một placeholder tham số truy vấn cho mỗi phần tử trong danh sách các giá trị:

SELECT * FROM MyTable 
WHERE word IN (?, ?, ?, ?, ?, ?, ?, ?); 

Số placeholders là gì bạn phải xác định thời điểm bạn tách chuỗi được phân cách bằng dấu phẩy. Sau đó, vượt qua một giá trị từ danh sách đó cho mỗi thông số.

Nếu bạn có quá nhiều giá trị trong danh sách và thực hiện một dài IN() ngữ là khó sử dụng, sau đó chèn các giá trị vào một bảng tạm thời, và JOIN chống lại bảng chính của bạn:

CREATE TEMPORARY TABLE TempTableForSplitValues (word VARCHAR(20)); 

...split your comma-separated list and INSERT each value to a separate row... 

SELECT * FROM MyTable JOIN TempTableForSplitValues USING (word); 

Cũng thấy nhiều khác tương tự câu hỏi về SO, bao gồm:

+0

Đầu tiên nói "thiết bị" là tại ít nhất 30 tuổi (nó thậm chí còn có cả chính SQL). Nó không có vẻ thích hợp để đổi tên nó sau khi một người đương đại. – RBarryYoung

+0

Đủ công bằng. Tôi sẽ viết lại câu. –

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