MathJax

MathJax-2

MathJax-3

Google Code Prettify

置頂入手筆記

EnterproseDB Quickstart — 快速入門筆記

由於考慮採用 EnterpriseDB 或是直接用 PostgreSQL 的人,通常需要一些入手的資料。這邊紀錄便提供相關快速上手的簡單筆記 ~ 這篇筆記以 資料庫安裝完畢後的快速使用 為目標,基本紀錄登入使用的範例:

2023年2月16日 星期四

在 PGSQL 裡面指定優先排序的清單

 這陣子遇到希望挑出特定內容往前排序的狀況。為了處理這個,想了一下子怎樣都要拆分資料做處理在合併,但寫好多行 script 處理還是有點痛苦。。。

不過~找了一陣子,總算讓我看到一個排序的奇妙範例。

這個功能,就是 ORDER BY 語法,其實也可以吃運算式~

以下範例,就是把系統表 pg_tables 的紀錄(Note:這其實是張 view),特地把兩個 schema 往前挪,優先排序

edb=# SELECT schemaname, tablename FROM pg_tables
ORDER BY (schemaname IN ('pg_catalog', 'sys')) DESC, tablename;
     schemaname     |              tablename
--------------------+-------------------------------------
 sys                | callback_queue_table
 sys                | dual
 sys                | edb$session_wait_history
 sys                | edb$session_waits
 sys                | edb$snap
 sys                | edb$stat_all_indexes
 sys                | edb$stat_all_tables
 sys                | edb$stat_database
 sys                | edb$statio_all_indexes
 sys                | edb$statio_all_tables
 sys                | edb$system_waits
 sys                | edb_dbms_redact_full_default_values
 pg_catalog         | edb_dir
 pg_catalog         | edb_last_ddl_time
 pg_catalog         | edb_last_ddl_time_shared
 pg_catalog         | edb_password_history
 pg_catalog         | edb_policy
 pg_catalog         | edb_profile
 pg_catalog         | edb_queue
 pg_catalog         | edb_queue_callback
 pg_catalog         | edb_queue_table
 pg_catalog         | edb_redaction_column
 pg_catalog         | edb_redaction_policy
 pg_catalog         | edb_resource_group
 pg_catalog         | edb_variable
 pg_catalog         | pg_aggregate
 pg_catalog         | pg_am
edb=#

但這招不能直接用在 UNION 上。。。會出錯。。
以下範例延伸上面範例,但湊了一個 UNION
edb=# SELECT schemaname, tablename FROM pg_tables
WHERE schemaname = 'pg_catalog'
UNION
SELECT schemaname, tablename FROM pg_tables
WHERE schemaname = 'sys'
ORDER BY (schemaname IN ('pg_catalog', 'sys')) DESC, tablename;
ERROR:  invalid UNION/INTERSECT/EXCEPT ORDER BY clause
LINE 6: ORDER BY (schemaname IN ('pg_catalog', 'sys')) DESC, tablena...
                  ^
DETAIL:  Only result column names can be used, not expressions or functions.
HINT:  Add the expression/function to every SELECT, or move the UNION into a FROM clause.
edb=#

這錯誤訊息,告知我們得把 UNION 框起來,不能讓 ORDER BY 的 IN list 看到(可以用 sub-query、CTE、或是塞到 FROM 裡)。這邊用 CTE 騙過去
edb=# WITH xx AS NOT MATERIALIZED(
SELECT schemaname, tablename FROM pg_tables
WHERE schemaname = 'pg_catalog'
UNION
SELECT schemaname, tablename FROM pg_tables
WHERE schemaname = 'sys'
)
SELECT * FROM xx
ORDER BY (schemaname IN ('pg_catalog', 'sys')) DESC, tablename;
 schemaname |              tablename
------------+-------------------------------------
 sys        | callback_queue_table
 sys        | dual
 sys        | edb$session_wait_history
 sys        | edb$session_waits
 sys        | edb$snap
 sys        | edb$stat_all_indexes
 sys        | edb$stat_all_tables
 sys        | edb$stat_database
 sys        | edb$statio_all_indexes
 sys        | edb$statio_all_tables
 sys        | edb$system_waits
 sys        | edb_dbms_redact_full_default_values
 pg_catalog | edb_dir
 pg_catalog | edb_last_ddl_time
 pg_catalog | edb_last_ddl_time_shared
 pg_catalog | edb_password_history
 pg_catalog | edb_policy
 pg_catalog | edb_profile
 pg_catalog | edb_queue
 pg_catalog | edb_queue_callback
 pg_catalog | edb_queue_table
 pg_catalog | edb_redaction_column
 pg_catalog | edb_redaction_policy
 pg_catalog | edb_resource_group
 pg_catalog | edb_variable
 pg_catalog | pg_aggregate
 pg_catalog | pg_am
 pg_catalog | pg_amop
