简体   繁体   English

Window function 不允许出现在 where 子句中 redshift

[英]Window function is not allowed in where clause redshift

I have a dates CTE in my below query where I am using limit clause which I don't want to use it.我在下面的查询中有一个dates CTE,我在其中使用了我不想使用的limit子句。 I am trying to understand on how to rewrite my dates CTE so that I can avoid using limit 8 query.我试图了解如何重写我的dates CTE,以便我可以避免使用limit 8查询。

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

Below is the output I get from my inner dates CTE query:下面是我从内部dates CTE 查询中得到的 output:

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

Output from dates CTE: Output 来自 CTE dates

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 CTE query and still get same output?有什么方法可以避免在我的 CTE 查询中使用limit 8并仍然得到相同的 output? Our platform doesn't allow us to run queries if it has limit clause in it so trying to see if I can rewrite it differently in sql redshift?如果我们的平台中有limit子句,我们的平台不允许我们运行查询,所以我想看看我是否可以在 sql redshift 中以不同的方式重写它?

If I modify my dates CTE query like this, then it gives me error as window function is not allowed in where clause .如果我像这样修改dates CTE 查询,则会出现错误,因为window function is not allowed in where clause

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,
    ROW_NUMBER() OVER () as seqnum
    FROM dimensions.customer
    WHERE seqnum <= 8;
)
....

Update更新

Something like this you mean?你的意思是这样的?

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,
    ROW_NUMBER() OVER () as seqnum
    FROM dimensions.customer
)
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 dates.seqnum <= 8 
AND features.type = 'capacity'
AND features.status = 'CURRENT'
GROUP BY dates.week_column
ORDER by dates.week_column DESC

Just move your WHERE clause to the outer SELECT. Seqnum doesn't exists until the CTE runs but does exist when the result of the CTE is consumed.只需将您的 WHERE 子句移动到外部 SELECT。Seqnum 在 CTE 运行之前不存在,但在使用 CTE 的结果时确实存在。

UPDATE...更新...

After moving the where clause AndyP got a correlated subquery error coming from a WHERE clause not included in the posted query.移动 where 子句后,AndyP 得到一个相关的子查询错误,该错误来自未包含在发布的查询中的 WHERE 子句。 As shown in this somewhat modified query:如这个稍微修改过的查询所示:

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_of
  FROM (SELECT 1 AS X UNION ALL SELECT 1 AS X UNION ALL SELECT 1 AS X UNION ALL SELECT 1 AS X UNION ALL SELECT 1 AS X UNION ALL SELECT 1 AS X UNION ALL SELECT 1 AS X UNION ALL SELECT 1 AS X)
)
SELECT dates.week_of,
       'W' || CEILING(DATE_PART('week',dates.week_of +INTERVAL '1 day')) AS week_number,
       COUNT(DISTINCT features.id) AS total
FROM dimensions.program features
  JOIN dates ON features.last_update <= dates.week_of
WHERE features.version = (SELECT MAX(version)
                                  FROM headers f2
                                  WHERE features.id = f2.id
                                  AND   features.type = f2.type
                                  AND   f2.last_update <= dates.week_of)
AND   features.type = 'type'
AND   features.status = 'live'
GROUP BY dates.week_of
ORDER BY dates.week_of DESC;

This was an interesting replacement of a correlated query with a join due to the inequality in the correlated sub query.由于相关子查询中的不平等,这是一个有趣的用连接替换相关查询的方法。 We thought others might be helped by posting the final solution.我们认为发布最终解决方案可能会对其他人有所帮助。 This works:这有效:

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_of
  FROM (SELECT 1 AS X UNION ALL SELECT 1 AS X UNION ALL SELECT 1 AS X UNION ALL SELECT 1 AS X UNION ALL SELECT 1 AS X UNION ALL SELECT 1 AS X UNION ALL SELECT 1 AS X UNION ALL SELECT 1 AS X)
)
SELECT dates.week_of,
       'W' || CEILING(DATE_PART('week',dates.week_of +INTERVAL '1 day')) AS week_number,
       COUNT(DISTINCT features.carrier_id) AS total
FROM dimensions.program features
  JOIN dates ON features.last_update <= dates.week_of
  JOIN (SELECT MAX(MAX(version)) OVER(Partition by id, type Order by dates.weeks_of rows unbounded preceding) AS feature_version,
               f2.id,
               f2.type,
               dates.week_of
        FROM dimensions.headers f2
        JOIN dates ON f2.last_update <= dates.week_of
        GROUP BY f2.id,
                 f2.type,
                 dates.week_of) f2
    ON features.id = f2.id
   AND features.type = f2.type
   AND f2.week_of = dates.week_of
   AND features.version = f2.version
WHERE features.type = 'type'
AND   features.status = 'live'
GROUP BY dates.week_of
ORDER BY dates.week_of DESC;

Needing to make a data segment that had all the possible Max(version) for all possible week_of values was the key.关键是需要制作一个数据段,使其具有所有可能的 week_of 值的所有可能的 Max(version)。 Hopefully having both of these queries posted will help other fix correlated subquery errors.希望发布这两个查询将有助于其他人修复相关的子查询错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM