2012-04-04 28 views
20

truy vấn: select id from users where id in (1,2,3,4,5)SELECT trả về danh sách các giá trị không xảy ra trong bất kỳ hàng

Nếu bảng người dùng chứa id 1, 2, 3, điều này sẽ trở lại 1, 2, và 3. Tôi muốn có một truy vấn mà sẽ quay trở lại 4 và 5. Nói cách khác, tôi không muốn truy vấn trả về bất kỳ hàng nào tồn tại trong bảng, tôi muốn cung cấp cho nó một danh sách các số và nhận các giá trị từ danh sách đó không xuất hiện trong bàn.

(cập nhật để làm rõ câu hỏi sau vài câu trả lời không phù hợp)

+0

Làm thế nào bạn sẽ chọn id cho 1,2 , 3,4,5? có phải là số cố định hoặc 1 đến ID tối đa được sử dụng không? – BugFinder

+0

@BugFinder: đó là số cố định. – Dev

+0

Tôi có thiếu gì đó ở đây không? Bảng người dùng của bạn chỉ chứa id của 1,2 và 3 nhưng bạn muốn nhận được id của 4 và 5? 4 và 5 của id ở đâu? Nếu họ không có trong bảng người dùng, bạn sẽ không nhận được bất cứ điều gì cho dù bạn nói 'chọn id từ người dùng trong đó id in (4,5)' hoặc bất cứ truy vấn nào khác bạn ném vào nó ... – DaveyBoy

Trả lời

10

Với các số là danh sách cố định. Cách nhanh nhất mà tôi có thể nghĩ đến là có một bảng thử nghiệm, được điền bằng những con số đó và làm

tuyên bố chọn chưa được kiểm tra - nhưng bạn sẽ tuân theo nguyên tắc.

select test.number from test left join users on test.number = users.id where test.number<>users.id 

Sau đó, bạn sẽ lấy lại tất cả những con số mà không có một user.id phù hợp và do đó có thể điền vào các lỗ ..

+1

câu trả lời bởi @safarov .... 'SELECT id FROM temp_ids WHERE temp_ids.id KHÔNG IN (SELECT id FROM users)' có vẻ tốt quá. – Dev

+0

@BugFinder +1, cuối cùng bạn nhận được câu hỏi – safarov

+0

Đây là một ý tưởng hay. Nó có tác dụng phụ có lợi mà phạm vi của các ID có thể được lưu trữ trong một bảng, thay vì bị ẩn trong một truy vấn ở đâu đó trong mã. – octern

1

Viết not in thay vì in

select id from users where id not in (1,2,3,4,5) 

Nếu bạn muốn điều ngược lại trong danh sách nhưng không có trong bảng. Temp_ids là bảng tạm thời bao gồm danh sách id của bạn

SELECT id FROM temp_ids WHERE temp_ids.id NOT IN (SELECT id FROM users) 
+0

-1, Không chính xác, điều này sẽ không trả lại bất kỳ kết quả nào, nhưng tôi cần 4 và 5. trong danh sách nhưng không nằm trong cột id của bảng người dùng. – Dev

+0

bảng chứa 3 bản ghi có id: 1,2,3 – Dev

+0

Vấn đề là nhà phát triển đang cố gắng tìm các số bị thiếu trong danh sách, vì vậy, thời lượng là 1 đến 5 hoặc 1 đến 1000, hes sau danh sách số có sẵn từ phạm vi chưa được phân bổ – BugFinder

2

Một lựa chọn khác là sử dụng bảng khác có chứa tất cả các id càng tốt và sau đó làm một lựa chọn từ đó:

mysql> describe ids; 
+-------+-----------------+------+-----+---------+-------+ 
| Field | Type   | Null | Key | Default | Extra | 
+-------+-----------------+------+-----+---------+-------+ 
| id | int(5) unsigned | NO |  | 0  |  | 
+-------+-----------------+------+-----+---------+-------+ 
1 row in set (0.05 sec) 

