1

我有一个看起来像这样的 mysql 数据库

target_color       
'rgb(200,200,200)'
'rgb(190,29,209)'

我需要生成一个看起来像这样的数据库

target_hue   ~   target_saturation  ~ target_lightness   ~   hex_value
10          ~    40        ~         40           ~         a567ff

我遇到的主要问题是解析rgb(x,y,z)以提取值。我认为正则表达式可以解决问题,但 mysql 不支持它们……也试过了substrint()substring_index()但完全纠结了……

4

3 回答 3

1

您可以使用该SUBSTRING_INDEX函数提取逗号之间的各个整数值。

SET @rgb := 'rgb(190,29,209)' ;

SELECT @rgb
     , @rgbv := SUBSTRING_INDEX(SUBSTRING_INDEX(@rgb,'rgb(',-1),')',1) AS `@rgbv`
     , @v1 := SUBSTRING_INDEX(@rgbv,',',1)                             AS `@v1`
     , @v2 := SUBSTRING_INDEX(SUBSTRING_INDEX(@rgbv,',',2),',',-1)     AS `@v2`
     , @v3 := SUBSTRING_INDEX(SUBSTRING_INDEX(@rgbv,',',3),',',-1)     AS `@v3`
     , 0 + @v1  AS R
     , 0 + @v2  AS G
     , 0 + @v3  AS B

SELECT 列表中的最后三列表明用户变量可以在其他(后续)表达式中使用,在这种情况下,将它们添加到整数值 0 以将它们作为整数返回。

不幸的是,MySQL 不提供GREATESTLEAST功能。这些会很方便,因此您可以使用如下表达式获得 Hue 的值:

GREATEST(0+@v1,0+@v2,0+@v3) - LEAST(0+@v1,0+@v2,0+@v3)

您可以为三个值“滚动自己的”最大和最小函数:

IF(0+@v1>0+@v2
  ,IF(0+@v1>0+@v3,0+@v1,IF(0+@v2>0+@v3,0+@v2,0+@v3))
  ,IF(0+@v2>0+@v3,0+@v2,0+@v3)
  ) AS `max(R,G,B)`

IF(0+@v1<0+@v2
  ,IF(0+@v1<0+@v3,0+@v1,IF(0+@v2<0+@v3,0+@v2,0+@v3))
  ,IF(0+@v2<0+@v3,0+@v2,0+@v3)
  ) AS `min(R,G,B)`

从包含名为 rgb 的列的表中,查询可能如下所示:

SELECT s.R
     , s.G
     , s.B
     , IF(s.R>s.G,IF(s.R>s.B,s.R,s.B),IF(s.G>s.B,s.G,s.B)) AS `max(R,G,B)`
     , IF(s.R<s.G,IF(s.R<s.B,s.R,s.B),IF(s.G<s.B,s.G,s.B)) AS `min(R,G,B)`
  FROM (
         SELECT t.rgb
              , @rgbv := SUBSTRING_INDEX(SUBSTRING_INDEX(t.rgb,'rgb(',-1),')',1) AS `@rgbv`
              , @v1 := SUBSTRING_INDEX(@rgbv,',',1)                              AS `@v1`
              , @v2 := SUBSTRING_INDEX(SUBSTRING_INDEX(@rgbv,',',2),',',-1)      AS `@v2`
              , @v3 := SUBSTRING_INDEX(SUBSTRING_INDEX(@rgbv,',',3),',',-1)      AS `@v3`
              , 0 + @v1  AS v1
              , 0 + @v2  AS v2
              , 0 + @v3  AS v3
           FROM mytable t
       ) s
于 2012-09-13T16:20:28.747 回答
0

给定包含'rgb(190,29,209)'被调用的字段rgb,那么您可以使用此 sql 提取这三个值:

select 
   substring(rgb, locate('(',rgb)+1,locate(',',rgb) -1 - locate('(',rgb)) as red,
   substring(substring_index(rgb,',',2) , locate(',',rgb)+1) as green,
   substring(rgb, locate(',',rgb, locate(',',rgb)+1 )+1 , locate(')',rgb) 
                   -1 - locate(',',rgb, locate(',',rgb)+1 )) as blue

这将输出这个结果集:

red  green  blue
190  29     209
于 2012-09-13T16:48:22.000 回答
0

我用它来将 csv rgb 值直接转换为十六进制。

UPDATE table1 ami
JOIN 
(
SELECT id, value 
, SUBSTRING(value, 1, LOCATE(',', value)-1) as R
, SUBSTRING(value, LOCATE(',', value)+1, LOCATE(',', value, LOCATE(',', value)+1) - LOCATE(',', value) - 1) G
, SUBSTRING(value, LOCATE(',', value, LOCATE(',', value)+1)+1) B
from table1 ai
where locate(',', value) > 0
) tbl ON ami.id = tbl.id
SET ami.value = CONCAT(
 LPAD(CONV(tbl.R, 10, 16),2,'0') 
, LPAD(CONV(tbl.G, 10, 16),2,'0')
, LPAD(CONV(tbl.B, 10, 16),2,'0'));

显然更改表名:) 希望这对其他人有所帮助。

于 2014-10-24T13:54:15.123 回答