需要备用SQL

时间:2016-12-06 14:47:09

标签: sql h2

我目前正在使用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中移除与famidparamid相同组合的行作为子查询

修改:为了澄清,子查询专门尝试查找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=1paramid=4的条目,即使宏0(又名“foo”)没有paramid=4的条目。如果我们扩展它,可能会有另一个famid=1paramid=4,但我们无法确定。我想根据allowedParam_map表中的数据从macrodata表中剔除任何未使用的参数。

2 个答案:

答案 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)

INNOT IN始终可以替换为EXISTSNOT EXISTS

首先要点:

  • 您在子查询中使用了ORDER BY,这当然是多余的。
  • 你在外面加入一张桌子,在要求存在时应该没有效果。因此,您需要在外连接表中查找字段,然后在内连接或不连接,然后从查询中删除它。 (无论如何,加入每个不相关的记录(macros.id != macrodata.macroid)都很奇怪。

您在评论部分说famidparamid都位于表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
);