sqlite 如何将这些查询嵌套在一个替换查询中?

yhxst69z  于 2022-11-15  发布在  SQLite
关注(0)|答案(1)|浏览(312)

我有三个查询和另一个名为output_table的表。此代码可以工作,但需要在1.REPLACE INTO查询中执行。我知道这涉及嵌套查询和子查询,但我不知道这是否可能,因为我的键是来自target_currencyDISTINCT硬币数据点。
如何重写2和3,以便它们在查询1中执行?也就是说,REPLACE INTO查询而不是单个的UPDATE查询:

1. conn3.cursor().execute(
    """REPLACE INTO coin_best_returns(coin) SELECT DISTINCT target_currency FROM output_table"""
)

2. conn3.cursor().execute(
    """UPDATE coin_best_returns SET
    highest_price = (SELECT MAX(ask_price_usd) FROM output_table WHERE coin_best_returns.coin = output_table.target_currency),
    lowest_price = (SELECT MIN(bid_price_usd) FROM output_table WHERE coin_best_returns.coin = output_table.target_currency)"""
)

3. conn3.cursor().execute(
    """UPDATE coin_best_returns SET
        highest_market = (SELECT exchange FROM output_table WHERE coin_best_returns.highest_price = output_table.ask_price_usd),
        lowest_market = (SELECT exchange FROM output_table WHERE coin_best_returns.lowest_price = output_table.bid_price_usd)"""
)
ee7vknir

ee7vknir1#

您可以借助一些窗口函数、子查询和内部联接来完成此操作。下面的版本相当长,但它并不像看起来那么复杂。它使用子查询中的窗口函数来计算所需的每种货币的统计信息,并将其分解到一个公共表表达式中,以便于将其与自身联接。
除了内联注解,复杂的主要原因是原始查询3。查询(1)和(2)可以很容易地组合为一个简单的聚合查询,但第三个查询就不那么容易处理了。为了保持exchange数据与相应的要价和出价相关联,该查询使用窗口函数而不是聚合查询。这还提供了一种不同于DISTINCT的工具,用于每种货币获得一个结果。
以下是最简单的查询:

WITH output_stats AS (
    -- The ask and bid information for every row of output_table, every row
    -- augmented by the needed maximum ask and minimum bid statistics
    SELECT
      target_currency as tc,
      ask_price_usd as ask,
      bid_price_usd as bid,
      exchange as market,
      MAX(ask_price_usd) OVER (PARTITION BY target_currency) as high,
      ROW_NUMBER() OVER (
        PARTITION_BY target_currency, ask_price_usd ORDER BY exchange DESC)
        as ask_rank
      MIN(bid_price_usd) OVER (PARTITION BY target_currency) as low,
      ROW_NUMBER() OVER (
        PARTITION_BY target_currency, bid_price_usd ORDER BY exchange ASC)
        as bid_rank
    FROM output_table
  )
REPLACE INTO coin_best_returns(
  -- you must, of course, include all the columns you want to fill in the
  -- upsert column list
  coin,
  highest_price,
  lowest_price,
  highest_market,
  lowest_market)
SELECT
  -- ... and select a value for each column
  asks.tc,
  asks.ask,
  bids.bid,
  asks.market,
  bids.market
FROM output_stats asks
  JOIN output_stats bids
    ON asks.tc = bids.tc
WHERE
  -- These conditions choose exactly one asks row and one bids row
  -- for each currency
  asks.ask = asks.high
  AND asks.ask_rank = 1
  AND bids.bid = bids.low
  AND bids.bid_rank = 1

请注意,与原始查询3不同,在目标表中设置highest_marketlowest_market列时,它将只考虑与目标货币相关联的exchange值。我认为这是你真正想要的,但如果不是,那么就需要一个不同的战略。

相关问题