edb=#

以上手法,就能省略好多行 script/程式了~


另外在紀錄一種,稍稍的不同用途:這次只要特定內容,但保持提供的 list 順序。
有時候會把 list 弄進 array 在利用 UNNEST() 轉成多筆資料(上一篇筆記有)。
不過這邊的點,是 Set-Returning function 額外支援的 WITH ORDINALITY ... USING 修飾字。其中 WITH ORDINALITY 所出來長的兩欄位分別是 JOIN 左右兩邊
edb=# SELECT t.schemaname, t.tablename FROM pg_tables t
JOIN unnest('{pg_catalog, sys}'::text[]) WITH ORDINALITY x(schemaname, ord) USING (schemaname)
ORDER BY x.ord, t.tablename;
 schemaname |              tablename
------------+-------------------------------------
 pg_catalog | edb_dir
 pg_catalog | edb_last_ddl_time
 pg_catalog | edb_last_ddl_time_shared
 pg_catalog | edb_password_history
 pg_catalog | edb_policy
 pg_catalog | edb_profile
 pg_catalog | edb_queue
 pg_catalog | edb_queue_callback
 pg_catalog | edb_queue_table
 pg_catalog | edb_redaction_column
 pg_catalog | edb_redaction_policy
 pg_catalog | edb_resource_group
 pg_catalog | edb_variable
 pg_catalog | pg_aggregate
 pg_catalog | pg_am
 pg_catalog | pg_amop
 pg_catalog | pg_amproc
 pg_catalog | pg_attrdef
 pg_catalog | pg_attribute
 pg_catalog | pg_auth_members
 pg_catalog | pg_authid
 pg_catalog | pg_cast
 pg_catalog | pg_class
 pg_catalog | pg_collation
 pg_catalog | pg_constraint
 pg_catalog | pg_conversion
 pg_catalog | pg_database
 pg_catalog | pg_db_role_setting
 pg_catalog | pg_default_acl
 pg_catalog | pg_depend
 pg_catalog | pg_description
 pg_catalog | pg_enum
 pg_catalog | pg_event_trigger
 pg_catalog | pg_extension
 pg_catalog | pg_foreign_data_wrapper
 pg_catalog | pg_foreign_server
 pg_catalog | pg_foreign_table
 pg_catalog | pg_index
 pg_catalog | pg_inherits
 pg_catalog | pg_init_privs
 pg_catalog | pg_language
 pg_catalog | pg_largeobject
 pg_catalog | pg_largeobject_metadata
 pg_catalog | pg_namespace
 pg_catalog | pg_opclass
 pg_catalog | pg_operator
 pg_catalog | pg_opfamily
 pg_catalog | pg_partitioned_table
 pg_catalog | pg_policy
 pg_catalog | pg_proc
 pg_catalog | pg_publication
 pg_catalog | pg_publication_rel
 pg_catalog | pg_range
 pg_catalog | pg_replication_origin
 pg_catalog | pg_rewrite
 pg_catalog | pg_seclabel
 pg_catalog | pg_sequence
 pg_catalog | pg_shdepend
 pg_catalog | pg_shdescription
 pg_catalog | pg_shseclabel
 pg_catalog | pg_statistic
 pg_catalog | pg_statistic_ext
 pg_catalog | pg_statistic_ext_data
 pg_catalog | pg_subscription
 pg_catalog | pg_subscription_rel
 pg_catalog | pg_synonym
 pg_catalog | pg_tablespace
 pg_catalog | pg_transform
 pg_catalog | pg_trigger
 pg_catalog | pg_ts_config
 pg_catalog | pg_ts_config_map
 pg_catalog | pg_ts_dict
 pg_catalog | pg_ts_parser
 pg_catalog | pg_ts_template
 pg_catalog | pg_type
 pg_catalog | pg_user_mapping
 sys        | callback_queue_table
 sys        | dual
 sys        | edb$session_wait_history
 sys        | edb$session_waits
 sys        | edb$snap
 sys        | edb$stat_all_indexes
 sys        | edb$stat_all_tables
 sys        | edb$stat_database
 sys        | edb$statio_all_indexes
 sys        | edb$statio_all_tables
 sys        | edb$system_waits
 sys        | edb_dbms_redact_full_default_values
 sys        | plsql_profiler_rawdata
 sys        | plsql_profiler_runs
 sys        | plsql_profiler_units
 sys        | product_component_version
