ในการสร้างชุดวันที่นี่เป็นวิธีที่ดีที่สุด :
SELECT t.day::date
FROM generate_series(timestamp '2004-03-07'
, timestamp '2004-08-16'
, interval '1 day') AS t(day);
เพิ่มเติมdate_trunc()ไม่จำเป็น การส่งไปยังdate( day::date) ทำเช่นนั้นโดยปริยาย
แต่ก็ไม่มีประเด็นในการแคสต์ตัวอักษรวันที่dateเป็นพารามิเตอร์อินพุต Au contraire, เป็นตัวเลือกที่ดีที่สุดtimestamp ข้อได้เปรียบในด้านประสิทธิภาพคือเล็กน้อย แต่ไม่มีเหตุผลที่จะไม่ใช้มัน และคุณไม่จำเป็นต้องเกี่ยวข้องกับกฎ DST (เวลาออมแสง) ควบคู่ไปกับการแปลงจากdateเป็นtimestamp with time zoneและกลับ ดูด้านล่าง
ไวยากรณ์สั้นที่เทียบเท่าและชัดเจนน้อยกว่า:
SELECT day::date
FROM generate_series(timestamp '2004-03-07', '2004-08-16', '1 day') day;
หรือด้วยฟังก์ชัน set-return ในSELECTรายการ:
SELECT generate_series(timestamp '2004-03-07', '2004-08-16', '1 day')::date AS day;
ASคำหลักที่จำเป็นในตัวแปรที่ผ่านมา Postgres จะตีความผิดนามแฝงคอลัมน์dayมิฉะนั้น และฉันจะไม่แนะนำตัวแปรนั้นก่อน Postgres 10 - อย่างน้อยก็ไม่ต้องมีฟังก์ชันคืนค่ามากกว่าหนึ่งSELECTรายการในรายการเดียวกัน:
(นอกจากนี้ตัวแปรสุดท้ายมักจะเร็วที่สุดโดยมีระยะขอบเล็กน้อย)
ทำไมtimestamp [without time zone]?
มีรูปแบบที่โอเวอร์โหลดจำนวนมากของgenerate_series(). ปัจจุบัน (Postgres 11):
SELECT oid::regprocedure AS function_signature
, prorettype::regtype AS return_type
FROM pg_proc
where proname = 'generate_series';
function_signature | return_type
: ------------------------------------------------- ------------------------------- | : --------------------------
create_series (จำนวนเต็ม, จำนวนเต็ม, จำนวนเต็ม) | จำนวนเต็ม
create_series (จำนวนเต็มจำนวนเต็ม) | จำนวนเต็ม
create_series (bigint, bigint, bigint) | bigint
create_series (bigint, bigint) | bigint
create_series (ตัวเลขตัวเลขตัวเลข) | ตัวเลข
create_series (ตัวเลข, ตัวเลข) | ตัวเลข
create_series (การประทับเวลาโดยไม่มีเขตเวลาการประทับเวลาโดยไม่มีเขตเวลาช่วงเวลา) | การประทับเวลาโดยไม่มีเขตเวลา
create_series (การประทับเวลาด้วยเขตเวลาการประทับเวลาด้วยเขตเวลาช่วงเวลา) | การประทับเวลาด้วยเขตเวลา
( numericสายพันธุ์ที่ถูกเพิ่มเข้ามาด้วย Postgres 9.5.) คนที่เกี่ยวข้องเป็นสองคนสุดท้ายที่เป็นตัวหนาจดและกลับ/timestamptimestamptz
มีตัวแปรที่ไม่มีการหรือกลับ datedateหล่ออย่างชัดเจนเป็นสิ่งจำเป็นที่จะกลับมา การเรียกที่มีtimestampอาร์กิวเมนต์จะเปลี่ยนเป็นตัวแปรที่ดีที่สุดโดยตรงโดยไม่ต้องลดระดับลงในกฎการแก้ปัญหาประเภทฟังก์ชันและไม่มีการแคสต์เพิ่มเติมสำหรับอินพุต
timestamp '2004-03-07'ถูกต้องอย่างสมบูรณ์ btw. ส่วนเวลาที่ละไว้จะ00:00มีค่าเริ่มต้นเป็นรูปแบบ ISO
ด้วยความละเอียดประเภทฟังก์ชันที่เรายังส่งผ่านdateได้ แต่ต้องทำงานเพิ่มเติมจาก Postgres มีการโยนโดยปริยายจากdateถึงtimestampหนึ่งจากdateถึงtimestamptzหนึ่ง จะไม่ชัดเจน แต่timestamptzเป็น"ต้องการ"ในหมู่ "ประเภทวันที่ / เวลา" ดังนั้นการแข่งขันจะถูกตัดสินที่ขั้นตอนที่4d :
ดำเนินการตามผู้สมัครทั้งหมดและเก็บผู้ที่ยอมรับประเภทที่ต้องการ (ของประเภทประเภทข้อมูลอินพุต) ไว้ที่ตำแหน่งส่วนใหญ่ที่จะต้องมีการแปลงประเภท เก็บผู้สมัครทั้งหมดไว้หากไม่มีใครยอมรับประเภทที่ต้องการ หากมีผู้สมัครเพียงคนเดียวให้ใช้ อื่น ๆ ให้เข้าสู่ขั้นตอนต่อไป
นอกเหนือจากงานพิเศษในความละเอียดประเภทฟังก์ชันแล้วยังเพิ่มการแคสต์พิเศษtimestamptzซึ่งไม่เพียง แต่จะเพิ่มต้นทุนมากขึ้นเท่านั้น แต่ยังสามารถทำให้เกิดปัญหากับ DST ซึ่งนำไปสู่ผลลัพธ์ที่ไม่คาดคิดในบางกรณี (DST เป็นแนวคิดที่ปัญญาอ่อนไม่สามารถเน้นสิ่งนี้ได้เพียงพอ)
ฉันเพิ่มการสาธิตให้กับซอที่แสดงแผนการสืบค้นที่แพงกว่า:
db <> ซอที่นี่
ที่เกี่ยวข้อง: