如何查询值为> = 60000的子字符串

时间:2014-11-21 19:19:58

标签: sql database postgresql pattern-matching amazon-redshift

我有一个数据集,其数据格式如下:

Date        | exec_time
------------+---------
Today       | 99999 ms
Yesterday   | 1 ms
Tomorrow    | 50000 ms
Another Day | None Recorded
Last Day |  ms

我需要做的是编写查询以获取exec_time

的所有>= 60000

我试图写它的方式是这样的:

select exec_time 
from myTable
where exec_time not like '%N%'
and cast(split_part(exec_time,' ', 1) as int) >= 60000
order by len(exec_time) desc, exec_time desc
limit 10

然而,当我运行它时,我收到此错误:

ERROR: Invalid digit, Value '2', Pos 0, Type: Integer 
  Detail: 
  -----------------------------------------------
  error:  Invalid digit, Value '2', Pos 0, Type: Integer 
  code:      1207
  context:   
  query:     2780081
  location:  :0
  process:   query0_61 [pid=0]
  -----------------------------------------------

我有什么想法可以解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

错误:WHERE条件不会以任何给定的顺序执行 使用CASE语句来避免异常。

SELECT exec_time 
FROM   myTable
WHERE  CASE WHEN exec_time NOT LIKE '%N%' THEN
         split_part(exec_time,' ', 1)::int >= 60000
       ELSE FALSE END
ORDER  BY length(exec_time) desc, exec_time desc
LIMIT  10;

在此期间,如果'None Recorded'是唯一要排除的情况,请使用更快的左锚定检查:

exec_time NOT LIKE 'N%'

如果仍然出现上述问题,请检查以查找您可能遗漏的任何违规行:

SELECT DISTINCT exec_time
FROM   myTable
WHERE  exec_time NOT LIKE '%N%'
AND    exec_time !~ '^\\d+ '  -- not all digits before the first space

在现代Postgres中,你只需要一个反斜杠。 '^\d+ '!似乎你必须加倍Redshift中的反斜杠,默认情况下似乎仍然使用过时的Posix escape syntax for strings,并且没有明确的声明(E'^\\d+ ')!

通常,以这种方式混合数据不是一个好主意。您应该有一个integer列来存储执行时间。更便宜,更清洁,更快。

答案 1 :(得分:1)

我认为问题是“无记录”值。我不知道它是否会运行第一个排除第一个或不排除第一个的位置。试试这个:

SELECT exec_time
FROM (SELECT exec_time FROM myTable WHERE exec_time NOT LIKE 'N%') as foo
WHERE cast(split_part(foo.exec_time, ' ', 1) as int) >= 60000
ORDER by length(foo.exec_time) desc, foo.exec_time desc
limit 10