mysql> select * from ids; 
+----+ 
| id | 
+----+ 
| 1 | 
| 2 | 
| 3 | 
| 4 | 
| 5 | 
+----+ 
5 rows in set (0.00 sec) 

mysql> select * from users; 
+----+ 
| id | 
+----+ 
| 1 | 
| 2 | 
| 3 | 
+----+ 
3 rows in set (0.00 sec) 


mysql> select id from ids where id not in (select id from users); 
+----+ 
| id | 
+----+ 
| 4 | 
| 5 | 
+----+ 
2 rows in set (0.04 sec) 

gia tăng tác dụng phụ - cho phép bạn mở rộng danh sách kết quả bằng cách chèn vào bảng id

+0

Đúng, đó là đề nghị của tôi. – BugFinder

+0

@BugFinder - xin lỗi - Tôi hơi chậm phát triển ngày hôm nay – DaveyBoy

+1

Thats OK bạn có hình ảnh đẹp :) – BugFinder

10

Đã nhu cầu tương tự và xây dựng trên câu trả lời bởi BugFinder sử dụng bảng tạm thời trong phiên. Bằng cách này, nó sẽ tự động bị phá hủy sau khi tôi thực hiện xong truy vấn, vì vậy tôi không phải đối phó với việc dọn dẹp nhà cửa vì tôi sẽ chạy loại truy vấn này thường xuyên.

Tạo bảng tạm thời:

CREATE TEMPORARY TABLE tmp_table (id INT UNSIGNED); 

cư tmp_table với các giá trị bạn sẽ kiểm tra:

INSERT INTO tmp_table (id) values (1),(2),(3),(4),(5); 

Với bảng tạo ra và dân cư, chạy truy vấn như với bất kỳ bảng thông thường:

SELECT tmp_table.id 
    FROM tmp_table 
    LEFT JOIN users u 
    ON tmp_table.id = u.id 
    WHERE u.id IS NULL; 

This info on MySQL Temporary Tables was also useful

13

Nếu bạn không muốn (rõ ràng) sử dụng bảng tạm thời, điều này sẽ làm việc:

SELECT id FROM (
    (SELECT 1 AS id) UNION ALL 
    (SELECT 2 AS id) UNION ALL 
    (SELECT 3 AS id) UNION ALL 
    (SELECT 4 AS id) UNION ALL 
    (SELECT 5 AS id) 
) AS list 
LEFT JOIN users USING (id) 
WHERE users.id IS NULL 

Tuy nhiên, nó là khá xấu xí, khá dài, và tôi mơ hồ về nó như thế nào sẽ thực hiện nếu danh sách ID dài.

+0

Cảm ơn, chỉ vì sự hoàn chỉnh. Nếu các con số là VARCHAR, bạn phải đảm bảo bạn sử dụng cùng loại CHARACTER nếu bạn nhận được ERROR 1267 SO nếu DataBade của bạn là utf8 -> SELECT id FROM ( (SELECT CONVERT ("1" USING utf8) AS id) UNION ALL (SELECT CONVERT ("2" SỬ DỤNG utf8) AS id) UNION ALL (SELECT CONVERT ("3" SỬ DỤNG utf8) AS id) UNION ALL (SELECT CONVERT ("4" SỬ DỤNG utf8) AS id) UNION ALL (SELECT CONVERT ("5" SỬ DỤNG utf8) AS id) ) AS danh sách LEFT JOIN người dùng SỬ DỤNG (id) WHERE users.id IS NULL; SORRY tôi biết HARD để đọc trong một bình luận = ^) – irJvV

0

Xin lỗi, tôi không thể thêm nhận xét, @Austin,

Bạn có +1 của mình.

Dù sao, không chắc chắn nếu điều này hoạt động trên mysql, nhưng thay đổi tất cả mà chọn nguyên tử nối nghiệp đoàn cho một tập giá trị, vì vậy bạn có cái gì đó như thế:

SELECT id FROM (
    VALUES (1), (2), (3), (4), (5) 
) AS list(id) 
LEFT JOIN users USING (id) 
WHERE users.id IS NULL 
Các vấn đề liên quan