我目前正在使用H2数据库并编写了以下SQL,但H2数据库引擎不支持在多列子查询上执行NOT IN
。
DELETE FROM AllowedParam_map
WHERE (AllowedParam_map.famid,AllowedParam_map.paramid) NOT IN (
SELECT famid,paramid
FROM macros
LEFT JOIN macrodata
ON macros.id != macrodata.macroid
ORDER BY famid)
基本上我想从allowedparam_map
中移除与famid
和paramid
相同组合的行作为子查询
修改:为了澄清,子查询专门尝试查找famid/paramid
中不存在的macrodata
组合,以便清除allowedparam_map
1}},因此ON macros.id != macrodata.macroid
。我在SQL上也很糟糕,所以这可能完全是错误的做法。
编辑2:以下是有关相关架构的更多信息:
Macros
| ID | NAME | FAMID |
| 0 | foo | 1 |
| 1 | bar | 1 |
| 2 | baz | 1 |
MacroData
| ID | MACROID | PARAMID | VALUE |
| 0 | 0 | 1 | 1024 |
| 1 | 0 | 2 | 200 |
| 2 | 0 | 3 | 89.85 |
AllowedParam_Map
| ID | FAMID | PARAMID |
| 0 | 1 | 1 |
| 1 | 1 | 2 |
| 2 | 1 | 3 |
| 3 | 1 | 4 |
每个家庭允许参数。注意allowedParam_map
表如何包含famid=1
和paramid=4
的条目,即使宏0(又名“foo”)没有paramid=4
的条目。如果我们扩展它,可能会有另一个famid=1
宏paramid=4
,但我们无法确定。我想根据allowedParam_map
表中的数据从macrodata
表中剔除任何未使用的参数。
答案 0 :(得分:2)
您可以改为使用not exists
:
DELETE FROM AllowedParam_map m
WHERE NOT EXISTS (SELECT 1
FROM macros LEFT JOIN
macrodata
ON macros.id <> macrodata.macroid -- I strongly suspect this should be =
WHERE m.famid = ?.famid and m.paramid = ?.paramid -- add the appropriate table aliases
);
注意:
<>
应为=
。 <>
在这种情况下没有意义。?
替换为相应的表别名。NOT EXISTS
优于NOT IN
。如果其中一个值为NULL
,则会执行您的预期。答案 1 :(得分:2)
IN
和NOT IN
始终可以替换为EXISTS
和NOT EXISTS
。
首先要点:
ORDER BY
,这当然是多余的。macros.id != macrodata.macroid
)都很奇怪。 您在评论部分说 famid
和paramid
都位于表macros
中,因此您可以从查询中删除外部联接到macrodata
。你得到:
正如您现在所说,famid
位于表macros
中,而paramid
位于表macrodata
中,您想要查找AllowedParam_map
中存在的对,但不是在前面提到的表中,你似乎在寻找一个简单的内部联接。
DELETE FROM AllowedParam_map
WHERE NOT EXISTS
(
SELECT *
FROM macros m
JOIN macrodata md ON md.macroid = m.id
WHERE m.famid = AllowedParam_map.famid
AND md.paramid = AllowedParam_map.paramid
);