在PostgreSQL 9.4中将爱好列拆分为N个多列,其中每个列标题显示爱好。Original table
| 姓名|爱好|
| - ------|- ------|
| 雷内|Python,猴子酒吧|
| CJ公司|交易,Python|
| 赫林达|时尚|
| DJ|咨询、销售|
| 玛莎|社交媒体,教学|
| 道格|领导力、管理|
| 马修|财务、员工参与|
| 迈耶斯|睡眠、编码、CrossFit|
| 迈克|YouTube,体育|
| 彼得|吃,睡,Python|
| 托马斯|阅读、交易、销售|
注意:不使用交叉表()Desire table
desire table result image
| 姓名|爱好|巨蟒|单杠|交易|时尚|康叙特林|销售额|社交媒体|教学|领导|管理|财务|员工参与度|睡觉|编码|交叉配合|优兔网|田径|吃吧|睡眠|读取|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 雷内|Python,猴子酒吧|正确|正确|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|
| CJ公司|交易,Python|正确|错误|正确|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|
| 赫林达|时尚|错误|错误|错误|正确|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|
| DJ|咨询、销售|错误|错误|错误|错误|正确|正确|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|
| 玛莎|社交媒体,教学|错误|错误|错误|错误|错误|错误|正确|正确|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|
| 道格|领导力、管理|错误|错误|错误|错误|错误|错误|错误|错误|正确|正确|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|
| 马修|财务、员工参与|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|正确|正确|错误|错误|错误|错误|错误|错误|错误|错误|
| 迈耶斯|睡眠、编码、CrossFit|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|正确|正确|正确|错误|错误|错误|错误|错误|
| 迈克|YouTube,体育|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|正确|正确|错误|错误|错误|
| 彼得|吃,睡,Python|正确|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|正确|正确|错误|
| 托马斯|阅读、交易、销售|错误|错误|正确|错误|错误|正确|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|错误|正确|
- --移除1NF removing the 1NF
CREATE TABLE ws_bi.split_clm(
id integer PRIMARY KEY,
name text,
hobby text
);
INSERT INTO ws_bi.split_clm (id, name, hobby) VALUES
(1, 'Rene', 'Python, Monkey Bars'),
(2, 'CJ', 'Trading, Python'),
(3, 'Herlinda', 'Fashion'),
(4, 'DJ', 'Consulting, Sales'),
(5, 'Martha', 'Social Media, Teaching'),
(6, 'Doug', 'Leadership, Management'),
(7, 'Mathew', 'Finance, Emp Engagement'),
(8, 'Meyers', 'Sleeping, Coding, CrossFit'),
(9, 'Mike', 'YouTube, Athletics'),
(10, 'Peter', 'Eat, Sleep, Python'),
(11, 'Thomas', 'Read, Trading, Sales');
/***query****/
SELECT id, unnest(string_to_array(hobby, ', ')) AS values
FROM ws_bi.split_clm
ORDER BY id;
结果图像result image
- --*更新日期:2023年3月2日。使用此解决方案: * 一个月三次
code creator: L. Rodgers
DB FIDDLE(英国):https://dbfiddle.uk/Sn7iO4zL
对L. Rodgers解决方案做了一些调整,由于某种原因仍然下降...可能是因为Json函数对我来说是非常新的东西。image result tmpMoToJson
---sample data
DROP TABLE IF EXISTS ws_bi.split_clm;
CREATE TABLE ws_bi.split_clm(
id integer PRIMARY KEY,
name text,
hobby text,
value int
);
INSERT INTO ws_bi.split_clm (id, name, hobby,value) VALUES
(1, 'Rene', 'Python, Monkey_Bars','5'),
(2, 'CJ', 'Trading, Python','25'),
(3, 'Herlinda', 'Fashion','15'),
(4, 'DJ', 'Consutling, Sales','35'),
(5, 'Martha', 'Social_Media, Teaching','45'),
(6, 'Doug', 'Leadership, Management','55'),
(7, 'Mathew', 'Finance, Emp_Engagement','65'),
(8, 'Mayers', 'Sleeping, Coding, Crossfit','75'),
(9, 'Mike', 'YouTube, Athletics','85'),
(10, 'Peter', 'Eat, Sleep, Python','95'),
(11, 'Thomas', 'Read, Trading, Sales','105');
/****query****/
--1NF <done>
--DROP TABLE IF EXISTS ws_bi.split_clm_Nor;
CREATE TABLE ws_bi.split_clm_Nor AS (
SELECT id, name, unnest(string_to_array(hobby, ', ')) AS Ivalues , value
FROM ws_bi.split_clm
ORDER BY id
--;
) with data
DISTRIBUTED BY (id) ;
Analyze ws_bi.split_clm_Nor;
--Select * from ws_bi.split_clm_Nor limit 6; ---
---ver 2.0
--DROP TABLE IF EXISTS ws_bi.split_clm_Nor2;
CREATE TABLE ws_bi.split_clm_Nor2 AS (
SELECT id, name, lower(unnest(string_to_array(hobby, ', '))) AS Ivalues , value,count(1) as "Case_Volume"
FROM ws_bi.split_clm
GROUP BY 1,2,3,4
ORDER BY id
--;
) with data
DISTRIBUTED BY (id) ;
Analyze ws_bi.split_clm_Nor2;
--Select * from ws_bi.split_clm_Nor2 limit 6;
---------------------------
DROP TABLE IF EXISTS ws_bi.tmpTblTyp2 CASCADE ;
DO LANGUAGE plpgsql $$
DECLARE v_sqlstring VARCHAR = '';
BEGIN
v_sqlstring := CONCAT( 'CREATE TABLE ws_bi.tmpTblTyp2 AS SELECT '
,(SELECT STRING_AGG( CONCAT('NULL::int AS ' , ivalues )::TEXT , ' ,'
ORDER BY ivalues
)::TEXT
FROM
(SELECT DISTINCT ivalues FROM ws_bi.split_clm_Nor2 )a
)
,' LIMIT 0 '
) ; -- RAISE NOTICE '%', v_sqlstring ;
EXECUTE( v_sqlstring ) ; END $$;
--------------------------------------------
DROP TABLE IF EXISTS ws_bi.tmpMoJson ;
CREATE TABLE ws_bi.tmpMoJson AS (
--CREATE TEMP TABLE tmpMoJson AS
SELECT
name AS name
,(json_build_array( mivalues )) AS js_mivalues_arr
,json_populate_recordset ( NULL::ws_bi.tmpTblTyp2 /** use temp table as a record type!!*/
, json_build_array( mivalues ) /** builds row-type column that can be expanded with (jprs).* */
) jprs /**no error with wrong JSON values result under jprs**/
FROM ( SELECT name
,json_object_agg(ivalues,value) AS mivalues
FROM ws_bi.split_clm_Nor2
GROUP BY 1
ORDER BY 1
) a
--;
) with data
DISTRIBUTED BY (name) ;
Analyze ws_bi.tmpMoJson;
--Select * from ws_bi.tmpMoJson;
SELECT
name
,(ROW((jprs).*)::ws_bi.tmpTblTyp2).* -- explode the composite type row
FROM ws_bi.tmpMoJson ;
DB FIDDLE(英国)之前:https://dbfiddle.uk/BoyKmDrT
DB FIDDLE(英国):https://dbfiddle.uk/gP0kAnZ5
2条答案
按热度按时间j5fpnvbx1#
我并不想使用tablefunc/crosstab。
---图像中最后一次查询的结果
picture result
qyswt5oh2#
要使它工作,只需将列Ivalues(hobby)改为小写
DB FIDDLE(英国):https://dbfiddle.uk/gP0kAnZ5