带有子查询的 redshift sql 查询中的语法错误

Posted

技术标签:

【中文标题】带有子查询的 redshift sql 查询中的语法错误【英文标题】:Syntax error in redshift sql query with subqueries 【发布时间】:2020-01-26 20:23:48 【问题描述】:

总的来说,我对 SQL 很陌生,以前没有处理过红移。我正在尝试进行一个查询,该查询在 postgresql 中完美运行。但是我在红移中遇到语法错误。查询是:

SELECT 
    test.table_1.user_id as user_id,
    test.table_1.timestamp as start_session,
    test.table_1.step_3 :: timestamp +  interval '1 hour' as end_session,
    test.table_1.step_3 :: timestamp +  interval '1 hour' - test.table_1.timestamp :: timestamp as session_duration

FROM (SELECT *,
    min(case when page = 'second_page' then timestamp end) OVER (partition by user_id order by timestamp desc rows between unbounded preceding and unbounded following) as step_2,
    min(case when page = 'third_page' then timestamp end) OVER (partition by user_id order by timestamp desc rows between unbounded preceding and unbounded following) as step_3
    FROM test.table_1) test.table_1

WHERE 
    test.table_1.page = 'first_page' AND
    step_2 > test.table_1.timestamp AND
    step_3 > step_2 AND
    step_3 :: timestamp - step_2 :: timestamp < '1 hour' AND
    step_2 :: timestamp - test.table_1.timestamp :: timestamp < '1 hour'
ORDER BY
    user_id,start_session

错误是Error running query: syntax error at or near "." LINE 11: FROM test.vimbox_pages) test.vimbox_pages ^ 在行FROM test.table_1) test.table_1 我不明白那里有什么问题。 通过这个查询,我试图以某种顺序在阅读页面期间获取用户操作的会话列表。 将感谢任何帮助!

【问题讨论】:

将子查询的别名从 test.table_1 更改为 t1 并在您的查询中使用它。 文档没有明确说明它也适用于别名,但我猜别名命名应该遵循相同的规则:docs.aws.amazon.com/redshift/latest/dg/r_names.html 它说:不包含引号和空格。 【参考方案1】:

别名是标识符,需要遵循标识符的规则。您还可以通过其他方式简化查询:

SELECT t.user_id, t.timestamp as start_session,
       (t.step_3::timestamp + interval '1 hour' as end_session),
       (t.step_3::timestamp + interval '1 hour' - t.timestamp::timestamp) as session_duration
FROM (SELECT t.*,
             MIN(CASE WHEN page = 'second_page' THEN timestamp END) OVER (PARTITION BY user_id) as step_2,
             MIN(CASE WHEN page = 'third_page' THEN timestamp END) OVER (partition by user_id) as step_3
      FROM test.table_1 t
     ) t
WHERE t.page = 'first_page' AND
      step_2 > t.timestamp AND
      step_3 > step_2 AND
      step_3::timestamp < step_2::timestamp + interval '1 hour' AND
      step_2::timestamp < timestamp + interval '1 hour'
ORDER BY user_id, start_session;

注意事项:

您的窗口子句过于复杂。如果您想要整个窗口范围,则不需要ORDER BY。 考虑到列的名称,应该不需要转换为timestamp。但我把它们留在里面了。 t.user_id as user_id 是多余的。无论如何,列名将是 user_id。 我从未在:: 周围看到空格。当然是允许的,但是类型转换的优先级很高,并且通常不带空格。 我更喜欢时间戳比较而不是时间戳,而不是转换为间隔。间隔时间可能会发生奇怪的事情。

【讨论】:

以上是关于带有子查询的 redshift sql 查询中的语法错误的主要内容,如果未能解决你的问题,请参考以下文章

MySQL基础语法之子链接查询和特殊查询(union 和 limit)

带子查询的redshift sql查询中的语法错误

Redshift:连接到由表中的 SELECT * 组成的子查询/CTE 相当于连接表本身,还是性能下降?

如何运行存储在 Redshift 表中的 SQL 查询

带有(来自)别名的 SQL 子查询

Redshift 中的 DAU WAU MAU 错误:[Amazon](500310) 无效操作:由于内部错误,不支持此类关联子查询模式;