PostgreSQL中将因子(字符串)转换为数字

PostgreSQL中将因子(字符串)转换为数字,sql,postgresql,types,Sql,Postgresql,Types,类似于,可以在PostgreSQL中将字符串字段转换为数字字段。比如说, create table test (name text); insert into test (name) values ('amy'); insert into test (name) values ('bob'); insert into test (name) values ('bob'); insert into test (name) values ('celia'); 并添加一个 name | num

类似于,可以在PostgreSQL中将字符串字段转换为数字字段。比如说,

create table test (name text);

insert into test (name) values ('amy');
insert into test (name) values ('bob');
insert into test (name) values ('bob');
insert into test (name) values ('celia');
并添加一个

 name  | num
-------+-----
 amy   | 1
 bob   | 2
 bob   | 2
 celia | 3

如果它们都是单个字符,则可以执行以下操作:

ALTER TABLE test ADD COLUMN num int;
UPDATE test SET num = ascii(name);

如果字符串不止一个字符,则只返回第一个字母的字符。

如果它们都是单个字符,则可以执行以下操作:

ALTER TABLE test ADD COLUMN num int;
UPDATE test SET num = ascii(name);
不过,如果字符串不止一个字符,那么它只会返回第一个字母的字符。

名称的散列如何

如果您需要将md5文本转换为一个数字:

关于名称的散列如何


如果您需要将md5文本转换为数字:

最有效的散列函数是主键-为您提供问题中所希望的唯一数字

在本演示中,我还处理了重复项:

CREATE TEMP TABLE string (
  string_id serial PRIMARY KEY
 ,string    text NOT NULL UNIQUE    -- no dupes
 ,ct        int NOT NULL DEFAULT 1  -- count instead of dupe rows
);
然后输入新字符串,如下所示: 需要PostgreSQL 9.1或更高版本

WITH x AS (SELECT 'abc'::text AS nu)
   , y AS (
   UPDATE string s
   SET    ct = ct + 1
   FROM   x
   WHERE  s.string = x.nu
   RETURNING TRUE
   )
INSERT INTO string (string)
SELECT nu
FROM   x
WHERE NOT EXISTS (SELECT 1 FROM y);
如果字符串nu已经存在,则计数ct增加1。如果不是,则插入一个新行,从计数1开始

UNIQUE还会自动在string.string列上添加索引,从而使此查询获得最佳性能

添加额外的逻辑触发器?用于更新/删除以使此防弹-如果需要

注意,如果两个并发事务试图在同一时刻添加相同的字符串,那么这里有一个非常小的竞争条件。当然,您可以使用可序列化事务。更多信息和链接在此


最有效的散列函数是一个主键-给你一个唯一的数字,就像你在问题中希望的那样

在本演示中,我还处理了重复项:

CREATE TEMP TABLE string (
  string_id serial PRIMARY KEY
 ,string    text NOT NULL UNIQUE    -- no dupes
 ,ct        int NOT NULL DEFAULT 1  -- count instead of dupe rows
);
然后输入新字符串,如下所示: 需要PostgreSQL 9.1或更高版本

WITH x AS (SELECT 'abc'::text AS nu)
   , y AS (
   UPDATE string s
   SET    ct = ct + 1
   FROM   x
   WHERE  s.string = x.nu
   RETURNING TRUE
   )
INSERT INTO string (string)
SELECT nu
FROM   x
WHERE NOT EXISTS (SELECT 1 FROM y);
如果字符串nu已经存在,则计数ct增加1。如果不是,则插入一个新行,从计数1开始

UNIQUE还会自动在string.string列上添加索引,从而使此查询获得最佳性能

添加额外的逻辑触发器?用于更新/删除以使此防弹-如果需要

注意,如果两个并发事务试图在同一时刻添加相同的字符串,那么这里有一个非常小的竞争条件。当然,您可以使用可序列化事务。更多信息和链接在此


.您的请求中显示的确切案例可以通过以下方式生成:

因此,如果您为每行添加一个数字,您可以执行以下操作:

ALTER TABLE test ADD COLUMN some_num integer;

WITH gen(gen_name, gen_num) AS 
   (SELECT name, dense_rank() OVER (ORDER BY name) FROM test GROUP BY name)
UPDATE test SET some_num = gen_num FROM gen WHERE name = gen_name;

ALTER TABLE test ALTER COLUMN some_num SET NOT NULL;
然而,我认为使用散列或分配生成的密钥更明智。我只是想说明你的例子是可以实现的


这种方法的最大问题是插入新数据是一件痛苦的事。这是一个排名,如您的示例所示,因此如果您在测试名称中插入值“billy”;然后排名会发生变化。

您的请求中显示的确切案例可以通过以下方式生成:

因此,如果您为每行添加一个数字,您可以执行以下操作:

ALTER TABLE test ADD COLUMN some_num integer;

WITH gen(gen_name, gen_num) AS 
   (SELECT name, dense_rank() OVER (ORDER BY name) FROM test GROUP BY name)
UPDATE test SET some_num = gen_num FROM gen WHERE name = gen_name;

ALTER TABLE test ALTER COLUMN some_num SET NOT NULL;
然而,我认为使用散列或分配生成的密钥更明智。我只是想说明你的例子是可以实现的


这种方法的最大问题是插入新数据是一件痛苦的事。这是一个排名,如您的示例所示,因此如果您在测试名称中插入值“billy”;然后排名会改变。

插入测试名称值怎么样☃';?这个数字代表什么?您正在寻找字符串的ASCII字符表示形式吗?或者您想给一个字符指定一个任意的数字,如a=1?@jcern这些数字没有任何意义,只要它们能够区分名称。@MattBall我需要一个自动过程将名称字段转换为数字。真正的表有数千行。@所以像名称哈希这样的东西就足够了?插入到测试名称值中怎么样☃';?这个数字代表什么?您正在寻找字符串的ASCII字符表示形式吗?或者您想给一个字符指定一个任意的数字,如a=1?@jcern这些数字没有任何意义,只要它们能够区分名称。@MattBall我需要一个自动过程将名称字段转换为数字。真正的表有数千行。@Rock,所以像名称散列这样的东西就足够了吗?谢谢Jcern。实际上,它们不是单一的字符。这是一个文本字段,谢谢你。实际上,它们不是单一的字符。这是一个文本字段。@Rock:md5哈希值不是唯一的。虽然发生碰撞的可能性很小,但也无法保证。Amy可能会得到与Bob相同的哈希值。@Rock:md5哈希值不是唯一的。虽然发生碰撞的可能性很小,但也无法保证。艾米可能会得到和鲍勃一样的答案。谢谢你这个伟大的答案,永远和你的其他答案一样完整,欧文。谢谢你这个伟大的答案,永远和你的其他答案一样完整,欧文。谢谢你的答案克雷格。至少
这是实现它的另一种方法,在其他情况下可能有用。谢谢你的回答,克雷格。至少这是实现它的另一种方式,在其他情况下可能有用。