WHERE子句中的DB2别名

时间:2015-08-27 21:23:02

标签: sql db2

我有几个DB2表,一个用于users,一个用于newsletters,我想在WHERE子句中选择使用别名。

SELECT a.*, b.tech_id as user FROM users a  
JOIN newsletter b ON b.tech_id = a.newsletter_id
WHERE timestamp(user) < current_timestamp

这是彻底简化的,所以我可以看到发生了什么,但是我收到的错误让我认为user别名没有正确传递:

ERROR: An invalid datetime format was detected; that is, an 
invalid string representation or value was specified. 

user.tech_id是在创建记录时根据datetime构建的字符串,因此它看起来像20150210175040951186000000。我已经确认我可以成功执行timestamp(tech_id) - 因此它无法成为导致问题的字段格式。

有什么想法吗?

更多信息:

每个用户都有多个简报。我需要获取最新的时事通讯(由tech_id提供)并检查是否在过去一周内创建了该时事通讯。因此,更复杂的版本将是:

SELECT a.*, b.tech_id as user FROM users a  
JOIN newsletter b ON b.tech_id = a.newsletter_id
WHERE timestamp(max(user)) < current_timestamp

是否有办法JOIN仅限于最近的记录?

2 个答案:

答案 0 :(得分:1)

执行顺序与写入顺序不同。 FROM&amp; WHERE子句在SELECT子句之前执行,因此当您尝试使用别名时别名不存在。

您必须“嵌套”查询的一部分,以便在where子句之前定义别名。在许多情况下可以更容易地不使用别名。

WHERE timestamp(b.tech_id) < current_timestamp

SQL子句的通用“执行顺序”是

FROM
   JOINs (as part of the from clause)
WHERE
GROUP BY
HAVING
SELECT
ORDER BY

有没有办法仅在最近的记录中加入?

一个有用的技术是使用ROW_NUMBER(),假设你的DB2支持它,看起来像这样:

SELECT
      a.*
    , b.tech_id AS techuser
FROM users a
JOIN (
      SELECT
            *
          , ROW_NUMBER() OVER (ORDER BY timestamp(tech_id) DESC) AS RN
      FROM newsletter
) b
      ON b.tech_id = a.newsletter_id
      AND b.rn = 1

这只会给你一个新闻通讯行,并且使用DESCending订单会给你“最新”假设时间戳(tech_id)的工作原理如上所述。

答案 1 :(得分:0)

要获取最新的用户通讯,请考虑订购连接查询,然后选择最高记录(在DB2中使用FETCH FIRST ONLY):

SELECT a.*, b.tech_id as user 
  FROM users a  
INNER JOIN newsletter b ON b.tech_id = a.newsletter_id
ORDER BY b.tech_id
FETCH FIRST 1 ROW ONLY;

或者,您可以在WHERE子句中使用子查询来聚合最大用户:

SELECT a.*, b.tech_id as user 
  FROM users a  
WHERE b.tech_id IN (
  SELECT Max(n.tech_id) as maxUser
  FROM users u 
  INNER JOIN newsletter n ON n.tech_id = u.newsletter_id)

我遗漏了timestamp(user) < current_timestamp的条件,因为存储在数据库中的数据总是小于当前时间(即现在)。