根据条件使用 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
,所以我想你也应该修复它
我需要 运行 每天计算一个月。如果月份期间已经存在,我需要更新它,否则我需要为新月份创建一个新行。
目前,我写了
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
,所以我想你也应该修复它