ในการสร้างชุดวันที่นี่เป็นวิธีที่ดีที่สุด :
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.) คนที่เกี่ยวข้องเป็นสองคนสุดท้ายที่เป็นตัวหนาจดและกลับ/timestamp
timestamptz
มีตัวแปรที่ไม่มีการหรือกลับ date
date
หล่ออย่างชัดเจนเป็นสิ่งจำเป็นที่จะกลับมา การเรียกที่มีtimestamp
อาร์กิวเมนต์จะเปลี่ยนเป็นตัวแปรที่ดีที่สุดโดยตรงโดยไม่ต้องลดระดับลงในกฎการแก้ปัญหาประเภทฟังก์ชันและไม่มีการแคสต์เพิ่มเติมสำหรับอินพุต
timestamp '2004-03-07'
ถูกต้องอย่างสมบูรณ์ btw. ส่วนเวลาที่ละไว้จะ00:00
มีค่าเริ่มต้นเป็นรูปแบบ ISO
ด้วยความละเอียดประเภทฟังก์ชันที่เรายังส่งผ่านdate
ได้ แต่ต้องทำงานเพิ่มเติมจาก Postgres มีการโยนโดยปริยายจากdate
ถึงtimestamp
หนึ่งจากdate
ถึงtimestamptz
หนึ่ง จะไม่ชัดเจน แต่timestamptz
เป็น"ต้องการ"ในหมู่ "ประเภทวันที่ / เวลา" ดังนั้นการแข่งขันจะถูกตัดสินที่ขั้นตอนที่4d :
ดำเนินการตามผู้สมัครทั้งหมดและเก็บผู้ที่ยอมรับประเภทที่ต้องการ (ของประเภทประเภทข้อมูลอินพุต) ไว้ที่ตำแหน่งส่วนใหญ่ที่จะต้องมีการแปลงประเภท เก็บผู้สมัครทั้งหมดไว้หากไม่มีใครยอมรับประเภทที่ต้องการ หากมีผู้สมัครเพียงคนเดียวให้ใช้ อื่น ๆ ให้เข้าสู่ขั้นตอนต่อไป
นอกเหนือจากงานพิเศษในความละเอียดประเภทฟังก์ชันแล้วยังเพิ่มการแคสต์พิเศษtimestamptz
ซึ่งไม่เพียง แต่จะเพิ่มต้นทุนมากขึ้นเท่านั้น แต่ยังสามารถทำให้เกิดปัญหากับ DST ซึ่งนำไปสู่ผลลัพธ์ที่ไม่คาดคิดในบางกรณี (DST เป็นแนวคิดที่ปัญญาอ่อนไม่สามารถเน้นสิ่งนี้ได้เพียงพอ)
ฉันเพิ่มการสาธิตให้กับซอที่แสดงแผนการสืบค้นที่แพงกว่า:
db <> ซอที่นี่
ที่เกี่ยวข้อง: