ตัวดำเนินการนี้คืออะไร <=> ใน MySQL


163

ฉันกำลังทำงานกับโค้ดที่เขียนโดยนักพัฒนาคนก่อนหน้านี้

WHERE p.name <=> NULL

อะไร<=>หมายถึงในแบบสอบถามนี้? มันเท่ากับ=อะไรเหรอ? หรือเป็นข้อผิดพลาดทางไวยากรณ์หรือไม่

แต่จะไม่แสดงข้อผิดพลาดหรือข้อยกเว้น ผมรู้อยู่แล้วว่า<>= !=ในMySQL


19
spaceshipผู้ประกอบการ
Moha อูฐยิ่งใหญ่

4
@ Mhd.Tahawi เราต้องการ google ที่อนุญาตให้เรา google สำหรับผู้ให้บริการโดยตรง
Pacerier

@Pacerier - ฉันพบนี้หลายปีที่ผ่านมา 5ish symbolhound.com (dunno ถ้ามีทางเลือกที่ดีกว่า)
แอนดรู

คำตอบ:


239

TL; DR

มันเป็นโอเปอเรเตอร์ที่NULLปลอดภัย

เช่นเดียวกับ=โอเปอเรเตอร์ปกติมีการเปรียบเทียบสองค่าและผลลัพธ์จะเป็น0(ไม่เท่ากัน) หรือ1(เท่ากัน) ในคำอื่น ๆ : 'a' <=> 'b'อัตราผลตอบแทน0และอัตราผลตอบแทน'a' <=> 'a'1

ต่างจาก=ผู้ปฏิบัติงานทั่วไปค่าที่NULLไม่มีความหมายพิเศษและดังนั้นจึงไม่เคยให้ผลลัพธ์NULLที่เป็นไปได้ ดังนั้น: 'a' <=> NULLอัตราผลตอบแทน0และอัตราผลตอบแทนNULL <=> NULL1

ความมีประโยชน์

สิ่งนี้มีประโยชน์เมื่อตัวถูกดำเนินการทั้งสองอาจมีNULLและคุณต้องการผลลัพธ์การเปรียบเทียบที่สอดคล้องกันระหว่างสองคอลัมน์

การใช้งานอื่น ๆ พร้อมกับข้อความสั่งที่เตรียมไว้เช่น:

... WHERE col_a <=> ? ...

ที่นี่ตัวยึดตำแหน่งอาจเป็นค่าสเกลาร์หรือNULLไม่ต้องเปลี่ยนแปลงอะไรเกี่ยวกับแบบสอบถาม

ผู้ประกอบการที่เกี่ยวข้อง

นอกจากนี้<=>ยังมีโอเปอเรเตอร์อีกสองตัวที่สามารถใช้เปรียบเทียบกับNULLคือIS NULLและIS NOT NULL; พวกเขาเป็นส่วนหนึ่งของมาตรฐาน ANSI ดังนั้นจึงสนับสนุนในฐานข้อมูลอื่นซึ่งแตกต่างจาก<=>ซึ่งเป็นเฉพาะ MySQL

คุณสามารถคิดว่ามันเป็นความเชี่ยวชาญของ MySQL <=>:

'a' IS NULL     ==> 'a' <=> NULL
'a' IS NOT NULL ==> NOT('a' <=> NULL)

ด้วยเหตุนี้แบบสอบถามเฉพาะของคุณ (ส่วน) สามารถแปลงเป็นแบบพกพาได้มากขึ้น:

WHERE p.name IS NULL

สนับสนุน

มาตรฐาน SQL: 2003 ได้นำเสนอเพรดิเคตสำหรับสิ่งนี้ซึ่งทำงานเหมือนกับ<=>ตัวดำเนินการของ MySQL ในรูปแบบต่อไปนี้:

IS [NOT] DISTINCT FROM 

ต่อไปนี้ได้รับการสนับสนุนในระดับสากล แต่มีความซับซ้อนเชิงสัมพันธ์:

CASE WHEN (a = b) or (a IS NULL AND b IS NULL)
     THEN 1
     ELSE 0
END = 1

2
ดังนั้นหมายความว่าไม่มีความแตกต่าง? และนี่<=>คือผู้ประกอบการที่ไร้ประโยชน์หรือไม่ ขวา?
zzlalani

16
@zzlalani ไม่เลย; <=>ใช้เวลาสองตัวถูกดำเนินการในขณะที่IS (NOT) NULLใช้เพียงหนึ่ง; ความแตกต่างใหญ่ ... มันมีประโยชน์เท่า ๆ กัน=ในแง่นั้น
Ja͢ck

