简体   繁体   中英

BigQuery - How to Avoid correlated subqueries error?

I'm trying to run a query that works on my database, but not on Bigquery, I get this error.

Correlated subqueries that reference other tables are not supported unless they can be de-correlated, such as by transforming them into an efficient JOIN.

I have a table with historical prices of Bitcoin for each minute (timestamp and price) and another table with timestamp, block number and a empty column with price and I try to assign a price to each block, since the seconds appear in the blocks, I try to assign the price closest to that minute.

here goes my code

UPDATE bitcoin_data.bloques SET price_usd = 
    (
        SELECT close AS price_usd_final 
        FROM 
            (
                (SELECT timestamp, close FROM bitcoin_data.Precio AS precio WHERE timestamp >= bloques.timestamp ORDER BY timestamp LIMIT 1) 
                UNION ALL
                (SELECT timestamp, close FROM bitcoin_data.Precio AS precio WHERE timestamp <  bloques.timestamp  ORDER BY timestamp DESC LIMIT 1)
            ) AS prices 
        ORDER BY ABS(EXTRACT(DAY FROM bloques.timestamp - timestamp))
    ) 
WHERE price_usd IS NULL

You may use below approach to match the price from another table to the blocks based on the closest timestamp between your 2 tables.

WITH `project.dataset.bloques` AS (
  SELECT TIMESTAMP '2019-07-01 08:45:09' bloques_timestamp, 'A' bloques UNION ALL
  SELECT '2019-07-01 09:15:15', 'B' UNION ALL
  SELECT '2019-07-01 10:30:29', 'C' 
), `project.dataset.precio` AS (
  SELECT TIMESTAMP '2019-07-01 08:45:35' precio_timestamp, '1000' precio UNION ALL
  SELECT '2019-07-01 09:15:45', '4000' UNION ALL
  SELECT '2019-07-01 10:30:01', '5000' 
)
SELECT * FROM (
  SELECT IF(
    ts - LAST_VALUE(ts IGNORE NULLS) OVER(prev_win) < FIRST_VALUE(ts IGNORE NULLS) OVER(next_win) - ts, 
    LAST_VALUE(bloques_timestamp IGNORE NULLS) OVER(prev_win), FIRST_VALUE(bloques_timestamp IGNORE NULLS) OVER(next_win)
    ) bloques_timestamp, IF(
    ts - LAST_VALUE(ts IGNORE NULLS) OVER(prev_win) < FIRST_VALUE(ts IGNORE NULLS) OVER(next_win) - ts, 
    LAST_VALUE(bloques IGNORE NULLS) OVER(prev_win), FIRST_VALUE(bloques IGNORE NULLS) OVER(next_win)
    ) bloques, precio 
  FROM (
    SELECT bloques_timestamp, UNIX_SECONDS(bloques_timestamp) ts, bloques, '' precio FROM `project.dataset.bloques` 
    UNION ALL
    SELECT precio_timestamp, UNIX_SECONDS(precio_timestamp), NULL, precio FROM `project.dataset.precio` 
  )
  WINDOW 
    prev_win AS (ORDER BY bloques_timestamp ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING),
    next_win AS (ORDER BY bloques_timestamp ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)
)
WHERE precio != ''  

However, you are encountering the error because according to this documentation ,

FROM clause aliases are not visible to subqueries in the same FROM clause. Subqueries in a FROM clause cannot contain correlated references to other tables in the same FROM clause.

As a suggestion, you may use WITH inside your subquery to avoid correlated subqueries error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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