T-SQL NOT IN 有效,但 NOT EXISTS 不
T-SQL NOT IN works, but NOT EXISTS does not
随着新记录添加到 table,我需要将 'level' 的旧记录标记为旧记录。我可以使用 NOT IN 来做到这一点,但 NOT EXISTS 不起作用。我怀疑它与子查询相关性有关,如下所述:
NOT EXISTS query doesn't work on Informix while same query with NOT IN works
但我不明白为什么 & 可以使用进一步的解释。下面是一些示例代码:
CREATE TABLE t2 (id INT, level INT, someDate datetime, mostRecent int)
GO
INSERT INTO t2
SELECT 1, 1, '1/1/2010', 1 UNION ALL
SELECT 2, 1, '2/2/2010', 1 UNION ALL
SELECT 3, 2, '3/3/2010', 1 UNION ALL
SELECT 4, 3, '4/4/2010', 1 UNION ALL
SELECT 5, 3, '5/5/2010', 1 UNION ALL
SELECT 6, 3, '6/6/2010', 1 UNION ALL
SELECT 7, 4, '7/7/2010', 1 UNION ALL
SELECT 8, 5, '8/8/2010', 1 UNION ALL
SELECT 9, 6, '9/9/2010', 1 UNION ALL
SELECT 10, 6, '10/10/2010', 1 UNION ALL
SELECT 11, 8, '11/11/2012', 1
GO
-- this doesn't work
UPDATE t2 SET mostRecent = 0
FROM t2
WHERE NOT EXISTS
(SELECT * FROM t2
JOIN
(SELECT level, max(someDate) as someDate FROM t2 group by level) as maxrows
ON t2.someDate = maxrows.someDate)
GO
-- this works
UPDATE t2 SET mostRecent = 0
FROM t2
WHERE id NOT IN
(SELECT t2.id FROM t2
JOIN
(SELECT level, max(someDate) as someDate FROM t2 group by level) as maxrows
ON t2.someDate = maxrows.someDate)
你的查询有误,应该是:
UPDATE T SET mostRecent = 0
FROM t2 as T
WHERE NOT EXISTS
(SELECT * FROM
(SELECT level, max(someDate) as someDate FROM t2 group by level) as maxrows
WHERE T.someDate = maxrows.someDate)
我在 table 中添加了别名以保持清晰
在您的原始查询中,您没有将 NOT EXISTS
查询中的任何内容链接到您的 UPDATE
语句,因此它总是 return 结果,并且它将 "exist" 对于 table 中的每条记录进行更新。
您可以将整个查询重写为这样以获得更好的性能,Joao 的脚本应该已经修复了您描述的错误:
;WITH CTE as
(
SELECT
mostrecent,
row_number() over (partition by level order by somedate desc) rn
FROM t2
)
UPDATE CTE
SET
mostrecent = 0
WHERE
mostrecent = 1
and rn > 1
随着新记录添加到 table,我需要将 'level' 的旧记录标记为旧记录。我可以使用 NOT IN 来做到这一点,但 NOT EXISTS 不起作用。我怀疑它与子查询相关性有关,如下所述: NOT EXISTS query doesn't work on Informix while same query with NOT IN works 但我不明白为什么 & 可以使用进一步的解释。下面是一些示例代码:
CREATE TABLE t2 (id INT, level INT, someDate datetime, mostRecent int)
GO
INSERT INTO t2
SELECT 1, 1, '1/1/2010', 1 UNION ALL
SELECT 2, 1, '2/2/2010', 1 UNION ALL
SELECT 3, 2, '3/3/2010', 1 UNION ALL
SELECT 4, 3, '4/4/2010', 1 UNION ALL
SELECT 5, 3, '5/5/2010', 1 UNION ALL
SELECT 6, 3, '6/6/2010', 1 UNION ALL
SELECT 7, 4, '7/7/2010', 1 UNION ALL
SELECT 8, 5, '8/8/2010', 1 UNION ALL
SELECT 9, 6, '9/9/2010', 1 UNION ALL
SELECT 10, 6, '10/10/2010', 1 UNION ALL
SELECT 11, 8, '11/11/2012', 1
GO
-- this doesn't work
UPDATE t2 SET mostRecent = 0
FROM t2
WHERE NOT EXISTS
(SELECT * FROM t2
JOIN
(SELECT level, max(someDate) as someDate FROM t2 group by level) as maxrows
ON t2.someDate = maxrows.someDate)
GO
-- this works
UPDATE t2 SET mostRecent = 0
FROM t2
WHERE id NOT IN
(SELECT t2.id FROM t2
JOIN
(SELECT level, max(someDate) as someDate FROM t2 group by level) as maxrows
ON t2.someDate = maxrows.someDate)
你的查询有误,应该是:
UPDATE T SET mostRecent = 0
FROM t2 as T
WHERE NOT EXISTS
(SELECT * FROM
(SELECT level, max(someDate) as someDate FROM t2 group by level) as maxrows
WHERE T.someDate = maxrows.someDate)
我在 table 中添加了别名以保持清晰
在您的原始查询中,您没有将 NOT EXISTS
查询中的任何内容链接到您的 UPDATE
语句,因此它总是 return 结果,并且它将 "exist" 对于 table 中的每条记录进行更新。
您可以将整个查询重写为这样以获得更好的性能,Joao 的脚本应该已经修复了您描述的错误:
;WITH CTE as
(
SELECT
mostrecent,
row_number() over (partition by level order by somedate desc) rn
FROM t2
)
UPDATE CTE
SET
mostrecent = 0
WHERE
mostrecent = 1
and rn > 1