edb=#

不過其實這招,把 INNER JOIN 改 LEFT JOIN 就有這篇筆記原本要的效果了~
edb=# SELECT t.schemaname, t.tablename FROM pg_tables t
LEFT JOIN unnest('{pg_catalog, sys}'::text[]) WITH ORDINALITY x(schemaname, ord) USING (schemaname)
ORDER BY x.ord, t.tablename;
 schemaname |              tablename
------------+-------------------------------------
 pg_catalog | edb_dir
 pg_catalog | edb_last_ddl_time
 pg_catalog | edb_last_ddl_time_shared
 pg_catalog | edb_password_history
 pg_catalog | edb_policy
 pg_catalog | edb_profile
 pg_catalog | edb_queue
 pg_catalog | edb_queue_callback
 pg_catalog | edb_queue_table
 pg_catalog | edb_redaction_column
 pg_catalog | edb_redaction_policy
 pg_catalog | edb_resource_group
 pg_catalog | edb_variable
 pg_catalog | pg_aggregate
 pg_catalog | pg_am
 pg_catalog | pg_amop
 pg_catalog | pg_amproc
 pg_catalog | pg_attrdef
 pg_catalog | pg_attribute
 pg_catalog | pg_auth_members
 pg_catalog | pg_authid
 pg_catalog | pg_cast
 pg_catalog | pg_class
 pg_catalog | pg_collation
 pg_catalog | pg_constraint
 pg_catalog | pg_conversion
 pg_catalog | pg_database
 pg_catalog | pg_db_role_setting
 pg_catalog | pg_default_acl
 pg_catalog | pg_depend
 pg_catalog | pg_description
 pg_catalog | pg_enum
 pg_catalog | pg_event_trigger
 pg_catalog | pg_extension
 pg_catalog | pg_foreign_data_wrapper
 pg_catalog | pg_foreign_server
 pg_catalog | pg_foreign_table
 pg_catalog | pg_index
 pg_catalog | pg_inherits
 pg_catalog | pg_init_privs
 pg_catalog | pg_language
 pg_catalog | pg_largeobject
 pg_catalog | pg_largeobject_metadata
 pg_catalog | pg_namespace
 pg_catalog | pg_opclass
 pg_catalog | pg_operator
 pg_catalog | pg_opfamily
 pg_catalog | pg_partitioned_table
 pg_catalog | pg_policy
 pg_catalog | pg_proc
 pg_catalog | pg_publication
 pg_catalog | pg_publication_rel
 pg_catalog | pg_range
 pg_catalog | pg_replication_origin
 pg_catalog | pg_rewrite
 pg_catalog | pg_seclabel
 pg_catalog | pg_sequence
 pg_catalog | pg_shdepend
 pg_catalog | pg_shdescription
 pg_catalog | pg_shseclabel
 pg_catalog | pg_statistic
 pg_catalog | pg_statistic_ext
 pg_catalog | pg_statistic_ext_data
 pg_catalog | pg_subscription
 pg_catalog | pg_subscription_rel
 pg_catalog | pg_synonym
 pg_catalog | pg_tablespace
 pg_catalog | pg_transform
 pg_catalog | pg_trigger
 pg_catalog | pg_ts_config
 pg_catalog | pg_ts_config_map
 pg_catalog | pg_ts_dict
 pg_catalog | pg_ts_parser
 pg_catalog | pg_ts_template
 pg_catalog | pg_type
 pg_catalog | pg_user_mapping
 sys        | callback_queue_table
 sys        | dual
 sys        | edb$session_wait_history
 sys        | edb$session_waits
 sys        | edb$snap
 sys        | edb$stat_all_indexes
 sys        | edb$stat_all_tables
 sys        | edb$stat_database
 sys        | edb$statio_all_indexes
 sys        | edb$statio_all_tables
 sys        | edb$system_waits
 sys        | edb_dbms_redact_full_default_values
 sys        | plsql_profiler_rawdata
 sys        | plsql_profiler_runs
 sys        | plsql_profiler_units
 sys        | product_component_version
(92 rows)

edb=#


上面這兩種,直接在 psql 底下看起來比較沒什麼,不過當 list 是從 script/程式碼處理得到的清單,這時候套用就會感覺到效果了~

參考資料
How to prioritize rows with specific condition when on Postgres? - Stack Overflow
How to have a custom sort order for a union query in Postgres - Stack Overflow
sql - ORDER BY the IN value list - Stack Overflow

沒有留言:

張貼留言