Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.3k views
in Technique[技术] by (71.8m points)

sql - How to avoid using limit clause in my redshift query?

I have a below query where I am using limit 8 to get value of dates as shown below:

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

Below is the output I get from above query:

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

Is there any way to avoid using limit 8 in my above query and still get same output? One of our platform doesn't allow us to run queries if it has limit in it so trying to see if I can rewrite it differently in sql redshift?

Below is my full query where I am using my 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

How can I rewrite my dates CTE query differently so that it can give me same output?

Update

If I run query like this it gives me an error but if I run innermost sql query inside from then it gives me data.

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;

Error is:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use window functions:

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;

In Redshift, the ORDER BY is optional for ROW_NUMBER(). In general, I would encourage you to have an ORDER BY. That is true of your query as well. LIMIT is normally used with an ORDER BY.

EDIT:

The idea is the same:

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;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...