我有一个数据集,其数据格式如下:
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]
-----------------------------------------------
我有什么想法可以解决这个问题吗?
答案 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