我有一張看起來像這樣的桌子
CREATE TABLE foo (id, name, category)
AS VALUES
( 1, 'name1.1', 'cat1.1.1'),
( 1, 'name1.2', 'cat1.1.1'),
( 1, 'name1.3', 'cat1.2.1'),
( 2, 'name2.1', 'cat2.1.1'),
( 2, 'name2.2', 'cat2.1.1'),
( 3, 'name3.1', 'cat3.1.1')
;
我試圖得到一個看起來像這樣的結果,
| ID | 名稱1 | 名稱2 | 名稱3 |
|---|---|---|---|
| 1 | 名稱1.1 | 名稱1.2 | 名稱1.3 |
| 2 | 名稱2.1 | 名稱2.2 | |
| 3 | 名稱3.1 |
uj5u.com熱心網友回復:
首先,您需要添加提供此功能的tablefunc模塊。
CREATE EXTENSION tablefunc;
現在你需要這樣的查詢,
SELECT *
FROM crosstab(
-- here we normalize this into `id | cat | value`
-- where the category is [1-3]
$$SELECT id, RIGHT(name,1)::int AS cat, name AS value FROM foo ORDER BY 1,2;$$,
-- For just the cat 1,2,3
$$VALUES (1),(2),(3);$$
) AS ct(id text, name1 text, name2 text, name3 text);
這將回傳這個,
id | name1 | name2 | name3
---- --------- --------- ---------
1 | name1.1 | name1.2 | name1.3
2 | name2.1 | name2.2 |
3 | name3.1 | |
(3 rows)
請注意這里的大問題,您的類別實際上是您的資料的函式RIGHT(name,1)::int。那可能是你的堅持。相反,您提供的實際資料category似乎可以完全忽略,除非我遺漏了什么。
另請注意,我在兩個地方對類別名稱進行了硬編碼,
$$VALUES (1),(2),(3);$$
和,
ct(id text, name1 text, name2 text, name3 text);
這是必需的,因為 PostgreSQL 不允許您在運行命令時回傳結果集未知的查詢。這將僅支持[name1 - name3]如果您希望它真正動態,則程式的范圍會擴大很多,并且在這個問題上是題外話。
uj5u.com熱心網友回復:
我會將所有名稱聚合到一個陣列中,然后將陣列元素提取為列:
select id,
names[1] as name1,
names[2] as name2,
names[3] as name3
from (
select id,
array_agg(name order by name) as names
from foo
group by id
) t
如果名稱可能包含類似的內容,name10.11那么列的順序將不是數字,因為 string'10'低于 string '2'。如果您希望訂單反映數字,排序會變得更加復雜:
array_agg(name order by string_to_array(replace(name, 'name', ''), '.')::int[]) as names
這將洗掉name前綴并將數字轉換為整數陣列,然后正確排序。另一種選擇是洗掉不是數字或點的所有內容:
array_agg(name order by string_to_array(regexp_replace(name, '[^0-9.]', '', 'g'), '.')::int[]) as names
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/408983.html
標籤:
下一篇:Go:無法解組json值
