PostgreSQL:数字到 2 位十六进制的更整洁转换

标签 postgresql

我获得的分区数据包含一组三列 - 红色绿色蓝色。它们分别是不同规划区域的填充颜色的 R、G 和 B 值。

在原始表中,它们是 VARCHAR,但我将它们转换为 INT,因为 RGB 中的 R、G 和 B 值是规范的 8 位(否则任何时候)如果你想将这些值用于其实际目的,你最终会陷入双冒号 hell - 而且更多的冒号一定很糟糕,对吧?)。

所以无论如何,对于表示层的东西,我需要 RGB 作为十六进制颜色(即 #000000 - #FFFFFF)。

我知道有两种方法可以做到这一点:

upper('#'||lpad(to_hex(red)::text,2,'0')||lpad(to_hex(green)::text,2,'0')||lpad(to_hex(blue)::text,2,'0'))

upper('#'||lpad(to_hex(((red * 65536) + (green * 256) + blue))::text,6,'0'))

这两个都相当重冒号,与 Python 相比,看起来真的 super 笨拙

'#%02x%02x%02x' % eval(a,)

其中a = (red,green,blue)通过cursor.execute从数据库中提取。

每个 PostgreSQL 变体上的 lpad() 对于获取有效的十六进制颜色是必需的:要了解原因,请在不使用 lpad 的情况下转换 (5,189,94) 或 (0,204,153) - ing,并将结果(分别为#5BDC2和#0CC99/#CC99)放入颜色检查器中。

upper() 只是我对颜色代码中全部大写的偏好;上面的 Python eval() 给出全部大写。

现在的问题是:在 PostgreSQL 中是否有一种更简洁的方法可以做到这一点,而无需编写一个函数来实现我上面概述的两个变体之一?

使其成为一个函数很简单,但如果已经有 native 功能(无论是查询中还是以更简洁的方式将其编码为函数),了解这一点将会很有用。

环境:PostgreSQL 9.3.5 (Windows)。

最佳答案

SELECT
    '#' || lpad(upper(to_hex((R << 16) | (G << 8) | B)), 6, '0')
FROM (
    SELECT
        1 AS R,
        28 AS G,
        123 AS B
    ) AS RGB;

没有使用冒号;)但是我有 PostgreSQL 9.5,我希望它也可以在 9.3.5 上运行。

关于PostgreSQL:数字到 2 位十六进制的更整洁转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38317954/

相关文章:

sql - 仅当所有需求行都存在时才从表中选择徽章

spring - 使用 tomcat 池和 Spring 在 postgres 中自动重新连接

PostgreSQL:使用 LIKE、ANY 和通配符的 Where 子句

sql - 使用 postgresql 连接一对多表时如何使用 LIMIT 和 OFFSET?

sql - 替代 Postgres SERIAL 字段以解决在 ON CONFLICT 导致更新时递增的值

postgresql - 启动时的 Sail.js 多个连接

node.js - 计算日期范围的重叠量

sql - 递归 SQL - 计算层次结构中的后代数

mysql - 为什么不能通过显式锁定查询语法获取谓词锁

macos - 在 lion 上损坏的 brew 安装的 postgresql