如何从SQL中比较两个逻辑表达式的条件?

时间:2016-06-03 06:49:08

标签: java sql regex complexity-theory np

我想要两个比较两个SQL where子句来检查条件是否相似。

在下面的示例中,SQL查询在where子句中具有相同的逻辑条件。什么操作告诉我两个条款条件在逻辑上是一样的?

这是否有REGEX?还有其他方法吗?

String Q3 = "select t1.ID as ID,t1.FIELD8 as I_RECHARGE_TYPE,t1.FIELD28 as I_RECHARGE_AMOUNT,t1.FIELD1 as I_ACTIVATION_DATE,t1.FIELD2 as I_MSISDN from INSTANT_CDR_0 as t1 where t1.FIELD2 = ? and ((((t1.FIELD8 IS NOT NULL  AND  t1.FIELD28 > 0) OR  DATE_FORMAT(t1.FIELD1,'%Y-%m-%d') > '2016-05-21')) or ((DATE_FORMAT(t1.FIELD1,'%Y-%m-%d') < '2015-12-03' OR ( t1.FIELD28 > 0 AND  t1.FIELD28 < 101))))";
String Q4 = "select t1.ID as ID,t1.FIELD1 as I_ACTIVATION_DATE,t1.FIELD8 as I_RECHARGE_TYPE,t1.FIELD28 as I_RECHARGE_AMOUNT,t1.FIELD2 as I_MSISDN from INSTANT_CDR_0 as t1 where t1.FIELD2 = ? and (((DATE_FORMAT(t1.FIELD1,'%Y-%m-%d') > '2016-05-21' OR ( t1.FIELD8 IS NOT NULL  AND  t1.FIELD28 > 0))) or (((t1.FIELD28 > 0 AND  t1.FIELD28 < 101) OR  DATE_FORMAT(t1.FIELD1,'%Y-%m-%d') < '2015-12-03')))"; 

如何将((a=2) and (b=3))((b=3) and(a=2))进行比较并找出它们是相同的?

2 个答案:

答案 0 :(得分:2)

如果您拥有的所有字段都是布尔值,那么更简单的情况就是如此。所以所有逻辑表达式也都是布尔表达式。

你所拥有的将是试图找出两个布尔表达式是否相等的问题 - 也就是说,对于每个可能的输入,它们都提供相同的答案。

这样做的一种方法可能是:让A成为第一个表达式,B成为第二个表达式,A and B成为逻辑和两个表达式。对于应用于所有可能输入的两个表达式等效A and B必须为true。这意味着not (A and B)对于所有输入都必须为false。因此,最后一个问题变为Boolean satisfiability problem。这个问题询问,对于布尔表达式,是否存在至少一个使其成立的输入赋值。如果有,那么你可以说这两个表达式不等同使用我们的结构,否则你说它们是等价的

好消息是有大量用于攻击问题的工具,称为SAT解算器,用于大量工业应用(例如电路设计)。

坏消息是问题是NP-complete。所以它是非常难的。如果问题的设置不适合SAT求解器采用的通常的启发式方法,那么你将需要等待一段时间才能得到你的结果(可能直到宇宙死亡?)。

更糟糕的消息是SAT求解器专注于布尔问题,而你有SQL数据类型,这是更普遍的问题。不幸的是,开发出解决这个问题的工具。

正如其他人所提到的,所有这些都需要解析表达式。

根据您希望结果的准确程度,您可以执行以下操作:运行两个查询。如果它们提供相同的结果,则表示表达式是等效的。如果没有,说他们不是。你在这里有一种情况,你可以有误报,但没有误报。所以,如果你说两个表达不等同,那么事实,你不能否认,因为否则他们会提供相同的答案。但是如果你说它们是等价的,那么他们实际上并没有这样的机会,而且你的数据很幸运。如果人们将来在表格中添加更多数据,那么这两个数据就无法相提并论。这里涉及到一些数学,我在这个答案中没有勾画它,但是,如果一个人对输入表/表做出一些假设,并且一个表中也有足够的行,那么一个误报,也就是说,你说两个表达式是等价的,而事实上它们并不是,它们是相当低的 - 呈指数级。所以,如果你有1000行来测试这些东西,你可以非常肯定匹配是好的。

你也可以对表达式进行代数操作,试图将一个表达式转换为另一个表达式。从布尔表达式(DeMorgan规则,关联性,卡诺图等)中可以应用它们的整个集合,这可能有助于找到一个精确的解决方案,特别是如果 where 条款很简单,但这对我来说似乎更脆弱。

希望这会有所帮助。请务必订购查询结果,以免丢弃真实匹配。

答案 1 :(得分:0)

简单/简化的方法可能不够好(最初我没有看到你关于逻辑检查的评论)。正如其他人指出的那样,没有放松,这个问题就是NP-Complete ......

  • 使用类似JSQLParser的内容来获取结构化表示,然后遍历对象模型并尝试比较条件。我会尝试创建一个比较两个表达式并检查相等性的函数。对于具有深嵌套/括号的表达式,可以递归调用此函数。

  • 尝试使用正则表达式将where子句拆分为条件然后进行比较。在这里你必须要小心OR / AND和括号...理想情况下,你最终会想要一些保留括号内容的层次结构。

我倾向于认为第一种方法会更容易,因为你不必打破基于括号等条件的分组/分组。