根据条件使用 select 中的值更新行,否则插入新行

Update row with values from select on condition, else insert new row

我需要 运行 每天计算一个月。如果月份期间已经存在,我需要更新它,否则我需要为新月份创建一个新行。

目前,我写了

declare @period varchar(4) = '0218'
DECLARE @Timestamp date = GetDate()

IF EXISTS(select * from #output where period=@period)
  /* UPDATE #output SET  --- same calculation as below ---*/
ELSE
   SELECT
    @period AS period,
    SUM(timecard.tworkdol) AS dol_local,
    SUM(timecard.tworkdol/currates.cdrate) AS dol_USD,
    SUM(timecard.tworkhrs) AS hrs,
    @Timestamp AS timestamp
FROM dbo.timecard AS timecard
    INNER JOIN dbo.timekeep ON timecard.ttk = timekeep.tkinit
    INNER JOIN dbo.matter with (nolock) on timecard.tmatter = matter.mmatter
    LEFT JOIN dbo.currates with (nolock) on matter.mcurrency = currates.curcode 
        AND currates.trtype = 'A' 
        AND timecard.tworkdt BETWEEN currates.cddate1 
        AND currates.cddate2
WHERE   timekeep.tkloc IN('06','07') AND
    timecard.twoper = @period

SELECT * FROM #output;

如何使用 select 中的新数据简单地更新我的行。

这个问题的答案因 SQL 方言而异,但两种主要方法是:
1. Upsert(如果您的 DBMS 支持),例如在 SQL 服务器中使用 MERGE 语句。
2. 将你的 SQL 基于 IF:

IF NOT EXISTS (criteria for dupes)
 INSERT INTO (logic to insert)
ELSE
 UPDATE (logic to update)

不确定您使用的是什么 RDBMS,但是在 SQL 服务器中,类似这样的东西会使用您放置的 SELECT 的结果更新 #output table在 ELSE 部分:

UPDATE o
    SET o.dol_local = SUM(timecard.tworkdol),
    SET o.dol_USD = SUM(timecard.tworkdol/currates.cdrate),
    SET o.hrs = SUM(timecard.tworkhrs),
    set o.timestamp = @Timestamp
FROM #output o
INNER JOIN dbo.timecard AS timecard ON o.period = timecard.twoper
INNER JOIN dbo.timekeep ON timecard.ttk = timekeep.tkinit
INNER JOIN dbo.matter with (nolock) on timecard.tmatter = matter.mmatter
LEFT JOIN dbo.currates with (nolock) on matter.mcurrency = currates.curcode 
        AND currates.trtype = 'A' 
        AND timecard.tworkdt BETWEEN currates.cddate1 
        AND currates.cddate2
WHERE   timekeep.tkloc IN('06','07') AND
    timecard.twoper = @period

此外,我想你想在 ELSE 部分做一个 INSERT,但你只做了一个 SELECT,所以我想你也应该修复它