difference between "on" and "where" when using left/right join query
2013-04-23 18:38
337 查看
I used to put the where-condiction in the "on" substatement in a join query,wishing that can help reducing the join count and improving the performence.But totally i was wrong.It seems the on-condiction is not like the where-condiction in a left/right join query.
For example, there are two tables :
order([id],[order_code]), order_detail([id],[order_id],[product_name]), and they have some rows of data:
order:
order_detail:
Now i want to know the order_codes of orders which buying the product "p001",what is the query statement probably like?
In the pass,I may write this sql like this :
rather than this:
How come i prefer the first one?,but not the second one? I thought the first one is faster because it would only join rows which product_name is 'p001' in table [order_detail]. I guess
the sql server would check all of "on-condiction" and if the condiction is false, sql server would not execute the join operation,that means join operation will only occur twice(because there are only two rows which product_name is "p001" in table [order_detail]). But the second one sucks since it will join all rows of table [order_detail] and then find out which row's product_name is 'p001' only when all join operations get done!
But the first one is a bad query,it's not giving what i want. In fact it returns result like this:
But what result i want is like this:
And only the second sql is correct.
So what is wrong? What's the matter of the first one?
In this case, the "on-condiction" is not like what i think about.In a left/right join query, sql server will select all rows of the basic table no matter the on-condiction is true or false, in other words, the "on-condiction" is not a condiction to selecting rows of a basic table, in fact ,it's just a condiction to joinning rows.If the on-condiction is true, the current row of the basic table will join the row of the secondary table, if not,it won't,remainning the null in the field. But no matter it's true or not, all rows of the basic table are there,no more no less.
But the second,surely, will get the right result: only two row with the product_name "p001".It will join all rows,and when the join get done,it then find out rows i want.
For example, there are two tables :
order([id],[order_code]), order_detail([id],[order_id],[product_name]), and they have some rows of data:
order:
id | order_code |
1 | order001 |
2 | order002 |
3 | order003 |
id | order_id | product_name |
1 | 1 | p001 |
2 | 1 | p002 |
3 | 2 | p003 |
4 | 3 | p001 |
5 | 3 | p003 |
In the pass,I may write this sql like this :
select * from [order_detail] left join [order] on [order].id=[order_detail].orderid and order_detail.product_name='p001'
rather than this:
select * from [order_detail] left join [order] on [order].id=[order_detail].orderid where order_detail.product_name='p001'
How come i prefer the first one?,but not the second one? I thought the first one is faster because it would only join rows which product_name is 'p001' in table [order_detail]. I guess
the sql server would check all of "on-condiction" and if the condiction is false, sql server would not execute the join operation,that means join operation will only occur twice(because there are only two rows which product_name is "p001" in table [order_detail]). But the second one sucks since it will join all rows of table [order_detail] and then find out which row's product_name is 'p001' only when all join operations get done!
But the first one is a bad query,it's not giving what i want. In fact it returns result like this:
id | order_id | product_name | id | order_code |
1 | 1 | p001 | 1 | order001 |
2 | 1 | p002 | null | null |
3 | 2 | p003 | null | null |
4 | 3 | p001 | 3 | order003 |
5 | 3 | p003 | null | null |
id | order_id | product_name | id | order_code |
1 | 1 | p001 | 1 | order001 |
4 | 3 | p001 | 3 | order003 |
So what is wrong? What's the matter of the first one?
In this case, the "on-condiction" is not like what i think about.In a left/right join query, sql server will select all rows of the basic table no matter the on-condiction is true or false, in other words, the "on-condiction" is not a condiction to selecting rows of a basic table, in fact ,it's just a condiction to joinning rows.If the on-condiction is true, the current row of the basic table will join the row of the secondary table, if not,it won't,remainning the null in the field. But no matter it's true or not, all rows of the basic table are there,no more no less.
But the second,surely, will get the right result: only two row with the product_name "p001".It will join all rows,and when the join get done,it then find out rows i want.
相关文章推荐
- What is the difference between "green" threads and "native" threads?
- Sql 中having 和where的区别 SQL hardest question What is the difference between the WHERE and HAVING claus
- Oracle 11g: The difference between WHERE and HAVING
- Differences Between Enterprise, Standard and Standard One Editions on Oracle 11.2 (Doc ID 1084132.1)
- The differences between Java EE components and "standard" Java classes
- Oracle 11g: The difference between WHERE and HAVING
- JMeter daily notes --- the difference between "stop" and "shutdown" command
- an important difference between while and foreach on Perl
- The difference between "can" and "be able to"
- The difference between "malloc" and "new"
- Difference between "su - $username" and "su $username"
- difference between "<" and "<<"
- the difference between "./" and "sh"
- The fundamental differences between "GET" and "POST"
- Difference between onInterceptTouchEvent and dispatchTouchEvent?
- difference between "create group for any added .." and "create folder references ..."
- Difference between "/0" and '/0' and '0' and 0
- Difference between Beijing and Silicon Valley on innovation
- What is the difference between "transit","transfer","transmit... and "transport"