SUBSTR不适用于Postgres 8.3中的数据类型“timestamp”

时间:2009-07-07 12:02:48

标签: postgresql

我在postgres中遇到了以下查询的问题

SELECT u.username,l.description,l.ip,SUBSTRING(l.createdate,0,11) as createdate,l.action
FROM n_logs AS l LEFT JOIN n_users AS u ON u.id = l.userid
WHERE SUBSTRING(l.createdate,0,11) >= '2009-06-07'
    AND SUBSTRING(l.createdate,0,11) <= '2009-07-07';

我总是在较旧版本的postgres中使用上述查询,并且它可以100%运行。现在有了posgres的新版本,它给了我下面的错误

**ERROR:  function pg_catalog.substring(timestamp without time zone, integer, integer) does not exist
LINE 1: SELECT u.username,l.description,l.ip,SUBSTRING(l.createdate,...
                                             ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.**

我认为它与数据类型有关,数据是一个时区,而substring只支持字符串数据类型,现在我的问题是我可以对我的查询做些什么,以便我的结果出现?

5 个答案:

答案 0 :(得分:8)

您的问题的显式解决方案是将日期时间转换为字符串。

...,SUBSTRING(l.createdate :: VARCHAR,...

现在,使用结果比较日期并不是一个好习惯。

因此,您需要的良好解决方案是使用显式datetime manipulation, comparisonformatting函数更改查询,例如extract()和to_char()

您必须将查询更改为包含类似

的子句
l.createdate::DATE >= '2009-06-07'::DATE 
AND l.createdate::DATE < '2009-07-08'::DATE;

或下面的替代方案之一(你应该接受而不是这个。)

答案 1 :(得分:5)

SELECT  u.username, l.description, l.ip,
        CAST(l.createdate AS DATE) as createdate,
        l.action
FROM    n_logs AS l
LEFT JOIN
        n_users AS u
ON      u.id = l.userid
WHERE   l.createdate >= '2009-06-07'::TIMESTAMP
        AND l.createdate < '2009-07-07'::TIMESTAMP + '1 DAY'::INTERVAL

答案 2 :(得分:1)

Quassnoi答案的变体:

SELECT
    u.username,
    l.description,
    l.ip,
    CAST(l.createdate AS DATE) as createdate,
    l.action
FROM
    n_logs AS l
LEFT JOIN
    n_users AS u
ON
    (u.id = l.userid)
WHERE
    l.createdate::DATE BETWEEN '2009-06-07'::DATE AND '2009-07-07'::DATE

答案 3 :(得分:1)

我不确定你想要实现什么,但是日期数据类型上的“substring”基本上没有很好地定义,因为它取决于所述数据的外部格式。

在大多数情况下,您应该使用extract()to_char()函数。

通常 - 对于返回数据,你想要to_char(),以及对它的操作(包括比较) - extract()。在某些情况下,这个一般规则不适用,但这些通常表明数据结构并不是很好。

示例:

# select to_char( now(), 'YYYY-MM-DD');
  to_char
------------
 2009-07-07
(1 row)

对于抽取,让我们编写一个简单的查询,列出在晚上8点之后创建的所有对象:

select * from objects where extract(hour from created) >= 20;

答案 4 :(得分:0)

如果您使用Postgresql,您将收到:

select('SUBSTRING(offer.date_closed, 0, 11)')
  

函数substr(没有时区整数整数的时间戳)没有   存在

使用:

select('SUBSTRING(CONCAT(offer.date_closed, \'\'), 0, 11)')