[英]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.