Python SQL语句创建基于无组织表的字典
我有一个数据量很大的表,大小约为1TB,基于以下模式:Python SQL语句创建基于无组织表的字典,python,sql,postgresql,dictionary,Python,Sql,Postgresql,Dictionary,我有一个数据量很大的表,大小约为1TB,基于以下模式: CREATE TABLE my_table( col1 character varying, col2 character varying, col3 character varying ); 上述表格包含以下形式的数据: col1 col2 col3 <abc1> <def1> <ghi1> <abc1> <g1> <g2&
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>
例如,我知道我可以使用我选择的编程语言Python来实现这一点。我想知道的是,是否有可能使用纯SQL实现类似的功能?老实说,使用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;
请看下面的例子
我不是100%相信使用联合是最有效的方法,但我知道它符合您的标准,即从所有三列中检索不同的字符串并为它们分配所有数字。在Python中这样做要慢得多。老实说,在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;
请看下面的例子
我不是100%相信使用联合是最有效的方法,但我知道它符合您的标准,即从所有三列中检索不同的字符串并为它们分配所有数字。在Python中这样做要慢得多。好的,我是从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
使用“联合”而不是“联合”都会给你带来你想要的独特性。串口的使用将为您提供ID。好的,我是从SQL Server的角度来看这一点的,但概念基本相同。据我所知,SERIAL相当于SQL Server中的IDENTITY,因此它将为您提供一个自动递增的密钥。我的解决方案可能如下: CREATE TABLE DistinctStrings ( Id SERIAL NOT NULL, String CHARACTER VARYING NOT NULL )
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;
我假设您希望保留该表,因此它显然是数据库的一部分,而不是每次填充时都重新创建
像这样插入到这个表中
INSERT INTO DistinctStrings (String)
SELECT col1 FROM my_table UNION
SELECT col2 FROM my_table UNION
SELECT col3 FROM my_table
使用“联合”而不是“联合”都会给你带来你想要的独特性。序列号的使用会给你你的身份证
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)
结果:
col1 | col2 | col3
------+------+------
2 | 3 | 6
2 | 4 | 7
1 | 4 | 5
(3 rows)
所需输出中的第二列是否意味着与字符串来自的列相对应?这样,如果我们要扩展您的示例col1 col2 col3 row1:row2:将输出1 | 2 | 3 | 1 | 2 | 3?@misterManager No.。实际上,我想分配表整数ID中的所有字符串。它们在表中的存储顺序对用户来说无关紧要me@misterManager我编辑了我的问题来解释。谢谢你的回复。没问题。希望我的答案就是你想要的!所需输出中的第二列是否意味着与字符串来自的列相对应?这样,如果我们要扩展您的示例col1 col2 col3 row1:row2:将输出1 | 2 | 3 | 1 | 2 | 3?@misterManager No.。实际上,我想分配表整数ID中的所有字符串。它们在表中的存储顺序对用户来说无关紧要me@misterManager我编辑了我的问题来解释。谢谢你的回复。没问题。希望我的答案就是你想要的!您可以在不使用行号和distinct的情况下完成相同的任务。您的UNION为您处理distinct,您要插入的表上的一个自动递增键将处理ID。。。行号不能重复用于插入到表中,因为它总是从1开始,这将要求您在每次加载表时转储它。在这里,所有的排序和内容都超过1TB的数据,我想它的性能不如剥离一点。同意自动递增键,但是我故意把它忘在这里,这样我们只需要一个SELECT语句,而不需要CREATETABLE语句或类似的语句。您可以在没有行号和distinct的情况下完成同样的事情。您的UNION为您处理distinct,您要插入的表上的一个自动递增键将处理ID。。。行号不能重复用于插入到表中,因为它总是从1开始,这将要求您在每次加载表时转储它。在这里,所有的排序和内容都超过1TB的数据,我想它的性能不如剥离一点。同意使用自动递增键,但我故意不使用它,因此我们只需要一个SELECT语句,而不需要CREATE TABLE语句或类似的语句。