簡體   English   中英

Window function 不允許出現在 where 子句中 redshift

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

我在下面的查詢中有一個dates CTE,我在其中使用了我不想使用的limit子句。 我試圖了解如何重寫我的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

下面是我從內部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 來自 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

有什么方法可以避免在我的 CTE 查詢中使用limit 8並仍然得到相同的 output? 如果我們的平台中有limit子句,我們的平台不允許我們運行查詢,所以我想看看我是否可以在 sql redshift 中以不同的方式重寫它?

如果我像這樣修改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;
)
....

更新

你的意思是這樣的?

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

只需將您的 WHERE 子句移動到外部 SELECT。Seqnum 在 CTE 運行之前不存在,但在使用 CTE 的結果時確實存在。

更新...

移動 where 子句后,AndyP 得到一個相關的子查詢錯誤,該錯誤來自未包含在發布的查詢中的 WHERE 子句。 如這個稍微修改過的查詢所示:

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;

由於相關子查詢中的不平等,這是一個有趣的用連接替換相關查詢的方法。 我們認為發布最終解決方案可能會對其他人有所幫助。 這有效:

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;

關鍵是需要制作一個數據段,使其具有所有可能的 week_of 值的所有可能的 Max(version)。 希望發布這兩個查詢將有助於其他人修復相關的子查詢錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM