以下是创建数据库的代码:
CREATE TABLE foo (
id TEXT PRIMARY KEY,
value TEXT
);
INSERT INTO foo VALUES(1, 10), (2, 20), (3, 30), (5, 50);
现在我有一组行,如果行不存在则返回0;如果行存在但不相同则返回1;如果行完全存在则返回2.
因此,(1, 11), (2, 20), (4, 40)
上的查询结果应为1, 2, 0
。
我想要的原因是知道用于将数据插入数据库的查询。如果它是0,我做一个普通插入,如果它是1我做更新,如果它是2我跳过该行。我知道INSERT OR REPLACE
将导致几乎相同的行,但问题是它不会触发正确的触发器(它将始终触发插入触发器而不是更新触发器或如果行完全存在则不触发)
另外,我想对所有行进行一次查询,而不是每行一次查询。
答案 0 :(得分:1)
这个想法是使用聚合查询。计算id匹配的次数。如果没有,则返回0
。然后检查值以区分1和2:
select (case when max(id = 1) = 0 then 0
when max(id = 1 and value = 11) = 0 then 1
else 2
end) as flag
from table t;
您需要将值插入查询。
编辑:
如果你想匹配一堆行,可以这样做:
select testvalue.id,
(case when max(t.id = testvalue.id) = 0 then 0
when max(t.id = testvalue.id and t.value = testvalue.value) = 0 then 1
else 2
end) as flag
from table t cross join
(select 1 as id 10 as value union all
select 2, 20 union all
select 4, 40
) as testvalues
group by testvalues.id;
答案 1 :(得分:1)
您可以在Transact-SQL中使用EXISTS参数。 MSDN Documentation。
如果存在行,则返回true。
然后,您可以在其中使用If语句来检查行是相同还是不同,如果为true,则使用带有指定值的RETURN参数。 MSDN Documentation
答案 2 :(得分:0)
这是基于Gordon Linoff's answer的,所以请求他。我只是想分享一下我的实际情况:
select testvalues.id,
(case when t.id != testvalues.id then 0
when t.value != testvalues.value then 1
else 2
end) as flag
from (select 1 as id, 11 as entity union all
select 2, 20 union all
select 4, 40
) as testvalues
LEFT OUTER JOIN foo t on testvalues.id=t.id
这可以防止交叉连接和group by子句的完整内存使用。