【问题标题】:Creating a Bin column in Postgres to check an integer and return a string在 Postgres 中创建一个 Bin 列来检查一个整数并返回一个字符串
【发布时间】:2018-05-25 13:57:34
【问题描述】:

我在 Postgres 数据库中有一个大型数据集,需要生成一个字段,将行分组到相应的 bin 中,用于“0-100”、“101-200”、“201-300”等。多达近 5000 个。我知道我可以手动更新每一行并为每个 bin 生成一行代码,如下所示:

update test
   set testgroup = '0-100' where testint >= 1 and distance < 100;

我真的很想找到一种更有效的方法来做到这一点,对任何事物都开放!主要目标是查看“testint”列中的整数,然后如果它在 1-100 之间,则返回 testgroup 列“0-100”。

【问题讨论】:

  • 每一行都有唯一的标识符吗?
  • 在您的示例代码中,比较变量不应该相同吗?即 testint >=1 和 testint
  • 抱歉打错了。并不是真的想写那行并手动更新它 50 次。这些行确实具有唯一标识符。

标签: postgresql postgresql-9.5


【解决方案1】:

使用width_bucket 函数。请参阅the docs,但这里是语法的简短版本:

width_bucket(a, LBound, UBound, num_bins)

为了让它在你的垃圾箱中正常工作,我必须将 1 添加到 UBound。一些例子:

select width_bucket( 1, 0, 5001, 50) 给出 1
select width_bucket(100, 0, 5001, 0) 给出 1
select width_bucket(101, 0, 5001, 50) 给出 2
select width_bucket(4900, 0, 5001, 50) 给出 49
select width_bucket(4901, 0, 5001, 50) 给出 50

所以它按预期工作。接下来我们需要生成正确的字符串。伪格式是

(width_bucket - 1)*100 || '-' || (width_bucket)*100

在哪里 ||是 SQL 连接运算符。使用之前的第一个示例:

select (width_bucket(1, 0, 5001, 50)-1)*100 || ' - ' || width_bucket(1, 0, 5001, 50)*100

'0 - 100'

甜。现在把它们放在一起。首先制作一个可用于测试的沙盒表。这将是您数据的副本或部分副本:

CREATE TABLE test
AS
SELECT * 
FROM original_table 

然后将新列添加到表中:

ALTER TABLE test
  ADD COLUMN testgroup text

现在是 UPDATE 语句:

UPDATE test
   SET testgroup = width_bucket(testint, 0, 5001, 50)-1)*100 || ' - ' || 
                   width_bucket(testint, 0, 5001, 50)*100

【讨论】:

    【解决方案2】:

    您可以利用generate_series生成0到50的数字,然后在生成的值*100和下一个生成的值*100之间选择数据。使用相同的原理构建bin名称。

    UPDATE test
    SET testgroup = (x*100)+1 || '-' || (x+1)*100
    FROM generate_series(0,50) f(x)
    WHERE testint > (x*100) 
      AND testint <= ((x+1)*100);
    

    http://rextester.com/FXIS37706

    【讨论】:

    • 您好,我正在使用类似的分箱方法,发现您的代码很有用。虽然我似乎理解得不够好。关于“FROM generate_series(0,50) f(x)”的部分。虽然我理解逻辑,但我无法获得语法。 f(x) 在这里是什么意思 - 一个函数?或其他数据集,如 generate_series(0,50)
    • @KanduriR f 是输出的表别名,(x) 用于重命名列。因为generate_series 的输出是单列,所以它并没有真正增加太多。假设您有一个表mytable 有3 列x, y, z,您可以执行select * from mytable a(a,b,c),列将显示为a,b,c,而不是x,y,z
    • 现在明白了。谢谢@JGH。这个符号 mytable a(a,b,c) 是特定于 postgres 还是 SQL 语言中的通用符号?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多