简体   繁体   English

我可以在给定的SQL查询中使用where子句代替AND吗? 如果是,两者有什么区别?

[英]Can I use where clause instead of AND in given SQL query? If yes, whats the difference in both?

Came across this query online some where, explaining inner join with a condition (incentive>3k).Was just wondering if I can use where clause instead of 'AND' in below SQL, if yes, whats will be the output difference in both? 在线查询此查询的某些位置,解释了内部连接的条件(奖励> 3k)。只是想知道是否可以在SQL下面使用where子句代替“ AND”,如果可以,两者的输出差异是什么?

SELECT FIRST_NAME,
       INCENTIVE_AMOUNT
FROM employee a
     INNER JOIN incentives B ON A.EMPLOYEE_ID = B.EMPLOYEE_REF_ID
                                AND INCENTIVE_AMOUNT > 3000;

yes, you can try this 是的,你可以试试这个

Select FIRST_NAME,INCENTIVE_AMOUNT from employee
     inner join incentives B on A.EMPLOYEE_ID=B.EMPLOYEE_REF_ID 
where INCENTIVE_AMOUNT >3000

I guess you can use it 我想你可以用

Select FIRST_NAME,INCENTIVE_AMOUNT from 
employee inner join incentives B on 
A.EMPLOYEE_ID=B.EMPLOYEE_REF_ID 
where INCENTIVE_AMOUNT >3000

I don't know about Oracle but, at least for INNER JOIN , MySQL treats the WHERE conditions the same as the join conditions. 我不了解Oracle,但至少对于INNER JOIN ,MySQL将WHERE条件与INNER JOIN条件相同。 It checks all of them that can be checked as soon as possible while it computes each row to put in the result set. 它会计算所有要放入结果集中的行,并尽快检查所有可以检查的内容。

These two queries produce the same resultset (and afaik MySQL processes them about the same way): 这两个查询产生相同的结果集(而afaik MySQL以相同的方式处理它们):

SELECT FIRST_NAME, INCENTIVE_AMOUNT
FROM employee a
  INNER JOIN incentives B 
     ON A.EMPLOYEE_ID = B.EMPLOYEE_REF_ID AND INCENTIVE_AMOUNT > 3000

and

SELECT FIRST_NAME, INCENTIVE_AMOUNT
FROM employee a
  INNER JOIN incentives B 
WHERE A.EMPLOYEE_ID = B.EMPLOYEE_REF_ID AND INCENTIVE_AMOUNT > 3000

There is no difference in the output of INNER JOIN but if you move the join conditions in the WHERE clause of a LEFT/RIGHT JOIN you get a different result set. INNER JOIN的输出没有差异,但是如果您在LEFT/RIGHT JOINWHERE子句中移动INNER JOIN条件,则会得到不同的结果集。

The query: 查询:

SELECT FIRST_NAME, INCENTIVE_AMOUNT
FROM employee a
  LEFT JOIN incentives B 
     ON A.EMPLOYEE_ID = B.EMPLOYEE_REF_ID AND INCENTIVE_AMOUNT > 3000

includes in the result set all the rows from table employee , matching with a row full of NULL s the rows that do not have a match (on the join condition) in table b . 在结果集中包括表employee所有行,并与充满NULL s的行匹配,表b不匹配(在连接条件下)的行。

But this query: 但是这个查询:

SELECT FIRST_NAME, INCENTIVE_AMOUNT
FROM employee a
  LEFT JOIN incentives B 
WHERE A.EMPLOYEE_ID = B.EMPLOYEE_REF_ID AND INCENTIVE_AMOUNT > 3000

combines all the rows of table a with all rows of table b and then the WHERE clause keeps only the matching rows from the two tables. 将表a的所有行与表b所有行组合在一起,然后WHERE子句仅保留两个表中匹配的行。 Its output is identical with the above two INNER JOIN queries. 其输出与上面的两个INNER JOIN查询相同。

They come to the same thing. 他们碰到同样的事情。

However, it is generally considered good practice to use join clauses only for specifying joins, and keep filter predicates in the where clause, hence: 然而,人们普遍认为很好的做法,使用join的条款中只对指定联接,并保持过滤谓词where条款,因此:

select first_name, incentive_amount
from   employee e
       join incentives i
            on  i.employee_ref_id = e.employee_id
where  i.incentive_amount > 3000

(Note that the inner and outer keywords are optional and in my view redundant clutter, so I never use them.) (请注意, innerouter关键字是可选的,并且在我看来是多余的,所以我从不使用它们。)

In the case of outer joins ( left join , or if you absolutely must, left outer join ), the whole idea of separating the filter predicates and placing them in the where clause goes out of the window, because (for example) if there is no incentive row then i.incentive_amount will be null and so any predicate whatsoever will exclude the row. 对于外部连接( left join ,或者,如果绝对需要,则为left outer join ),分离过滤谓词并将其放置在where子句中的整个想法不在窗口之内,因为(例如)如果存在如果没有incentive行,那么i.incentive_amount将为null,因此任何谓词都会排除该行。 Some say this is why ANSI join syntax is rubbish and the distinction between join and filter predicates is artificial and pointless, while others see it as a quirk of an otherwise helpful syntax. 有人说这就是为什么ANSI连接语法是垃圾的,而连接谓词和过滤谓词之间的区别是人为的和毫无意义的,而另一些人则将其视为对其他有用语法的怪癖。

select first_name, incentive_amount
from   employee e
       left join incentives i
            on  i.employee_ref_id = e.employee_id
            and i.incentive_amount > 3000

You could still follow the convention for inner joins in the same query, eg: 您仍然可以在同一查询中遵循内部联接的约定,例如:

select first_name, incentive_amount
from   employee e
       join departments d
            on d.department_id = e.department_id
       left join incentives i
            on  i.employee_ref_id = e.employee_id
            and i.incentive_amount > 3000
where  d.name = 'Philology'

Just to add, I agree with Jonathan Lewis that a and b are terrible aliases for employee and incentives . 补充一点,我同意乔纳森·刘易斯的观点, abemployeeincentives可怕别名。 (By the way, why not employees or incentive ?) In my version I have used the surely more readable e and i . (顺便说一句,为什么不采用employeesincentive ?)在我的版本中,我使用了肯定更具可读性的ei

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM