2017-07-27 131 views
0

我是SQL新手,并且有一个由数字和文本组成的字符串的表(例如,“10 Windows”) 。从这个表中,我需要从字符串中提取出“10”,并将其作为整数移动到一个新列中(我使用的是pgAdmin4)如何在使用CAST和SUBSTRING时过滤postgresql中的查询结果(pgAdmin 4)

我能够编写一个查询来解析出数字该字符串并将它们作为整数返回到新列。

SELECT data1, CAST(SUBSTRING(data1 FROM '(\d+)') AS INTEGER) AS data1_num 
FROM events 

从这里,我可以从data1中的字符串中获取数字,将其作为data1_num列作为整数。

但是,如果我想过滤找到所有行,其中data1_num = 27,通过下面的查询,我得到一个错误。

SELECT data1, CAST(SUBSTRING(data1 FROM '(\d+)') AS INTEGER) AS data1_num 
FROM events 
WHERE data1_num = 27 

错误:

ERROR: column "data1_num" does not exist 
LINE 3: WHERE data1_num = 27 
     ^
********** Error ********** 

ERROR: column "data1_num" does not exist 
SQL state: 42703 
Character: 205 

我这么想吗?

我觉得这应该工作,即使data1_num是27的零行,我也不应该得到一个错误。

回答

0

由于在postgresql中解析查询的方式,您会收到错误消息。首先检查where条件,然后按语句排序(如果有的话),然后最后选择列列表。所以postgres无法识别别名。

我觉得这会给你想要的结果:

SELECT data1, CAST(SUBSTRING(data1 FROM '(\d+)') AS INTEGER) AS data1_num 
FROM events 
WHERE SUBSTRING(data1 FROM '(\d+)') = '27' 
0

这不会因为列“data1_num”是一个虚拟列,如果你想要得到的结果,那么你必须写同样的铸造工作where子句中的逻辑。

SELECT data1, CAST(SUBSTRING(data1 FROM '(\d+)') AS INTEGER) AS data1_num 
FROM events 
WHERE CAST(SUBSTRING(data1 FROM '(\d+)') AS INTEGER) = 27 
0

即使你SELECT条款首次出现在查询中,它实际上是WHERE条款后评估。这是标准的SQL。这意味着您无法访问您的SELECT上的计算列(或列别名)。

就试试这个:

SELECT data1, CAST(SUBSTRING(data1 FROM '(\d+)') AS INTEGER) AS data1_num 
FROM events 
WHERE CAST(SUBSTRING(data1 FROM '(\d+)') AS INTEGER) = 27 ; 

注意:不要担心被计算两次表达式。这是由数据库来优化的。

如果你还是担心,您可以使用此:

SELECT 
    * 
FROM 
    (
     SELECT data1, CAST(SUBSTRING(data1 FROM '(\d+)') AS INTEGER) AS data1_num 
     FROM events 
    ) AS q 
WHERE data1_num = 27 ; 

参考文献: