【发布时间】:2016-11-16 17:00:27
【问题描述】:
我有一个存储过程,如果它们不存在,我正在运行它来插入值,如果存在则更新。我有一个数据来自的表
Table1
Name (nvarchar)
Data (int)
Timestamp (datetime)
数据是这样的
Name1 5 2016-11-16 09:46:40.490
Name2 10 2016-11-16 09:48:35.240
Name1 7 2016-11-16 09:35:24.350
Name2 8 2016-11-15 02:27:44.670
我正在尝试将名称插入到新表中,对整数进行平均,然后按天分组。这是第二张表
Table2
Name (nvarchar)
Data (int)
Timestamp (date)
数据如下所示。 Name1 是同一天,所以取平均值。 Name2 是不同的日子,所以它们不是平均的。
Name1 6 2016-11-16 00:00:00.000
Name2 10 2016-11-16 00:00:00.000
Name2 8 2016-11-15 00:00:00.000
我将时间戳转换为日期,以便在当天更容易合并。我的存储过程是这样的
IF NOT EXISTS (SELECT t.Name, t.Timestamp
FROM Table2 t
JOIN Table1 a
ON t.Name = a.Name AND t.Timestamp = CONVERT(date, a.Timestamp)
GROUP BY t.Name, t.Timestamp)
INSERT INTO Table2 (Name, Timestamp, Data)
SELECT
Name,
CAST(Timestamp AS DATE) as Date,
AVG(Data) as Average_Data
FROM Table1
GROUP BY CAST(Timestamp AS DATE), Name
ELSE
UPDATE Table1
SET
WHERE
所以我第一次运行它,没有问题。这些值已正确添加和分组。但是,第二次运行时,它总是插入。
我的更新声明在我删除之前看起来像这样
SET Name = Name, Timestamp = Timestamp, Data = Date
WHERE Name = Name, Timestamp = Timestamp
我知道这是不对的,但它似乎永远不会点击更新,因为插入总是运行。如果我在 If Not Exists 中运行 Select,我会看到数据并且它应该认为它存在。
我想我需要帮助清理 If Not Exists 并创建有效的更新语句。
编辑:
以下更新代码
IF EXISTS(SELECT Name, Timestamp FROM Table2)
UPDATE
Table2
SET
Name = a.Name,
Timestamp = CONVERT(date, a.Timestamp),
Data = AVG(a.Data)
FROM
Table2 t
INNER JOIN
Table1 a
ON t.Name = a.Name
WHERE t.Name = a.Name AND t.Timestamp = CONVERT(date, a.Timestamp)
ELSE
INSERT INTO Table2 (Name, Timestamp, Data)
SELECT
Name,
CAST(Timestamp AS DATE) as Date,
AVG(Data) as Average_Data
FROM Table1
GROUP BY CAST(Timestamp AS DATE), Name
END
【问题讨论】:
-
你的逻辑是全有或全无,这不是你想要的。您需要先进行更新,无需检查行是否存在。如果他们不更新将不会更新他们。然后你想改变你的插入语句以使用一个不存在的地方。
-
谢谢。我会试一试
-
所以我将更新更改为先运行,看起来它仍然每次都插入值。这可能是我的时间戳的问题吗?我正在将其转换为日期,但我想知道它是否在转换之前对其进行检查?
-
新代码在哪里? FWIW,您应该考虑不使用名为 timestamp 的列。它是 sql server 中的一种数据类型,与日期或时间无关。老实说,无论如何,这个名字对我来说太模棱两可了。这是什么意思?时间创造?时间编辑?其他相关时间? DateCreated 或类似名称是更好的命名约定。明确说出你的名字。
-
您更新的代码仍然是全有或全无的方法。你不能在这里使用 If 语句,因为你想更新一些行并插入一些行。
标签: sql sql-server tsql stored-procedures