我有一个基于以下架构的数据量很大的表(大小约为1TB):
CREATE TABLE my_table(
col1 character varying,
col2 character varying,
col3 character varying
);
上述表格包含以下格式的数据:
col1 col2 col3
<abc1> <def1> <ghi1>
<abc1> <g1> <g2>
<g3> <g1> <g4>
现在,我想要做的是创建一个字典(另一个表),它映射表my_table
的所有唯一字符串(存在于col1
,col2
和{ {1}})到一个整数值。 e.g:
col3
我知道我可以使用我选择的编程语言(例如Python)来做到这一点。我想知道的是,使用纯SQL是否有可能实现这样的目标?
答案 0 :(得分:2)
老实说,您可以更轻松地在SQL中执行此操作。
例如,这可以解决问题:
SELECT DISTINCT ROW_NUMBER() OVER (ORDER BY col ASC) AS row, col FROM
(SELECT col1 AS col FROM mytable
UNION
SELECT col2 AS col FROM mytable
UNION
SELECT col3 AS col FROM mytable
) AS newtable
ORDER BY row;
请参阅此SQLFiddle。
我不是100%确信使用UNION
是最有效的方式,但我确实知道它符合从跨越检索不同字符串的标准所有三列并为它们分配所有数字。在Python中执行此操作会慢得多。
答案 1 :(得分:1)
好的,我是从SQL Server的角度出发的,但概念基本相同。据我所知,SERIAL
相当于SQL Server中的IDENTITY
,因此它将为您提供自动递增键。我的解决方案可能如下:
CREATE TABLE DistinctStrings ( Id SERIAL NOT NULL, String CHARACTER VARYING NOT NULL )
我假设您想要保留该表,因此它显然是数据库的一部分,并且不会在每次填充时重新创建。
像这样插入此表
INSERT INTO DistinctStrings (String) SELECT col1 FROM my_table UNION SELECT col2 FROM my_table UNION SELECT col3 FROM my_table
使用UNION
(与UNION ALL
相对)将为您提供所需的清晰度。使用SERIAL
会为您提供ID。
答案 2 :(得分:1)
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;
CREATE TABLE bigstrings
( col1 varchar
, col2 varchar
, col3 varchar
);
INSERT INTO bigstrings(col1, col2, col3) VALUES
('abc1','def1','ghi1')
,('abc1','g1','g2')
,('g3','g1','g4')
;
CREATE TABLE allstrings
( num BIGSERIAL NOT NULL PRIMARY KEY
, string varchar NOT NULL UNIQUE
);
CREATE TABLE nostrings
( col1 BIGINT REFERENCES allstrings(num)
, col2 BIGINT REFERENCES allstrings(num)
, col3 BIGINT REFERENCES allstrings(num)
);
INSERT INTO allstrings( string)
SELECT DISTINCT col1 FROM bigstrings bs
-- not needed on empty allstrings table.
-- WHERE NOT EXISTS ( SELECT * FROM allstrings nx WHERE nx.string = bs.col1)
;
INSERT INTO allstrings( string)
SELECT DISTINCT col2 FROM bigstrings bs
WHERE NOT EXISTS ( SELECT * FROM allstrings nx WHERE nx.string = bs.col2)
;
INSERT INTO allstrings( string)
SELECT DISTINCT col3 FROM bigstrings bs
WHERE NOT EXISTS ( SELECT * FROM allstrings nx WHERE nx.string = bs.col3)
;
INSERT INTO nostrings(col1,col2,col3)
SELECT s1.num, s2.num, s3.num
FROM bigstrings bs
JOIN allstrings s1 ON s1.string = bs.col1
JOIN allstrings s2 ON s2.string = bs.col2
JOIN allstrings s3 ON s3.string = bs.col3
;
SELECT * FROM nostrings;
结果:
col1 | col2 | col3
------+------+------
2 | 3 | 6
2 | 4 | 7
1 | 4 | 5
(3 rows)