【问题标题】:Replace or update table while using a with clause使用 with 子句时替换或更新表
【发布时间】:2023-02-23 23:10:50
【问题描述】:

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

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)

这非常有效,但不确定如何使用此语句更新我的 currency_converter 表?

关于如何解决这个问题的任何建议?

我试过使用 INSERT INTO,但似乎无法正常工作。这也需要我截断我的 currency_converter 表,这似乎是不必要的。我也无法使这种语法起作用。尝试在我的 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)
)

也许可以使用 upsert 或临时表来解决这个问题? 只是不确定如何应用它。

【问题讨论】:

  • 只需将您的选择包装在子查询中并从中选择,例如: with currency AS (...) insert into currency_converter (time_period, obs_value, valuta) select * from ( SELECT c.day as time_period, t.obs_value, t. valuta 来自 dim_calendar c...) x
  • 写:更新......从Cte
  • 您要更新哪一列的值?
  • 您的查询语法不正确,请参阅下面的答案。我通过插入特定列来补充答案(参见第二个示例“插入”),尝试根据示例自己重写查询。

标签: sql-server upsert with-statement


【解决方案1】:

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

但是如果我理解正确的话——你想使用 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:也将 WITH 用于 MERGE 语句

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.*
;

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

【讨论】:

    猜你喜欢
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 2017-04-21
    • 1970-01-01
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    • 2019-01-15
    相关资源
    最近更新 更多