使用 with 子句时替换或更新表

问题描述 投票:0回答:2

我有一个货币换算表,我在周末缺少日期。使用此查询通过将 Fridays 值添加到接下来的周六和周日来解决此问题。我创建了这个查询,它返回我想成为我的表 新的 currency_converter 表。如何将其另存为 currency_converter_new? 我的桌子现在看起来像这样:

currency_converter:

时间_周期 obs_value 货币
20.02.2023 10,9683 欧元
20.02.2023 147,3 丹麦克朗
17.02.2023 11,015 欧元
17.02.2023 147,92 丹麦克朗

这是我希望在我的其他表中的输出。 currency_converter_new:

时间_周期 obs_value 货币
20.02.2023 10,9683 欧元
20.02.2023 147,3 丹麦克朗
19.02.2023 11,015 欧元
19.02.2023 147,92 丹麦克朗
18.02.2023 11,015 欧元
18.02.2023 147,92 丹麦克朗
17.02.2023 11,015 欧元
17.02.2023 147,92 丹麦克朗

使用下面的语句,我能够实现我想要的,但不确定如何用它来替换我的 currency_converter_new 表。

with currency AS
(SELECT *, LEAD(time_period) OVER (PARTITION BY valuta ORDER BY time_period) as next_time_period
  FROM currency_converter
  )
 SELECT c.day as time_period, t.obs_value, t.valuta
 FROM dim_calendar c
 JOIN currency t
 ON c.day BETWEEN t.time_period and ISNULL(DATEADD(day, -1, t.next_time_period), t.time_period)

关于如何解决这个问题有什么建议吗?

我试过使用 INSERT INTO,但似乎无法正常工作。我也无法使这种语法起作用。尝试像这样在我的 SELECT 之前添加 INSERT INTO:

with currency AS
(SELECT *, LEAD(time_period) OVER (PARTITION BY valuta ORDER BY 
time_period) as next_time_period
FROM currency_converter
);
INSERT INTO (currency_converter(time_period, obs_value, valuta)
SELECT * FROM ( 
SELECT c.day as time_period, t.obs_value, t.valuta
FROM dim_calendar c
JOIN currency t
ON c.day BETWEEN t.time_period and ISNULL(DATEADD(day, -1, 
t.next_time_period), t.time_period)
)

我会在运行之前截断我的 currency_converter_new 表。

sql-server sql-insert with-statement
2个回答
0
投票

老实说,不清楚你想展示什么,因为这是某种没有上下文的撕毁请求。

但是如果我理解正确的话——你想使用 WITH 表达式从查询中插入或更新吗?

请看下面的例子:

DROP TABLE IF EXISTS #tt;

CREATE TABLE #tt (dt DATETIME);

-- inserting into a table from a 'SELECT' with the expression 'WITH'
WITH t AS (SELECT getdate() dt)
INSERT INTO #tt
SELECT * FROM t;

-- to insert specific columns, you can write like this
WITH t AS (SELECT getdate() dt)
INSERT INTO #tt (dt)
SELECT dt FROM t;

SELECT * FROM #tt;

-- update the table with FROM, JOIN and with the expression 'WITH'
WITH t AS (SELECT getdate() dt)
UPDATE #tt
  SET dt = DATEADD(millisecond,100,t.dt)
  FROM #tt, t

SELECT * FROM #tt;

WITH t AS (SELECT getdate() dt)
UPDATE #tt
  SET dt = DATEADD(millisecond,200,t.dt)
  FROM #tt
  JOIN t ON 1=1

SELECT * FROM #tt;

DROP TABLE IF EXISTS #tt;

PS:这里以临时表为例,你用你的表用你的查询,我给你展示了如何在表插入和更新操作中使用WITH表达式。

PPS: MERGE 语句也使用 WITH

WITH table_3 AS (
  SELECT ...
)
MERGE table t
  USING (
    SELECT
        *
      FROM table_2
      JOIN table_3 ON <join condition>
      WHERE <where condition>
  ) tt
  ON <join condition for "merging" table and query>
  WHEN MATCHED [AND <addition condition>]
    THEN DELETE
  WHEN MATCHED [AND <addition condition>]
    THEN UPDATE
      SET
        t.columns = tt.columns
        ...
  WHEN NOT MATCHED
    THEN INSERT
        (...)
      VALUES
        (tt.columns, ...)
  OUTPUT
     $action,
     inserted.*,
     deleted.*
;

对于更详细的解决方案,您需要在中描述您的问题 详细信息和数据示例


0
投票

就像在 with 子句之前添加一个 INSERT INTO 语句一样简单。

    INSERT INTO currency_converter_new(time_period, obs_value, valuta)
with currency AS
(
SELECT *, LEAD(time_period) OVER (PARTITION BY valuta ORDER BY time_period) as next_time_period
  FROM currency_converter
  )
 SELECT c.day as time_period, t.obs_value, t.valuta
 FROM dim_calendar c
 JOIN currency t
 ON c.day BETWEEN t.time_period and ISNULL(DATEADD(day, -1, t.next_time_period), t.time_period)
© www.soinside.com 2019 - 2024. All rights reserved.