ความแตกต่างระหว่าง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
ไม่ได้ผลกับรายการ