Trả về giá trị Boolean trên SQL Chọn câu lệnh


144

Làm cách nào để trả về giá trị boolean trên SQL Chọn Statement?

Tôi đã thử mã này:

SELECT CAST(1 AS BIT) AS Expr1
FROM [User]
WHERE (UserID = 20070022)

Và nó chỉ trở lại TRUEnếu UserIDtồn tại trên bàn. Tôi muốn nó trở lại FALSEnếu UserIDkhông tồn tại trên bàn.


3
Những dbms nào? Chi tiết của sql khác nhau.
joshp

SQL Server không hỗ trợ loại Boolean, ví dụ SELECT WHEN CAST(1 AS BIT) THEN 'YES' END AS result- dẫn đến lỗi, nghĩa CAST(1 AS BIT)là không phải là TRUE logic tương tự.
onedaywhen

Câu trả lời:


253

Những gì bạn có sẽ không trả lại hàng nếu người dùng không tồn tại. Đây là những gì bạn cần:

SELECT CASE WHEN EXISTS (
    SELECT *
    FROM [User]
    WHERE UserID = 20070022
)
THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT) END

2
Tại sao sử dụng dấu hoa thị, sẽ tốt hơn nếu bạn sử dụng 1thay vì *.

7
@ robertpeter07 - Hai cái này tương đương nhau, nhưng *thành ngữ hơn. Xem câu hỏi này .
Chad

Nếu sử dụng trên vòng lặp WHILE, tôi có phải đặt nó trong vòng ngoặc {} ngay sau 'WHILE' không?
full_prog_full

Bạn có thể thêm một tên cột vào giá trị trả về?
xMetalDetectorx

3
@xMetalDetectorx Điều này giúp tôi thêm tên cột ( AS boolphần rất quan trọng):CAST( CASE WHEN EXISTS ( SELECT * FROM mytable WHERE mytable.id = 1) THEN TRUE ELSE FALSE END AS bool) AS nameofmycolumn
Lucio Mollinedo

31

Có thể một cái gì đó dọc theo những dòng này:

SELECT CAST(CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END AS BIT)
FROM dummy WHERE id = 1;

http://sqlfiddle.com/#!3/5e555/1


6
Điều này trả về một chuỗi, không phải là boolean
OMG Ponies

Đó là một cách thực hành tốt để bao gồm một tên cột - CHỌN CAST (TRƯỜNG HỢP KHI QUẬN (*)> 0 THÌ 1 ELSE 0 END AS BIT) làm tên màu của tôi TỪ hình nộm WHERE id = 1
Diego Alves

22

Cho rằng thông thường 1 = true0 = false, tất cả những gì bạn cần làm là đếm số lượng hàng và chuyển thành a boolean.

Do đó, mã được đăng của bạn chỉ cần một COUNT()chức năng được thêm vào:

SELECT CAST(COUNT(1) AS BIT) AS Expr1
FROM [User]
WHERE (UserID = 20070022)

8
Làm Exists(bài kiểm tra nhanh hơn nhiều so với làm Count(1)bài kiểm tra trên các bảng có số lượng hàng lớn.
Scott Chamberlain

5
Có lẽ. Tôi không đưa ra yêu cầu nào về hiệu suất trong câu trả lời của mình, chỉ cần thay đổi mã tối thiểu để đạt được những gì OP muốn. Tuy nhiên, nếu cột UserIDđược lập chỉ mục (hoặc thậm chí là PK), chắc chắn bạn sẽ đi thẳng đến một hàng duy nhất tồn tại (hoặc không).
Stewart

9

Sử dụng 'Tồn tại' trả về 0 hoặc 1.

Truy vấn sẽ như sau:

SELECT EXISTS(SELECT * FROM USER WHERE UserID = 20070022)

10
Lỗi: "Cú pháp không chính xác gần từ khóa 'EXISTS'." sqlfiddle.com/#!18/ef905/18
JoePC

8
select CAST(COUNT(*) AS BIT) FROM [User] WHERE (UserID = 20070022)

Nếu đếm (*) = 0 trả về sai. Nếu đếm (*)> 0 trả về đúng.


4

Tôi làm như thế này:

SELECT 1 FROM [dbo].[User] WHERE UserID = 20070022

Xem như là một boolean không bao giờ có thể là null (ít nhất là trong .NET), nó sẽ mặc định thành false hoặc bạn có thể tự đặt nó thành đó nếu nó mặc định là true. Tuy nhiên 1 = true, vì vậy null = false và không có cú pháp bổ sung.

Lưu ý: Tôi sử dụng Dapper làm micro orm của mình, tôi tưởng tượng ADO sẽ hoạt động tương tự.


Yêu thích của tôi, câu trả lời ngắn gọn nhất cho đến nay. Câu đố
JoePC 16/07/18

"Xem như là một boolean không bao giờ có thể là null (ít nhất là trong .NET)." (bool?) là một bool nullable.
Andrew Dennison

1

Lưu ý một vấn đề tương đương khác: Tạo một truy vấn SQL trả về (1) nếu điều kiện được thỏa mãn và kết quả trống khác. Lưu ý rằng một giải pháp cho vấn đề này là tổng quát hơn và có thể dễ dàng được sử dụng với các câu trả lời ở trên để đạt được câu hỏi mà bạn đã hỏi. Vì vấn đề này là tổng quát hơn, tôi đang chứng minh giải pháp của mình bên cạnh các giải pháp đẹp được trình bày ở trên cho vấn đề của bạn.

SELECT DISTINCT 1 AS Expr1
FROM [User]
WHERE (UserID = 20070022)

1

Đối với những người bạn quan tâm đến việc nhận giá trị thêm tên cột tùy chỉnh, điều này hiệu quả với tôi:

CAST(
    CASE WHEN EXISTS ( 
           SELECT * 
           FROM mytable 
           WHERE mytable.id = 1
    ) 
    THEN TRUE 
    ELSE FALSE 
    END AS bool) 
AS "nameOfMyColumn"

Bạn có thể bỏ qua dấu ngoặc kép từ tên cột trong trường hợp bạn không quan tâm đến việc giữ độ nhạy trường hợp của tên (ở một số khách hàng).

Tôi hơi điều chỉnh câu trả lời của @ Chad cho việc này.


Msg 102, Cấp 15, Trạng thái 1, Dòng 8 Cú pháp không chính xác gần 'CAST'. Msg 156, Cấp 15, Trạng thái 1, Dòng 12 Cú pháp không chính xác gần từ khóa 'THEN'.
ShaneC

@ShaneC Tôi đã thử nghiệm mã này trên PostgreSQL 9.X và nó hoạt động tốt. Bạn đang sử dụng máy chủ nào?
Lucio Mollinedo

0
DECLARE @isAvailable      BIT = 0;

IF EXISTS(SELECT 1  FROM [User] WHERE (UserID = 20070022))
BEGIN
 SET @isAvailable = 1
END

ban đầu giá trị boolean có sẵn được đặt thành 0

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.