使用select on条件更新行,否则插入新行

时间:2018-03-07 16:51:21

标签: sql-server tsql upsert

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

目前,我已写过

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中的新数据简单地更新我的行。

2 个答案:

答案 0 :(得分:0)

对此的答案因SQL方言而异,但两种主要方法是:
1. Upsert(如果您的DBMS支持它),例如在SQL Server中使用MERGE语句 2.将SQL基于IF:

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

答案 1 :(得分:0)

不确定您使用的是哪种RDBMS,但在SQL Server中,这样的内容会更新#output表,其中包含您放在SELECT部分中的ELSE的结果:< / p>

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

此外,我认为您想在INSERT部分中执行ELSE,但您只是SELECT,所以我猜你也应该解决这个问题