ความแตกต่างระหว่างINและANYตัวดำเนินการใน PostgreSQL คืออะไร?
กลไกการทำงานของทั้งสองดูเหมือนจะเหมือนกัน ใครช่วยอธิบายเรื่องนี้ด้วยตัวอย่างได้ไหม
ความแตกต่างระหว่างINและANYตัวดำเนินการใน PostgreSQL คืออะไร?
กลไกการทำงานของทั้งสองดูเหมือนจะเหมือนกัน ใครช่วยอธิบายเรื่องนี้ด้วยตัวอย่างได้ไหม
คำตอบ:
(ทั้งINมิได้ANYเป็น "ผู้ประกอบการ". A "สร้าง" หรือ "องค์ประกอบไวยากรณ์".)
เหตุผลโดยอ้างถึงคู่มือ :
INเทียบเท่ากับ= ANY.
แต่มีสองสายพันธุ์ไวยากรณ์ของสองสายพันธุ์IN ANYรายละเอียด:
IN การเซ็ตจะเทียบเท่ากับ= ANYการเซ็ตตามที่แสดงไว้ที่นี่:
แต่ตัวแปรที่สองของแต่ละตัวไม่เทียบเท่ากับตัวแปรอื่น ตัวแปรที่สองของการANYสร้างใช้เวลาอาร์เรย์ (ต้องเป็นชนิดอาร์เรย์ที่เกิดขึ้นจริง) ในขณะที่ตัวแปรที่สองของการINใช้คั่นด้วยเครื่องหมายจุลภาครายการค่า สิ่งนี้นำไปสู่ข้อ จำกัด ที่แตกต่างกันในการส่งผ่านค่าและยังสามารถนำไปสู่แผนการสืบค้นที่แตกต่างกันในกรณีพิเศษ:
ANY มีความหลากหลายมากขึ้นANYสร้างอยู่ไกลมากขึ้นหลากหลายขณะที่มันสามารถใช้ร่วมกับผู้ประกอบการต่าง ๆ =ไม่ได้เป็นเพียง ตัวอย่าง:
SELECT 'foo' LIKE ANY('{FOO,bar,%oo%}');
สำหรับค่าจำนวนมากให้จัดชุดสเกลที่ดีกว่าสำหรับแต่ละค่า:
ที่เกี่ยวข้อง:
"ค้นหาแถวที่idอยู่ในอาร์เรย์ที่กำหนด":
SELECT * FROM tbl WHERE id = ANY (ARRAY[1, 2]);
ผกผัน: "หาแถวที่idเป็นไม่ได้ในอาร์เรย์":
SELECT * FROM tbl WHERE id <> ALL (ARRAY[1, 2]);
SELECT * FROM tbl WHERE id <> ALL ('{1, 2}'); -- equivalent array literal
SELECT * FROM tbl WHERE NOT (id = ANY ('{1, 2}'));
เทียบเท่าทั้งสาม ครั้งแรกกับคอนสตรัคอาร์เรย์อีกสองกับอาร์เรย์ที่แท้จริง ชนิดข้อมูลได้มาจากบริบทอย่างไม่น่าสงสัย '{1,2}'::int[]อื่นหล่ออย่างชัดเจนอาจจะต้องชอบ
แถวที่มีid IS NULLไม่ผ่านนิพจน์เหล่านี้ หากต้องการรวมNULLค่าเพิ่มเติม:
SELECT * FROM tbl WHERE (id = ANY ('{1, 2}')) IS NOT TRUE;
SELECT * from mytable where id in (1, 2, 3)จะส่งผลให้แถวเดียวกันเสมอSELECT * from mytable where id = ANY('{1, 2, 3}')แม้ว่าอาจมีแผนการสืบค้นที่แตกต่างกันก็ตาม
ANY ไม่สามารถใช้ร่วมกับตัว!=ดำเนินการได้ ผมไม่คิดว่ามันเป็นเอกสาร แต่ไม่ได้เช่นเดียวกับselect * from foo where id != ANY (ARRAY[1, 2]) select * from foo where id NOT IN (1, 2)ในทางกลับกันselect * from foo where NOT (id = ANY (ARRAY[1, 2]))ทำงานตามที่คาดไว้
ANYสามารถใช้ร่วมกับตัว!=ดำเนินการได้ แต่มีมากกว่านั้น ฉันเพิ่มบทด้านบน (โปรดทราบว่า<>เป็นตัวดำเนินการใน SQL มาตรฐาน - แม้ว่า!=จะได้รับการยอมรับเช่นกันใน Postgres)
NULLค่าต่างๆทำงานอย่างไร จะWHERE id = ANY (ARRAY[1, 2]) OR id IS NULL;ทำงานได้ดีหรือไม่?
(id = ...) IS NOT TRUEงานได้เพราะid = ...จะประเมินTRUEว่ามีการแข่งขันจริงหรือไม่ ผลลัพธ์FALSEหรือNULLผ่านการทดสอบของเรา ดู: stackoverflow.com/a/23767625/939860 นิพจน์ที่คุณเพิ่มจะทดสอบอย่างอื่น สิ่งนี้จะเทียบเท่าWHERE id <> ALL (ARRAY[1, 2]) OR id IS NULL;
มีสองประเด็นที่ชัดเจนเช่นเดียวกับประเด็นในคำตอบอื่น ๆ :
เทียบเท่ากันทุกประการเมื่อใช้แบบสอบถามย่อย:
SELECT * FROM table
WHERE column IN(subquery);
SELECT * FROM table
WHERE column = ANY(subquery);ในทางกลับกัน:
เฉพาะINโอเปอเรเตอร์เท่านั้นที่อนุญาตรายการง่ายๆ:
SELECT * FROM table
WHERE column IN(… , … , …);การสันนิษฐานว่าพวกเขาเหมือนกันทำให้ฉันหลงลืมหลายครั้งเมื่อลืมสิ่งนั้นANYไม่ได้ผลกับรายการ