我有以下SQL Server 2008表:
CREATE TABLE tbl (ID INT, dtIn DATETIME2, dtOut DATETIME2, Type INT, nID INT)
INSERT tbl VALUES
(1, '05:00', '10:00', 1, 1), --will be changed
(2, '08:00', '16:00', 2, 1),
(3, '02:00', '08:00', 1, 1), --will be changed
(4, '07:30', '11:00', 1, 1)
我使用以下SQL来更新部分重叠的记录:
UPDATE tbl
SET dtOut = COALESCE((
SELECT MIN(dtIn)
FROM tbl as t2
WHERE t2.type = tbl.type AND
t2.id <> tbl.id AND
t2.dtIn >= tbl.dtIn AND t2.dtIn < tbl.dtOut
), dtOut)
WHERE nID=1;
SELECT ROWCOUNT_BIG();
使用最后一个SELECT我想要检索更新的记录数,但它不起作用。
所以我的问题是,如何重写此语句以获取实际更新的记录数? (上面的数据表中有2个。)
答案 0 :(得分:2)
SQL Server将更新原始示例中的所有行。这样的事情怎么样:
WITH CTE AS (
SELECT t1.ID, MIN(t2.dtIn) as New_dtOut
FROM tbl as t1
LEFT JOIN tbl AS t2 ON t2.type = t1.type AND t2.id <> t1.id
AND t2.dtIn >= t1.dtIn AND t2.dtIn < t1.dtOut
WHERE t1.nID = 1
GROUP BY t1.ID
)
UPDATE t1 SET dtOut = t2.New_dtOut
FROM tbl t1
JOIN CTE t2 on t2.ID = t1.ID
WHERE t1.dtOut <> t2.New_dtOut
SELECT ROWCOUNT_BIG();
答案 1 :(得分:2)
1。
只需在最后SELECT
UPDATE tbl
SET dtOut = COALESCE((
SELECT MIN(dtIn)
FROM tbl as t2
WHERE t2.type = tbl.type AND
t2.id <> tbl.id AND
t2.dtIn >= tbl.dtIn AND t2.dtIn < tbl.dtOut
), dtOut)
WHERE nID=1
SELECT @@ROWCOUNT;
...它现在返回一些东西 - 4 - 这是因为UPDATE正在所有行上运行,而不是仅仅需要2行。
2。 越来越近 - 以下仅对类型1的3行进行操作:
update x
set x.dtout = y.mn
from tbl x
inner join
(
SELECT t1.type, min(t1.dtIn) mn
FROM tbl t1
inner join tbl t2
on
t1.type = t2.type AND
t1.id <> t2.id AND
t1.dtIn >= t2.dtIn AND
t1.dtIn < t2.dtOut
group by t1.type
) y
on
x.type = y.type
SELECT @@ROWCOUNT;
HERE IS THE SQL FIDDLE OF THE ABOVE
3。 感谢@Gilm,我已经想到了我希望可以做到的事情;它与Gilm的CTE答案中使用的逻辑非常相似:
update x
set x.dtout = y.mn
from tbl x
inner join
(
SELECT t1.id, min(t2.dtIn) mn
FROM tbl t1
inner join tbl t2
on
t1.type = t2.type AND
t1.id <> t2.id AND
t2.dtIn >= t1.dtIn AND
t2.dtIn < t1.dtOut
group by t1.id
) y
on
x.id = y.id
SELECT @@ROWCOUNT;
SELECT * FROM tbl;
答案 2 :(得分:2)
WHERE nID=1
决定将更新多少行。即使您为自己指定dtOut
的行也会更新并计算在内。
您可以使用output子句捕获表变量中的更新行,然后计算dtOut
已更改的行。
DECLARE @T TABLE
(
dtOutOld DATETIME2,
dtOutNew DATETIME2
)
UPDATE tbl
SET dtOut = COALESCE((
SELECT MIN(dtIn)
FROM tbl as t2
WHERE t2.type = tbl.type AND
t2.id <> tbl.id AND
t2.dtIn >= tbl.dtIn AND t2.dtIn < tbl.dtOut
), dtOut)
OUTPUT deleted.dtOut, inserted.dtOut INTO @T
WHERE nID=1
SELECT COUNT(*)
FROM @T
WHERE dtOutOld <> dtOutNew