12
@zzlalani IS NULLและIS NOT NULLอยู่ในมาตรฐาน SQL <=>เป็นส่วนเสริมเฉพาะของ MySQL
Daniel Dinnyes

5
ดังนั้นเช่นis not distinct fromผู้ประกอบการ อยากรู้ว่าถ้า MySQL สามารถใช้ดัชนีบนที่ ...
เดนิสเดอ Bernardy

3
@Pacerier ไม่มีค่าผกผันของการมีa <=> b NOT(a <=> b)
Ja͢ck

57

คือ<=> NULL-safe equal to operator

ตัวดำเนินการนี้ทำการเปรียบเทียบความเท่าเทียมกันเช่นตัวดำเนินการ = แต่คืนค่า 1 แทนที่จะเป็น NULL ถ้าตัวถูกดำเนินการทั้งคู่เป็น NULL และ 0 มากกว่า NULL ถ้าตัวถูกดำเนินการตัวหนึ่งเป็น NULL

ดูที่นี่สำหรับเอกสาร

ตัวอย่าง:

คุณควรใช้ไม่เป็นโมฆะ (ตัวดำเนินการเปรียบเทียบ = และ <> ทั้งสองให้ UNKNOWN กับ NULL ที่ด้านใดด้านหนึ่งของนิพจน์)

SELECT * 
FROM table 
WHERE YourColumn IS NOT NULL;

ยังสามารถปฏิเสธตัวดำเนินการความปลอดภัยของค่าว่างที่เป็นโมฆะ แต่นี่ไม่ใช่ SQL มาตรฐาน

SELECT *
FROM table 
WHERE NOT (YourColumn <=> NULL);

1
การแก้ไข: <=>ควรเรียกว่าตัวดำเนินการเท่ากับและ=เป็นตัวดำเนินการที่NULLไม่ปลอดภัยเท่ากับ
Pacerier

26

เป็นค่า NULL ที่ปลอดภัยเท่ากับตัวดำเนินการ

<=> ผู้ประกอบการใช้ในการเปรียบเทียบค่า NULL กับเขตข้อมูล ถ้า normal = (เท่ากับ) ตัวดำเนินการคืนค่า NULL ถ้าหนึ่งในค่าการเปรียบเทียบคือ NULL ด้วย <=> โอเปอเรเตอร์คืนค่าจริงหรือเท็จ <=> ผู้ประกอบการเหมือนกับ IS NULL

จากคู่มือ: -

<=> ทำการเปรียบเทียบความเท่าเทียมกันเช่นตัวดำเนินการ = แต่ส่งคืน 1 แทนที่จะเป็น NULL ถ้าตัวถูกดำเนินการทั้งสองเป็น NULL และ 0 แทนที่จะเป็น NULL ถ้าตัวถูกดำเนินการหนึ่งตัวเป็น NULL

mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
        -> 1, 1, 0
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;
        -> 1, NULL, NULL

แก้ไข: - ( แม้ว่าจะช้ามากที่จะเพิ่มบันทึกย่อด้านหนึ่งที่กล่าวถึงไม่ <=>เช่นกัน )

ในหมายเหตุด้าน: -

ไม่ <=>

มีอีกหนึ่งจุดคือไม่ <=>ซึ่งใช้ในการเปรียบเทียบค่า NULL กับเขตข้อมูล ถ้า Normal! = หรือ <> (ไม่เท่ากับ) ตัวดำเนินการคืนค่า NULL ถ้าหนึ่งในค่าการเปรียบเทียบคือ NULL ด้วย NOT ที่ใช้กับ <=> โอเปอเรเตอร์จะคืนค่าจริงหรือเท็จ ไม่ใช้กับ <=> ตัวดำเนินการเหมือนกับ IS NULL

ตัวอย่าง:-

SELECT NULL != NULL,         //--Result is NULL
   NOT NULL <=> NULL,        //--Result is 0
   NULL IS NOT NULL;         //--Result is 0

1
NOT <=>ไม่ได้เป็นผู้ประกอบการก็นำไปใช้กับผลการNOT op1 <=> op2
Ja͢ck

@ แจ็ค: - ใช่คุณถูกต้อง อัปเดตคำตอบ! เสริมว่าเพื่อที่จะทำให้จุด :)
ราหุล Tripathi

ดังนั้นฉันเดาว่าไม่มี<!=>ผู้ให้บริการ
Kip

@kip: ไม่มีไม่มี!
ราหุล Tripathi

18

<=>MySQL ปลอดภัยเป็นโมฆะ "เท่ากับ" ตัวดำเนินการ จากคู่มือ :

