2016-12-06 66 views
1

我目前正在使用H2数据库,并且已经编写了以下SQL,但H2数据库引擎不支持在多列子查询上执行的NOT IN需要备用SQL

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删除行无论它有famidparamid作为子查询相同的组合

编辑:为了澄清,子查询是专门试图找到famid/paramidmacrodata中不存在的组合,试图清除allowedparam_map,因此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  | 

参数允许在每个家庭的基础。请注意0​​表如何包含famid=1paramid=4的条目,即使宏0(又名“foo”)没有paramid=4的条目。如果我们扩展这个,可能会有另一个famid=1宏,它有paramid=4,但我们无法确定。我想根据macrodata表中的数据从allowedParam_map表中挑选任何未使用的参数。

+0

“famid”和“paramid”在哪些表中? –

+0

@ThorstenKettner'famid'和'paramid'驻留在'macros'表 – bss36504

+0

至于编辑:“macrodata中不存在的famid/paramid组合”?如果这些列驻留在宏表中,它们如何存在或不存在于宏数据表中?您可能想要显示您的表实际包含的列。如果你甚至提供了一些样本数据和预期结果,那将是一个很大的帮助。 –

回答

2

INNOT IN总是可以用EXISTSNOT EXISTS取代。

几点第一:

  • 您正在使用您的子查询,这当然是多余的ORDER BY
  • 您正在外连接一个表格,在询问是否存在时应该没有任何影响。因此,无论您需要在外连接表中查找一个字段,然后进行内部连接,或者不连接,然后将其从查询中删除。 (它的奇怪加入每一个不相关的记录(macros.id != macrodata.macroid)反正。

您在评论部分,这两个 famidparamid驻留在表 macros说,这样可以去掉外从查询加盟 macrodata 。你得到:

正如你现在说famid在表macrosparamid是表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 
); 
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,它会达到您的预期。
+0

出于某种原因,我原来的查询根本不能用'NOT EXISTS'工作,我只是得到一个语法错误,但是回到'NOT IN'只是抱怨多列子查询。 – bss36504

+0

@ bss36504。 。 。你用适当的表名替换了'?'? –