我获得的分区数据包含一组三列 - 红色
、绿色
和蓝色
。它们分别是不同规划区域的填充颜色的 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/