ส่งคืนค่าบูลีนบนคำสั่ง SQL Select


144

จะคืนค่าบูลีนได้อย่างไรในคำสั่ง SQL Select?

ฉันลองรหัสนี้:

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

และจะส่งกลับเฉพาะTRUEถ้าUserIDมีอยู่บนโต๊ะ ฉันต้องการให้มันคืนFALSEหากUserIDไม่มีอยู่บนโต๊ะ


3
dbms ใด รายละเอียดของ sql แตกต่างกัน
joshp

SQL Server ไม่สนับสนุนประเภทบูลีนเช่นSELECT WHEN CAST(1 AS BIT) THEN 'YES' END AS result- ส่งผลให้เกิดข้อผิดพลาดเช่นCAST(1 AS BIT)ไม่ใช่ตรรกะจริง
oneday เมื่อ

คำตอบ:


253

สิ่งที่คุณมีจะไม่ส่งคืนแถวเลยหากผู้ใช้ไม่มีอยู่ นี่คือสิ่งที่คุณต้องการ:

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

2
ทำไมใช้เครื่องหมายดอกจันมันจะดีกว่าถ้าคุณใช้แทน1 *

7
@ robertpeter07 - ทั้งสองเทียบเท่ากัน แต่*มีสำนวนมากกว่า ดูคำถามนี้
Chad

หากใช้กับลูป WHILE ฉันจะต้องใส่มันไว้ในวงเล็บ {} ทันทีหลังจาก 'WHILE'?
full_prog_full

คุณสามารถเพิ่มชื่อคอลัมน์ในค่าที่ส่งคืนได้หรือไม่?
xMetalDetectorx

3
@xMetalDetectorx สิ่งนี้ได้ผลสำหรับฉันที่จะเพิ่มชื่อคอลัมน์ ( AS boolส่วนสำคัญมาก):CAST( CASE WHEN EXISTS ( SELECT * FROM mytable WHERE mytable.id = 1) THEN TRUE ELSE FALSE END AS bool) AS nameofmycolumn
Lucio Mollinedo

31

อาจเป็นไปได้บางอย่างตามบรรทัดเหล่านี้:

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
ส่งคืนสตริงไม่ใช่บูลีน
OMG Ponies

เป็นวิธีปฏิบัติที่ดีที่จะรวมชื่อคอลัมน์ - เลือกนักแสดง (กรณีเมื่อ COUNT (*)> 0 จากนั้น 1 อีก 1 จบ 0 เป็นบิต) เป็นชื่อไมคอolจาก Dummy WHERE id = 1
Diego Alves

22

ระบุว่าโดยทั่วไป1 = trueและสิ่งที่คุณต้องทำคือการนับจำนวนแถวและโยนไป0 = falseboolean

ดังนั้นรหัสที่คุณโพสต์ต้องการเพียงแค่COUNT()เพิ่มฟังก์ชั่น:

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

8
การทำExists(แบบทดสอบเร็วกว่าการทำแบบCount(1)ทดสอบในตารางที่มีจำนวนแถวมาก
Scott Chamberlain

5
อาจ. ฉันไม่ได้อ้างสิทธิ์ในคำตอบของฉันเพียงแค่การเปลี่ยนรหัสขั้นต่ำเพื่อให้ได้สิ่งที่ OP ต้องการ อย่างไรก็ตามหากUserIDมีการจัดทำดัชนีคอลัมน์(หรือแม้แต่ PK) คุณจะตรงไปยังแถวที่ไม่ซ้ำกันซึ่งมีอยู่ (หรือไม่)
Stewart

9

ใช้ 'มีอยู่' ซึ่งส่งคืนค่า 0 หรือ 1

แบบสอบถามจะเป็นเช่น:

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

10
ข้อผิดพลาด: "ไวยากรณ์ไม่ถูกต้องใกล้กับคำหลัก" EXISTS " sqlfiddle.com/#!18/ef905/18
JoePC

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

ถ้า count (*) = 0 ส่งคืนค่าเท็จ ถ้า count (*)> 0 ผลตอบแทนจริง


4

ฉันทำแบบนี้:

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

การเห็นว่าเป็นบูลีนจะไม่มีวันเป็นโมฆะ (อย่างน้อยก็ใน. NET) มันควรเป็นค่าเริ่มต้นเป็นเท็จหรือคุณสามารถตั้งค่าให้เป็นตัวคุณเองได้หากมันเป็นค่าเริ่มต้นจริง อย่างไรก็ตาม 1 = จริงดังนั้น null = false และไม่มีไวยากรณ์เพิ่มเติม

หมายเหตุ: ฉันใช้ Dapper เป็น micro orm ของฉันฉันจินตนาการว่า ADO ควรทำงานเหมือนกัน


คำตอบที่กระชับที่สุดที่ฉันโปรดปราน Fiddle ของคำตอบทั้งหมด: sqlfiddle.com/#!18/ef905/18
JoePC

"การเห็นว่าเป็นบูลีนจะไม่มีผลใด ๆ (อย่างน้อยก็ใน. NET)" (bool?) เป็นบูลแบบ nullable
Andrew Dennison

1

สังเกตเห็นปัญหาที่เทียบเท่าอื่น: การสร้างเคียวรี SQL ที่ส่งคืน (1) หากเงื่อนไขเป็นไปตามเงื่อนไขและผลลัพธ์ที่ว่างเปล่าเป็นอย่างอื่น โปรดสังเกตว่าวิธีแก้ปัญหานี้เป็นเรื่องทั่วไปและสามารถใช้กับคำตอบข้างต้นได้อย่างง่ายดายเพื่อให้ได้คำถามที่คุณถาม เนื่องจากปัญหานี้เป็นเรื่องทั่วไปฉันจึงพิสูจน์วิธีแก้ปัญหาเพิ่มเติมจากวิธีแก้ปัญหาที่สวยงามที่นำเสนอข้างต้นกับปัญหาของคุณ

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

1

สำหรับบรรดาของคุณที่มีความสนใจในการรับค่าเพิ่มชื่อคอลัมน์ที่กำหนดเองนี้ทำงานสำหรับฉัน:

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

คุณสามารถข้ามเครื่องหมายอัญประกาศคู่จากชื่อคอลัมน์ในกรณีที่คุณไม่สนใจรักษาขนาดตัวอักษรของชื่อ (ในไคลเอ็นต์บางราย)

ฉันปรับแต่งคำตอบของ @ Chad เล็กน้อยสำหรับเรื่องนี้


ข่าวสารเกี่ยวกับ 102 ระดับ 15 สถานะ 1 บรรทัด 8 ไวยากรณ์ที่ไม่ถูกต้องใกล้กับ 'CAST' เกี่ยวกับข่าวสาร 156 ระดับ 15 สถานะ 1 บรรทัด 12 ไวยากรณ์ไม่ถูกต้องใกล้กับคำหลัก 'THEN'
ShaneC

@ShaneC ฉันทดสอบโค้ดนี้ใน PostgreSQL 9.X และใช้งานได้ดี คุณใช้เซิร์ฟเวอร์อะไร
Lucio Mollinedo

0
DECLARE @isAvailable      BIT = 0;

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

เริ่มแรกคือค่าบูลีน isAvailable ถูกตั้งค่าเป็น 0

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.