30/10/2011 | jiangws CREATE TABLE Loans ( loan_nbr INT NOT NULL , customer_nbr INT NOT NULL, loan_date DATETIME NOT NULL,� loan_amount DECIMAL(15, 2) NOT NULL, loan_type CHAR(1) NOT NULL, CONSTRAINT ck_loan_type CHECK (loan_type IN(‘P’,’B’)), — P = Personal; –B=Business CONSTRAINT pk_loans PRIMARY KEY(loan_nbr)); Question:Let’s try to find the top two customers with personal loan amounts that do not exceed $3000 select top 2 customer_nbr, SUM(loan_amount) AS total_amount�from Loanswhere loan_type=’P’group by customer_nbrhaving SUM(loan_amount)<3000order by total_amount desc; The Process:1.From2.Where3.Group by4.Having5.Select — Column aliases are added at this point. Steps prior to this cannot use the column aliases.6.Order by7.Top 补充:1)http://msdn.microsoft.com/en-us/library/ms189499.aspxLogical Processing Order of the SELECT statement The following steps show the logical processing order, or binding order, for a SELECT statement. This order determines when the objects defined in one step are made available to the clauses in subsequent steps. For example, if the query processor can bind to (access) the tables or views defined in the FROM clause, these objects and their columns are made available to all subsequent steps. Conversely, because the SELECT clause is step 8, any column aliases or derived columns defined in that clause cannot be referenced by preceding clauses. However, they can be referenced by subsequent clauses such as the ORDER BY clause. Note that the actual physical execution of the statement is determined by the query processor and the order may vary from this list. FROM ON JOIN WHERE GROUP BY WITH CUBE or WITH ROLLUP HAVING SELECT DISTINCT ORDER BY TOP 2) Now let us understand ON clause it is apply before JOIN that is why it retrieves all the result of Table2 where there are Flag = 1 but it does not affect Table1 so it retrieves all the rows of table1. When WHERE clause is applied it applies to complete result so it removes all the rows from Table1 and Table2 where Flag is not equal to 1, essentially keeping flag = 1 rows from Table1 and Table2. http://blog.sqlauthority.com/2009/03/15/sql-server-interesting-observation-of-on-clause-on-left-join-how-on-clause-effects-resultset-in-left-join/ SQL SERVER – Interesting Observation of ON Clause on LEFT JOIN – How ON Clause affects Resultset in LEFT JOIN March 15, 2009Pinal DaveSQL, SQL Performance, SQL Puzzle, SQL Server, SQL Tips and Tricks77 Comments Today I received email from Yoel from Israel. He is one smart man always bringing up interesting questions. Let us see his latest email first. Hi Pinal, I am subscribed to your blog and enjoy reading it. I have a question which has been bothering me for some time now. When I want to filter records in a query, I usually put the condition in the WHERE clause. When I make an inner join, I can put the condition in the ON clause instead, giving the same result. But with left joins this is not the case. Here is a quote from the SQL Server documentation: Although the placement of such predicates does not make a difference for INNER joins, they might cause a different result when OUTER joins are involved. This is because the predicates in the ON clause are applied to the table before the join, whereas the WHERE clause is semantically applied to the result of the join. I still can’t fully grasp the difference. Perhaps you could explain this better? I am sure that many of your readers could benefit from this too.Thank you. Yoel, You have asked very good question. Let us go through following example first. Download the script for this example here and execute in SSMS. I will explain the behavior as we go through the example. If any user does not want to read complete explanation, just go last paragraph of article which is in bold fonts. USE AdventureWorksGO-- Create Table1CREATE TABLE Table1(ID INT, Value VARCHAR(10), FlagINT)GO-- Populate Table1INSERT INTO Table1 (ID, Value, Flag)SELECT 1, 'First', 1UNION ALLSELECT 2, 'Second', 1UNION ALLSELECT 3, 'Third', 2UNION ALLSELECT 4, 'Fourth', 1UNION ALLSELECT 5, 'Fifth', 2UNION ALLSELECT 6, 'Sixth', 1UNION ALLSELECT 7, 'Seventh', 2GO-- Create Table2CREATE TABLE Table2(ID INT, Value VARCHAR(10), FlagINT)GO-- Populate Table2INSERT INTO Table2 (ID, Value, Flag)SELECT 1, 'First', 1UNION ALLSELECT 2, 'Second', 1UNION ALLSELECT 3, 'Third', 2UNION ALLSELECT 8, 'Eightth', 1UNION ALLSELECT 9, 'Nineth', 2GO-- Check the data in Table1 and Table2SELECT *FROM Table1SELECT *FROM Table2GO-- INNER JOIN with WHERE ConditionSELECT *FROM Table1 t1INNER JOIN Table2 t2 ON t1.ID = t2.IDWHERE t2.Flag = 1GO-- INNER JOIN with Additional Condition on ON clauseSELECT *FROM Table1 t1INNER JOIN Table2 t2 ON t1.ID = t2.ID AND t2.Flag = 1GO-- LEFT JOIN with WHERE ConditionSELECT *FROM Table1 t1LEFT JOIN Table2 t2 ON t1.ID = t2.ID AND t2.Flag = 1GO-- LEFT JOIN with Additional Condition on ON clauseSELECT *FROM Table1 t1LEFT JOIN Table2 t2 ON t1.ID = t2.IDWHERE t2.Flag = 1GO-- Clean up tablesDROP TABLE Table1DROP TABLE Table2GO Let us see the example in parts. Let us see the result of INNER JOIN clause. First of all we will run the query without WHERE clause and ON clause. Our result of join without any clause has to be same as they are essentially same query. Now we will run the same query with WHERE clause and ON clause and compare our result with earlier result and later resultset. As mentioned earlier it really does not matter for INNER JOIN if WHERE condition is moved to ON clause. In case of JOIN if ON clause (evaluated first) of WHERE clause (evaluated later) the result is same. Now let us see the example of LEFT JOIN. First we will run both the queries without WHERE clause and ON clause. Our result of join without any clause has to be same as they are essentially same query. Now we will run the same query with WHERE clause and ON clause and compare our result with earlier result and later resultset. Now let us understand ON clause it is apply before JOIN that is why it retrieves all the result of Table2 where there are Flag = 1 but it does not affect Table1 so it retrieves all the rows of table1. When WHERE clause is applied it applies to complete result so it removes all the rows from Table1 and Table2 where Flag is not equal to 1, essentially keeping flag = 1 rows from Table1 and Table2. I hope now this explanation is clear to Yoel. I am really waiting for feedback from my readers about this article. If you think this is interesting article, please share it on your social network and leave your comment here.