【问题标题】:How to avoid using limit clause in my redshift query?如何避免在我的红移查询中使用限制子句?
【发布时间】:2021-01-12 21:10:24
【问题描述】:

我有一个下面的查询,我使用limit 8 来获取日期值,如下所示:

SELECT (date_trunc('week', getdate() + INTERVAL '1 day')::date - 7 * (row_number() over (order by true) - 1) - INTERVAL '1 day')::date AS week_column
FROM dimensions.customer LIMIT 8

下面是我从上面的查询得到的输出:

2021-01-10
2021-01-03
2020-12-27
2020-12-20
2020-12-13
2020-12-06
2020-11-29
2020-11-22

有什么方法可以避免在上面的查询中使用limit 8 并且仍然得到相同的输出?我们的一个平台不允许我们运行查询,如果它有限制,所以想看看我是否可以在 sql redshift 中以不同的方式重写它?

以下是我使用dates CTE 的完整查询:

WITH dates AS (
    SELECT (date_trunc('week', getdate() + INTERVAL '1 day')::date - 7 * (row_number() over (order by true) - 1) - INTERVAL '1 day')::date AS week_column
    FROM dimensions.customer LIMIT 8
)
SELECT 
dates.week_column, 
'W' || ceiling(date_part('week', dates.week_column + INTERVAL '1 day')) AS week_number,
COUNT(DISTINCT features.client_id) AS total
FROM dimensions.program features 
JOIN dates ON features.last_update <= dates.week_column
WHERE features.type = 'capacity'
AND features.status = 'CURRENT'
GROUP BY dates.week_column
ORDER by dates.week_column DESC

我怎样才能以不同的方式重写我的dates CTE 查询,以便它可以给我相同的输出?

更新

如果我像这样运行查询,它会给我一个错误,但如果我在 from 内运行最里面的 sql 查询,那么它会给我数据。

SELECT *
FROM (SELECT (date_trunc('week', getdate() + INTERVAL '1 day')::date - 7 * (row_number() over (order by true) - 1) - INTERVAL '1 day')::date AS week_column,
              ROW_NUMBER() OVER () as seqnum
      FROM dimensions.customer
     ) c
WHERE seqnum <= 8;

错误是:

Invalid operation: Output timestamp out of range after subtracting constant. Details: ----------------------------------------------- error: Output timestamp out of range after subtracting constant. 

【问题讨论】:

    标签: sql amazon-web-services amazon-redshift


    【解决方案1】:

    你可以使用窗口函数:

    SELECT . . .   -- whatever columns you want
    FROM (SELECT (date_trunc('week', getdate() + INTERVAL '1 day')::date - 7 * (row_number() over (order by true) - 1) - INTERVAL '1 day')::date AS week_column,
                  ROW_NUMBER() OVER () as seqnum
          FROM dimensions.customer
         ) c
    WHERE seqnum <= 8;
    

    在 Redshift 中,ORDER BY 对于 ROW_NUMBER() 是可选的。一般来说,我会鼓励你有一个ORDER BY。您的查询也是如此。 LIMIT 通常与ORDER BY 一起使用。

    编辑:

    思路是一样的:

    with dates as (
         ),
         q as (
          <your query here>
         )
    select q.*
    from (select q.*,
                 row_number() over (order by weeks_column desc) as seqnum
          from q
         ) q
    where seqnum <= 8;
    

    【讨论】:

    • 谢谢戈登。我正在用我的完整查询更新我的问题,而我正在使用我的dates CTE,而您的答案进来了。如何在原始查询中使用您的建议?
    • 顺便说一句,我在运行您的建议后遇到错误,因为它是 error: Output timestamp out of range after subtracting constant. code:。有什么想法可能是错的吗?
    • @AndyP 。 . .只需在您的 CTE 中使用row_number() 来计算seqnum,这样您就可以过滤而不是使用limit
    • 我用我尝试过的方法更新了我的问题。当我运行它时它会给我一个错误,除非我做错了。您能否根据我的查询提供一个示例依据?
    • 对为什么我在问题中更新的查询给出错误的任何想法?我看到了你的编辑,但它与更新部分中的查询几乎相同,它给出了一个错误,所以想看看有什么问题?
    猜你喜欢
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 2011-07-25
    • 2016-06-28
    • 1970-01-01
    • 2013-07-14
    • 2010-09-17
    相关资源
    最近更新 更多