INSERT和WHERE NOT EXISTS的奇怪SQL行为

时间:2011-06-10 15:59:27

标签: sql insert

我有这个查询,如果表格中不存在相同ID的金额等于或高于此金额,则应插入金额。

我在MySQL 5.1和MSSQL 2k5下试过这个:

的MySQL

INSERT IGNORE INTO test(id,amount) SELECT 6,50 FROM测试 什么不存在(选择1来自测试WHERE数量> = 50 AND id = 6)LIMIT 1

MSSQL

INSERT INTO test(id,amount) SELECT 6,50 FROM测试 什么不存在(选择TOP 1 1 FROM测试WHERE数量> = 50 AND id = 6)

如果表中至少有一个条目,则此查询可以正常工作。如果表是空的,它将永远不会工作。这与MySQL(5.1)和MSSQL(2005)下的行为相同。 我不明白为什么。即使表格完全为空,任何人都有解释和修复此查询的方法吗?

编辑:我主要需要MySQL;

更新:我专门为MySQL启动了一个新问题: MySQL Problem with inserting a row with certain conditions

4 个答案:

答案 0 :(得分:2)

它失败,因为select语句根据返回的行数选择值6和50。由于您的表是空的 - 没有返回任何行来获得这些值。

将其修改为

 INSERT INTO test (id, amount) SELECT 6, 50 WHERE NOT EXISTS (SELECT TOP 1 1 FROM test WHERE amount >= 50 AND id = 6) 

答案 1 :(得分:0)

按如下方式更改您的查询:

INSERT INTO test (id, amount) 
SELECT 6, 50 FROM test 
WHERE (SELECT count(*) FROM test WHERE amount >= 50 AND id = 6) = 0 

答案 2 :(得分:0)

我一步一步地尝试了这个:

    -- create a test-table with one entry
SELECT id = 1, amount = 50 
into #TEST

-- see if statement works when table is not empty
INSERT INTO #test (id, amount)  
SELECT id = 6, amount = 50 
FROM #test  
WHERE NOT EXISTS (SELECT * FROM #test WHERE amount >= 50 AND id = 6) 

-- show content of test-table
select * from #test

-- empty the test table
truncate table #test

-- try to insert a first dataentry
INSERT INTO #test (id, amount)  
SELECT id = 6, amount = 50 
FROM #test  
WHERE NOT EXISTS (SELECT * FROM #test WHERE amount >= 50 AND id = 6) 
union
SELECT id = 6, amount = 50 
where (SELECT C = COUNT(*)  FROM #test WHERE amount >= 50 AND id = 6) = 0

-- show content of test-table
select * from #test

-- remove Test-table
drop table #test

首先我尝试重现这种行为,是的,这很奇怪。工会 - 想想管理空表案件,并且这很好。

答案 3 :(得分:0)

好吧,那是真正的问题。试试这个,使用第二个表(#test2):

    -- create a test-table with one entry
SELECT id = 1, amount = 50 
into #TEST

-- create a second test-table with one entry
SELECT id = 1, amount = 50 
into #TEST2

-- see if statement works when table is not empty
INSERT INTO #test (id, amount)  
SELECT id = 6, amount = 50 
FROM #test  
WHERE NOT EXISTS (SELECT * FROM #test WHERE amount >= 50 AND id = 6) 

-- show content of test-table
select * from #test

-- empty the test table
truncate table #test

INSERT INTO #test (id, amount) SELECT 6, 50 WHERE NOT EXISTS (SELECT TOP 1 1 FROM #test WHERE amount >= 50 AND id = 6)  

-- try to insert a first dataentry
INSERT INTO #test (id, amount)  
SELECT id = 6, amount = 50 
FROM #test  
WHERE NOT EXISTS (SELECT * FROM #test WHERE amount >= 50 AND id = 6) 
union
SELECT id = 6, amount = 50 
from #test2
where (SELECT C = COUNT(*)  FROM #test) = 0


-- show content of test-table
select * from #test

-- remove Test-table
drop table #test

(假设您知道前面带有#的表,这是MS-SQL中的临时表。)

BonyT已经解释了原因。