jjzjj

php - 特殊行为 : AND without WHERE still works

coder 2023-10-16 原文

我想知道为什么这个查询仍然可以完美运行。我认为 WHERE 子句总是必须以 WHERE 开头?

    SELECT `persons`.*
    FROM `persons`
    LEFT JOIN `team_memberships`
    ON (`team_memberships`.`participant` = `persons`.`id`)
    JOIN `teams`
    ON (`teams`.`id` = `team_memberships`.`team`)
    JOIN `departments`
    ON (`departments`.`id` = `teams`.`department`)
    JOIN `areas`
    ON (`areas`.`id` = `departments`.`area`)
    JOIN `companies`
    ON (`companies`.`id` = `areas`.`company`)

    [NO WHERE HERE]

    AND `persons`.`id` = ?

最佳答案

您刚刚在 ON 子句中添加了一个 ANDON 子句的计算结果为 bool 值 true 或 false,因此 AND 和例如 OR bool 运算符是允许的,具有关于括号等也适用。

将特定于特定联接表的条件从 WHERE 子句移动到适当的 ON 子句通常是有利的 - 如果没有其他原因提高可读性。

继续连接其他表之前限制连接的结果是合乎逻辑的*有意义的,而不是返回一个大的结果集,然后在最后用 WHERE 子句。我说 *合乎逻辑,因为 DBMS 通常会优化您的查询,以便无论如何都会发生这种情况......但并非总是如此......有时可以通过在连接处进行过滤来改进性能不佳的查询(有时反之亦然)。

例如,如果您知道自己只对 25 岁以上的人感兴趣,那么JOIN persons ON persons.id = team_memberships.participant AND persons.age > 25 是有意义的,而不是包括 所有 仅与年轻朋克有关的后续表格的结果,只是在末尾使用您的 WHERE persons.age > 25 子句再次过滤这些结果。

我的理解是,连接性能可能会因 ON 子句中的附加表达式而降低,在附加表达式的实例中:

  • 导致对联接中的每一行进行评估(因此我上面的 age > 25 示例可能属于此类),或者

  • 依赖一个/两个连接表中的非索引列,否则连接将仅依赖于索引列。

因此,例如,在连接时从结果集中剥离年轻朋克可能仍然值得,即使这会使特定连接变慢,因为此时较小的结果集可能会大大提高后续连接的性能。但是,如果将它们包含在联接中只会使记录数量略有增加,那么实际上将它们包含在联接中然后在 WHERE 子句中将它们过滤掉实际上可能会更快。

但我欢迎评论澄清/纠正我的理解。


编辑:根据下面的@ITroubs 评论,我真的应该澄清一下,如果连接是 INNER JOIN,那么无论附加过滤条件是否在ONWHERE 子句,但例如在 OP 的原始示例中,如果移动过滤条件,LEFT JOIN ON team_memberships 将产生完全不同的结果集从 WHERELEFT JOIN ... ON ...

关于php - 特殊行为 : AND without WHERE still works,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15526985/

有关php - 特殊行为 : AND without WHERE still works的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. ruby-on-rails - 标准化文件名的字符串,删除重音和特殊字符 - 2

    我正在尝试找到一种方法来规范化字符串以将其作为文件名传递。到目前为止我有这个:my_string.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n,'').downcase.gsub(/[^a-z]/,'_')但第一个问题:-字符。我猜这个方法还有更多问题。我不控制名称,名称字符串可以有重音符、空格和特殊字符。我想删除所有这些,用相应的字母('é'=>'e')替换重音符号,并将其余的替换为'_'字符。名字是这样的:“Prélèvements-常规”“健康证”...我希望它们像一个没有空格/特殊字符的文件名:“prelevements_routin

  3. ruby - Ruby gsub 替换中的行为不一致? - 2

    两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio

  4. ruby-on-rails - Ruby 中意外的大小写行为 - 2

    我在一段非常简单的代码(如我所想)中得到了一个错误的值:org=4caseorgwhenorg=4val='H'endputsval=>nil请不要生气,我希望我错过了一些非常明显的东西,但我真的想不通。谢谢。 最佳答案 这是典型的Ruby错误。case有两种被调用的方法,一种是你传递一个东西作为分支的基础,另一种是你不传递的东西。如果您确实在case中指定了一个表达式语句然后评估所有其他条件并与===进行比较.在这种情况下org评估为false和org===false显然不是真的。所有其他情况也是如此,它们要么是真的,要么是假的。

  5. ruby - 使对象的行为类似于 ruby​​ 中并行分配的数组 - 2

    假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje

  6. ruby - 了解在 Ruby 中与 lambda 一起使用的 inject 行为 - 2

    我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject

  7. ruby - 奇怪的 ruby​​ for 循环行为(为什么这样做有效) - 2

    defreverse(ary)result=[]forresult[0,0]inaryendresultendassert_equal["baz","bar","foo"],reverse(["foo","bar","baz"])这行得通,我想了解原因。有什么解释吗? 最佳答案 如果我使用each而不是for/in重写它,它看起来像这样:defreverse(ary)result=[]#forresult[0,0]inaryary.eachdo|item|result[0,0]=itemendresultendforainb基本上就

  8. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  9. ruby - 比较 rspec 中的 float 时的奇怪行为 - 2

    以下测试中的第3个失败:specify{(0.6*2).shouldeql(1.2)}specify{(0.3*3).shouldeql(0.3*3)}specify{(0.3*3).shouldeql(0.9)}#thisonefails这是为什么呢?这是浮点问题还是ruby​​或rspec问题? 最佳答案 从rspec-2.1开始specify{(0.6*2).shouldbe_within(0.01).of(1.2)}在那之前:specify{(0.6*2).shouldbe_close(1.2,0.01)}

  10. ruby - 为什么 `Symbol#match` 的行为与 `String#match` 和 `Regexp#match` 不同? - 2

    String#match和Regexp#match在匹配成功时返回一个MatchData:"".match(//)#=>#//.match("")#=>#//.match(:"")#=>#但是Symbol#match返回匹配位置(如String#=~)::"".match(//)#=>0为什么Symbol#match表现不同?有用例吗? 最佳答案 我将其报告为Ruby核心中的错误:https://bugs.ruby-lang.org/issues/11991.让我们看看他们会怎么说。更新被质疑的行为似乎是一个错误。似乎从Ruby2.

随机推荐