WITH ORDINALITY
ใน Postgres 9.4 หรือใหม่กว่า
คุณสมบัติใหม่นี้ช่วยลดความซับซ้อนของปัญหานี้ แบบสอบถามด้านบนสามารถเป็น:
SELECT *
FROM regexp_split_to_table('I think Postgres is nifty', ' ') WITH ORDINALITY x(word, rn);
หรือนำไปใช้กับตาราง:
SELECT *
FROM tbl t, regexp_split_to_table(t.my_column, ' ') WITH ORDINALITY x(word, rn);
รายละเอียด:
เกี่ยวกับการLATERAL
เข้าร่วมโดยนัย:
Postgres 9.3 หรือเก่ากว่า - และคำอธิบายทั่วไปเพิ่มเติม
สำหรับสายเดี่ยว
คุณสามารถใช้ฟังก์ชั่นหน้าต่างrow_number()
เพื่อจดจำลำดับขององค์ประกอบ อย่างไรก็ตามโดยปกติrow_number() OVER (ORDER BY col)
คุณจะได้รับตัวเลขตามลำดับการเรียงไม่ใช่ตำแหน่งดั้งเดิมในสตริง
คุณสามารถละเว้นORDER BY
เพื่อรับตำแหน่ง "ตามที่เป็น":
SELECT *, row_number() OVER () AS rn
FROM regexp_split_to_table('I think Postgres is nifty', ' ') AS x(word);
ประสิทธิภาพของการregexp_split_to_table()
ย่อยสลายด้วยสตริงยาว unnest(string_to_array(...))
เครื่องชั่งที่ดีกว่า:
SELECT *, row_number() OVER () AS rn
FROM unnest(string_to_array('I think Postgres is nifty', ' ')) AS x(word);
อย่างไรก็ตามในขณะนี้ใช้งานได้ตามปกติและฉันไม่เคยเห็นมันทำลายในการสืบค้นง่าย Postgres ORDER BY
อ้างอะไรที่เป็นคำสั่งของแถวโดยไม่ต้องชัดเจน
ในการรับประกันหมายเลขลำดับขององค์ประกอบในสตริงเดิมให้ใช้generate_subscript()
(ปรับปรุงด้วยความคิดเห็นโดย @deszo):
SELECT arr[rn] AS word, rn
FROM (
SELECT *, generate_subscripts(arr, 1) AS rn
FROM string_to_array('I think Postgres is nifty', ' ') AS x(arr)
) y;
สำหรับตารางของสตริง
เพิ่มPARTITION BY id
ไปยังOVER
ข้อ ...
ตารางสาธิต:
CREATE TEMP TABLE strings(string text);
INSERT INTO strings VALUES
('I think Postgres is nifty')
,('And it keeps getting better');
ผมใช้ctid
เป็นตัวแทนเฉพาะกิจสำหรับคีย์หลัก หากคุณมีหนึ่ง (หรือคอลัมน์ที่ไม่ซ้ำกัน ) ให้ใช้สิ่งนั้นแทน
SELECT *, row_number() OVER (PARTITION BY ctid) AS rn
FROM (
SELECT ctid, unnest(string_to_array(string, ' ')) AS word
FROM strings
) x;
สิ่งนี้ทำงานโดยไม่มี ID ที่แตกต่างกัน:
SELECT arr[rn] AS word, rn
FROM (
SELECT *, generate_subscripts(arr, 1) AS rn
FROM (
SELECT string_to_array(string, ' ') AS arr
FROM strings
) x
) y;
ซอ Fiddle
ตอบคำถาม
SELECT z.arr, z.rn, z.word, d.meaning -- , partofspeech -- ?
FROM (
SELECT *, arr[rn] AS word
FROM (
SELECT *, generate_subscripts(arr, 1) AS rn
FROM (
SELECT string_to_array(string, ' ') AS arr
FROM strings
) x
) y
) z
JOIN dictionary d ON d.wordname = z.word
ORDER BY z.arr, z.rn;