首页 > 解决方案 > 如何避免在我的红移查询中使用限制子句?

问题描述

我有一个下面的查询,我用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 中以不同的方式重写它?

以下是我在哪里使用datesCTE 的完整查询:

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

如何以不同的方式重写我的datesCTE 查询,以便它可以给我相同的输出?

更新

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

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. 

标签: sqlamazon-web-servicesamazon-redshift

解决方案


您可以使用窗口函数:

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;

推荐阅读