我正在编写一个SQL查询,用于检查where
子句中的错误设备。为了执行此操作,我需要逐个检查每个设备的修订周期,因此该条款将结果限制为正确的设备(没有任何周期不正确):
where not exists(select * from trevision_cycle cycle
where cycle.id_equipment = equip.id and cycle.`status` = 'NO_OK')
但是,现在我想引入一个查询参数,以便只检索正确的设备或只检索不正确的设备,具体取决于其值。我们说我称之为incorrect
,所以我想做和这里做的一样:
where (not incorrect and not exists(select * from trevision_cycle cycle
where cycle.id_equipment = equip.id and cycle.`status` = 'NO_OK'))
or (incorrect and exists (select * from trevision_cycle cycle
where cycle.id_equipment = equip.id and cycle.`status` = 'NO_OK'))
因此,如果存在incorrect
标志,请检查至少有一个错误修订周期的设备。否则,只检索所有设备都正确的设备。 查询看起来非常冗余但是使用逻辑XNOR可以获得相同的结果。
我有更好的选择吗?
更新
示例数据
Equipment 1 -> Has one NO_OK cycle
Equipment 2 -> All its cycles are OK
Query with incorrect = true -> Returns only Equipment 1
Query with incorrect = false -> Returns only Equipment 2
答案 0 :(得分:2)
您可以将XOR
与NOT
结合使用 - 两者都存在于mysql中。这是XOR
的真值表:
+----------------+ |A | B | A XOR B | +--+---+---------+ |0 | 0 | 0 | |0 | 1 | 1 | |1 | 0 | 1 | |1 | 1 | 0 | +----------------+
如果我们将NOT
应用于此表,它将会显示:
+---------------------+ |A | B | NOT(A XOR B) | +--+---+--------------+ |0 | 0 | 1 | |0 | 1 | 0 | |1 | 0 | 0 | |1 | 1 | 1 | +---------------------+
与XNOR
表相同。因此,WHERE
可能如下所示:
WHERE NOT (incorrect XOR EXISTS(SELECT * FROM trevision_cycle cycle
WHERE cycle.id_equipment = equip.id AND cycle.`status` = 'NO_OK'))
答案 1 :(得分:1)
引用This Fellow's博客,如果你要像这样创建XNOR函数:
Your models have changes that are not yet reflected in a migration, and so won't be applied.
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
然后你可以使用它来简化你的陈述:
--XNOR
CREATE FUNCTION XNOR (@a bit, @b bit) RETURNS bit AS
BEGIN
RETURN @a ^ @b ^ 1
END
编辑:我很抱歉,对于MySQL,您必须使用XOR而不是' ^'来创建函数。 (' ^'是SQL Server的XOR函数)。我不确定MySQL的其余语法是否正确,但你明白了:
where dbo.XNOR(incorrect, exists(select * from trevision_cycle cycle
where cycle.id_equipment = equip.id and cycle.`status` = 'NO_OK'))
如果您有理由不构成新功能,那么以下内容在逻辑上是等效的:
--XNOR
CREATE FUNCTION XNOR (@a bit, @b bit) RETURNS bit AS
BEGIN
RETURN @a XOR @b XOR 1
END