2010-07-08 72 views
8

Cho phép xem xét Tôi có một bảng 'Tab' trong đó có một cột 'Col'Query: tìm hàng mà không thuộc về một danh sách các giá trị

Bảng 'Tab' có dữ liệu này -

Col 
1 
2 
3 
4 
5 

Nếu tôi có một bộ giá trị (2,3,6,7). Tôi có thể truy vấn các giá trị mà có mặt trong bảng và danh sách bằng cách khởi kiện truy vấn

Select Col from Tab where col IN (2,3,6,7) 

Nhưng, nếu tôi muốn quay trở lại các giá trị trong danh sách mà không có mặt trong bảng tức là chỉ (6,7) trong trường hợp này. Tôi nên sử dụng truy vấn nào?

+0

Bạn đang sử dụng RDBMS và phiên bản nào? –

+0

Trong các bình luận bạn đã thêm vào các câu trả lời khác nhau, tôi thấy rằng bạn đang xử lý các giá trị chuỗi, không phải số nguyên và danh sách đầu vào của bạn chứa một nơi nào đó trong vùng lân cận của 70 giá trị. Bạn đang tìm cách viết một thủ tục lưu sẵn? Sử dụng SQL được tạo động? Truy vấn tham số? Như Martin đã hỏi, bạn đang làm việc với nền tảng và phiên bản DB nào? Điều đó sẽ cho chúng tôi biết chúng tôi phải làm việc với tính năng nào. (XML, UDF, vv) Có phải Linq-> SQL là một tùy chọn không? – Toby

+0

@Martin Tôi đang làm việc trên SQL Server 2005. @Toby Tôi chỉ đang cố gắng sử dụng truy vấn sql để truy xuất các hàng đáp ứng các điều kiện tôi đã đề cập trong câu hỏi. – pavanred

Trả lời

3

Vấn đề tôi tin là bạn đang cố gắng tìm giá trị từ bạn trong bảng sao kê. Những gì bạn cần làm là biến câu lệnh trong của bạn thành một bảng và sau đó bạn có thể xác định giá trị nào khác nhau.

create table #temp 
(
value int 
) 

insert into #temp values 1 
insert into #temp values 2 
insert into #temp values 3 
insert into #temp values 4 

select 
id 
from 
#temp 
where 
not exists (select 1 from Tab where Col = id) 

Thay thế tốt hơn là tạo hàm giá trị bảng để biến chuỗi được phân cách bằng dấu phẩy thành bảng. Tôi không có bất kỳ mã nào tiện dụng, nhưng nó phải dễ tìm trên Google. Trong trường hợp đó, bạn chỉ cần sử dụng cú pháp bên dưới.

select 
id 
from 
dbo.SplitStringToTable('2,3,6,7') 
where 
not exists (select 1 from Tab where Col = id) 

Hope this helps

+0

Tôi đã sử dụng một ví dụ ở đây để đơn giản. Tôi thực sự đang xử lý khoảng 70 giá trị. Viết 70 câu lệnh chèn không thực sự thực tế. Tôi tự hỏi nếu có một cách đơn giản hơn để làm điều này. Cảm ơn câu trả lời anyway. – pavanred

+0

Bạn xác định các giá trị như thế nào? – Wade73

+1

xin lỗi tôi đã thêm nhận xét trước khi thử phần sau câu trả lời của bạn, tức là để tạo hàm có giá trị bảng để biến chuỗi được phân tách bằng dấu phẩy thành bảng. Tôi đã thử điều này ngay bây giờ nó trở nên đơn giản sau khi tôi nhận được danh sách các giá trị vào một bảng. Cảm ơn bạn. – pavanred

0

Một phương pháp là

declare @table table(col int) 
insert into @table 
select 1 union all 
select 2 union all 
select 3 union all 
select 4 union all 
select 5 


declare @t table(col int) 
insert into @t 
select 2 union all 
select 3 union all 
select 6 union all 
select 7 

select t1.col from @t as t1 left join @table as t2 on t1.col=t2.col 
where t2.col is null 
2

một cách sẽ được sử dụng một bảng temp:

DECLARE @t1 TABLE (i INT) 
INSERT @t1 VALUES(2) 
INSERT @t1 VALUES(3) 
INSERT @t1 VALUES(6) 
INSERT @t1 VALUES(7) 

SELECT i FROM @t1 WHERE i NOT IN (Select Col from Tab) 
+0

+1 để ăn cắp câu trả lời của tôi :) – Wade73

+0

Tôi đã sử dụng một ví dụ ở đây để đơn giản. Tôi thực sự đang xử lý khoảng 70 giá trị. Viết 70 câu lệnh chèn không thực sự thực tế. Tôi tự hỏi nếu có một cách đơn giản hơn để làm điều này. Cảm ơn câu trả lời. – pavanred

3

Một SQL Server phương pháp 2008

SELECT N FROM (VALUES(2),(3),(6),(7)) AS D (N) 
EXCEPT 
Select Col from Tab 

Hoặc SQL Server 2005

DECLARE @Values XML 

SET @Values = 
'<r> 
    <v>2</v> 
    <v>3</v> 
    <v>6</v> 
    <v>7</v> 
</r>' 


SELECT 
    vals.item.value('.[1]', 'INT') AS Val 
FROM @Values.nodes('/r/v') vals(item) 
EXCEPT 
Select Col from Tab 
+0

+1 để sử dụng các kỹ thuật mới nhất – Wade73

0

Bạn có bảng [số] trong cơ sở dữ liệu của mình không? (Xem Why should I consider using an auxiliary numbers table?)

SELECT 
    [Tab].* 
FROM 
    [numbers] 
    LEFT JOIN [Tab] 
     ON [numbers].[num] = [Tab].[Col] 
WHERE 
    [numbers].[num] IN (2, 3, 6, 7) 
    AND [Tab].[Col] IS NULL 
+0

Cảm ơn câu trả lời. Tôi không biết điều này. Nhưng, tôi đã sử dụng một ví dụ ở đây để đơn giản. Tôi thực sự đang đối phó với varchar và không phải số. – pavanred

0

Tôi nghĩ rằng có rất nhiều cách để đạt được điều này, đây là một trong.

SELECT a.col 
FROM 
    (SELECT 2 AS col UNION ALL SELECT 3 UNION ALL SELECT 6 UNION ALL SELECT 7) AS a 
WHERE a.col NOT IN (SELECT col FROM Tab) 
0

muộn để đảng ...

SELECT 
    '2s' = SUM(CASE WHEN Tab.Col = 2 THEN 1 ELSE 0 END), 
    '3s' = SUM(CASE WHEN Tab.Col = 3 THEN 1 ELSE 0 END), 
    '6s' = SUM(CASE WHEN Tab.Col = 6 THEN 1 ELSE 0 END), 
    '7s' = SUM(CASE WHEN Tab.Col = 7 THEN 1 ELSE 0 END) 
FROM 
(SELECT 1 AS Col, 'Nums' = 1 UNION SELECT 2 AS Col,'Nums' = 1 UNION SELECT 3 AS Col,  'Nums' = 1 UNION SELECT 4 AS Col, 'Nums' = 1 UNION SELECT 5 AS Col, 'Nums' = 1) AS Tab 
GROUP BY Tab.Nums 

BTW, tôi cũng cho tội danh từng, hữu ích nếu bạn cần nó. Giống như nếu bạn đang kiểm tra danh sách sản phẩm dựa trên những gì bạn có trong khoảng không quảng cáo. Mặc dù bạn có thể viết một trục cho tốt hơn, chỉ cần không biết làm thế nào ra khỏi đỉnh đầu của tôi.

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