ค่า NULL-safe เท่ากับ ตัวดำเนินการนี้ทำการเปรียบเทียบความเท่าเทียมกันเช่นตัวดำเนินการ = แต่คืนค่า 1 แทนที่จะเป็น NULL ถ้าตัวถูกดำเนินการทั้งคู่เป็น NULL และ 0 มากกว่า NULL ถ้าตัวถูกดำเนินการตัวหนึ่งเป็น NULL

mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
        -> 1, 1, 0
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;
        -> 1, NULL, NULL

11

ค่า NULL-safe เท่ากับ ตัวดำเนินการนี้ทำการเปรียบเทียบความเท่าเทียมกันเช่นตัวดำเนินการ = แต่คืนค่า 1 แทนที่จะเป็น NULL ถ้าตัวถูกดำเนินการทั้งคู่เป็น NULL และ 0 มากกว่า NULL ถ้าตัวถูกดำเนินการตัวหนึ่งเป็น NULL

mysql> SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
        -> 1, 1, 0
mysql> SELECT 1 = 1, NULL = NULL, 1 = NULL;
        -> 1, NULL, NULL

มันสำคัญ:

เมื่อคุณเปรียบเทียบค่า NULL กับค่าที่ไม่ใช่ NULL คุณจะได้รับ NULL ถ้าคุณต้องการตรวจสอบว่าค่าเป็นโมฆะ

ตัวดำเนินการความเท่าเทียมกัน (<=>) ซึ่งถือว่า NULL เป็นค่าปกติดังนั้นจะส่งกลับ 1 (ไม่ใช่ NULL) หากค่าทั้งสองเป็น NULL และส่งกลับ 0 (ไม่ใช่ NULL) หากหนึ่งในค่านั้นเป็น NULL:

เช่น

 SELECT NULL <=> NULL -- 1
 SELECT TRUE <=> TRUE -- 1
 SELECT col1 <=> col2 FROM myTable

10

<=>เป็นผู้ประกอบการเท่ากับโมฆะปลอดภัย a <=> bเหมือนกับการเขียน:

CASE
    WHEN a IS NULL AND b IS NULL THEN 1 -- both operands null then 1
    WHEN a IS NULL OR  b IS NULL THEN 0 -- one operand is null then 0
    ELSE a = b                          -- else behave like normal = operator
END

และขออภัยฉันไม่พบเหตุผลที่ดีอย่างหนึ่งในการใช้โอเปอเรเตอร์นี้แทน AND/OR IS (NOT) NULLและขอโทษฉันไม่สามารถหาเหตุผลหนึ่งที่ดีที่จะใช้ประกอบการแทนนี้ตัวอย่างของคุณตัวอย่างเช่นเป็นเช่นเดียวกับWHERE p.name <=> NULLWHERE p.name IS NULL


9

จากเอกสาร MySQL :

ค่า NULL-safe เท่ากับ ตัวดำเนินการนี้ทำการเปรียบเทียบความเท่าเทียมกันเช่นตัวดำเนินการ = แต่คืนค่า 1 แทนที่จะเป็น NULL ถ้าตัวถูกดำเนินการทั้งคู่เป็น NULL และ 0 มากกว่า NULL ถ้าตัวถูกดำเนินการตัวหนึ่งเป็น NULL

ตัวอย่างการใช้<=>โอเปอเรเตอร์จะเป็น:

SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;

ซึ่งจะกลับมา:

1, 1, 0

ตัวอย่างของ=ผู้ประกอบการปกติจะเป็น:

SELECT 1 = 1, NULL = NULL, 1 = NULL;

ซึ่งจะกลับมา:

1, NULL, NULL

<=>ผู้ประกอบการเป็นอย่างมากคล้ายกับ=ผู้ประกอบการยกเว้น<=>จะไม่กลับNULL



1
mysql> SELECT * FROM t JOIN t2 WHERE t2.ids = t.ids;
+----+------+----+------+
| id | ids  | id | ids  |
+----+------+----+------+
|  1 |    1 |  1 |    1 |
|  2 |    2 |  2 |    2 |
|  5 |    6 |  5 |    6 |
|  6 |    7 |  6 |    7 |
+----+------+----+------+
4 rows in set (0.00 sec)

mysql> SELECT * FROM t JOIN t2 WHERE t2.ids <=> t.ids;
+----+------+----+------+
| id | ids  | id | ids  |
+----+------+----+------+
|  1 |    1 |  1 |    1 |
|  2 |    2 |  2 |    2 |
|  3 | NULL |  3 | NULL |
|  4 | NULL |  3 | NULL |
|  3 | NULL |  4 | NULL |
|  4 | NULL |  4 | NULL |
|  5 |    6 |  5 |    6 |
|  6 |    7 |  6 |    7 |
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.