SQL 在多个表中选择 EXIST 作为布尔值(位)
Posted
技术标签:
【中文标题】SQL 在多个表中选择 EXIST 作为布尔值(位)【英文标题】:SQL select EXIST over multiple tables as Boolean (Bit) 【发布时间】:2014-05-26 13:39:45 【问题描述】:我正在使用来自this question 的已接受答案,但用于多个表。
$result = mssql_query("SELECT CAST(
CASE WHEN
EXISTS(select 1 from codes where code = '".$generatedCode."') OR
EXISTS(select 1 from pakete where code = '".$generatedCode."') OR
EXISTS(select 1 from kunden where code = '".$generatedCode."') OR
EXISTS(select 1 from formulare where code = '".$generatedCode."') OR
EXISTS(select 1 from berater where code = '".$generatedCode."')
THEN 1
ELSE 0
END
AS BIT) as 'exists'";
$row = mssql_fetch_assoc($result);
if ($row['exists']==0)
理论上它看起来不错,实际上它也有效。但它时常发生,查询(我认为)出错并返回 1,即使其中一个表中有“代码”。
也许有人知道一个更好的跨表检查解决方案,在这种情况下,搜索到的 varchar 可能只存在于一个或两个表中。
仅供参考:生成的代码是一个九位字母数字的唯一字符串。
问候, 马库斯
更新:查询按预期工作,失败是返回后命名变量错误,因此使用原始生成代码(重复代码)代替。感谢您的帮助和简化查询。
【问题讨论】:
【参考方案1】:我猜你的代码可以工作。你可以做几件事来改进它。首先,cast()
不是必需的,因为您可以直接输入位文字(请参阅here)。以下代码使用这两种方法来表达 bit
文字。
其次,不要对列名使用单引号(当然,不推荐使用 mysql_,但这是另一回事,因为它只关注查询)。事实上,您应该避免使用保留字作为列名。所以:
SELECT (CASE WHEN
EXISTS(select 1 from codes where code = '".$generatedCode."') OR
EXISTS(select 1 from pakete where code = '".$generatedCode."') OR
EXISTS(select 1 from kunden where code = '".$generatedCode."') OR
EXISTS(select 1 from formulare where code = '".$generatedCode."') OR
EXISTS(select 1 from berater where code = '".$generatedCode."')
THEN 0b1
ELSE b'0'
END) as CodeExists
顺便说一句,我不鼓励你使用比特,除非你真的知道你在优化方面做什么。它们可能不会节省空间,也可能不会运行得更快。以下对我来说似乎完全合理:
SELECT (EXISTS(select 1 from codes where code = '".$generatedCode."') OR
EXISTS(select 1 from pakete where code = '".$generatedCode."') OR
EXISTS(select 1 from kunden where code = '".$generatedCode."') OR
EXISTS(select 1 from formulare where code = '".$generatedCode."') OR
EXISTS(select 1 from berater where code = '".$generatedCode."')
) as CodeExists
【讨论】:
【参考方案2】:你知道,你可以使用简单的 union 和 num_rows,没有必要选择一点 - 除非你的查询是其他复杂查询的一部分,否则它对你没有任何好处:
$sql="select 1 from codes where code = '".$generatedCode."'
union select 1 from pakete where code = '".$generatedCode."'
union select 1 from kunden where code = '".$generatedCode."'
union select 1 from formulare where code = '".$generatedCode."'
union select 1 from berater where code = '".$generatedCode."'";
$result = mssql_query($sql);
if(mssql_num_rows($result))
【讨论】:
这样效率会低很多,因为它会在返回值之前处理所有五个条件。另外,它会将值作为整数返回,而不是位。 你确定吗?不幸的是,我手头没有 MSSQL 安装,但在 Oracle 中它可能几乎相同,并且由于缓存机制可能更快 - 试试吧。 。 .是的。union
需要运行所有子查询、获取结果并删除重复项,然后才能返回任何行。这需要处理所有值。 or
方法应该在第一个匹配时停止。
是的,当然,您应该使用 UNION ALL,它不会删除重复项,也不会处理值。至于子查询的执行时间——它取决于 SQL 解释器和缓存。
。 . union all
在传回任何结果之前仍会处理所有子查询。此外,您的版本将返回多行,而 OP 的版本仅将一列添加到单行。以上是关于SQL 在多个表中选择 EXIST 作为布尔值(位)的主要内容,如果未能解决你的问题,请参考以下文章