Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
schludi
Starting Member
1 Post |
Posted - 2010-07-14 : 10:43:25
|
Hello! I have a problem doing a LEFT JOIN on two tables which have the following keys:compcode, salesdiv, market, materialFirst my SQL (result has 4526 rows (must be 35532 like tmp_all..) with no NULL values want to have them on the right...): SELECT a.*, b.amount 'actuallastyear' FROM tmp_alleivcsetartikel a LEFT JOIN SUCCESS.dbo.bulktable_converted b ON (b.material+'/'+b.compcode+'/'+b.salesdiv+'/'+b.market)=(a.material+'/'+a.compcode+'/'+a.salesdiv+'/'+a.market) SAME WITH: SELECT count(*) FROM tmp_alleivcsetartikel a LEFT JOIN SUCCESS.dbo.bulktable_converted b ON b.material=a.material AND b.compcode=a.compcode AND b.salesdiv=a.salesdiv AND b.market=a.market or the same with: ON b.material=a.material AND a.compcode=b.compcode...The table tmp_alleivcsetartikel has 35532 rows.SELECT TOP 2 * FROM tmp_alleivcsetartikel:compcode salesdiv market material101 AE Domestic 4021800K101 AE Domestic 4021819The table SUCCESS.dbo.bulktable_converted has 6288589 rows.SELECT TOP 2 * FROM SUCCESS.dbo.bulktable_converted:compcode market salesdiv material month year umsatz amount101 Domestic AE 100-000-000 1 2009 0 30101 Domestic AE 100-000-000 2 2009 58 16 |
|
|
Ifor
Aged Yak Warrior
700 Posts |
Posted - 2010-07-14 : 11:02:10
|
The FROM clause is evaluated before the WHERE clause, so the filter needs to be applied on the JOIN.SELECT a.*, b.amount AS actuallastyearFROM tmp_alleivcsetartikel a LEFT JOIN SUCCESS.dbo.bulktable_converted b ON a.material = b.material AND a.compcode = b.compcode AND a.salesdiv = b.salesdiv AND a.market = b.market -- filter needs to be applied here AND b.[year] IN (2009)-- this will filter out nulls from the OUTER JOIN-- WHERE b.[year] IN (2009) |
 |
|
|
Ifor
Aged Yak Warrior
700 Posts |
Posted - 2010-07-14 : 11:05:06
|
| You probably need to understand the order in which SQL clauses are evaluated. Roughly:FROMWHEREGROUP BYHAVINGSELECTDISTINCTORDER BYTOPThis explains why SELECT expressions cannot be referenced in the WHERE clause etc. |
 |
|
|
Kristen
Test
22859 Posts |
Posted - 2010-07-14 : 11:15:25
|
You definitely should useON b.material=a.material AND b.compcode=a.compcode AND b.salesdiv=a.salesdiv AND b.market=a.marketwhich will be MUCH more efficient thanON (b.material+'/'+b.compcode+'/'+b.salesdiv+'/'+b.market)=(a.material+'/'+a.compcode+'/'+a.salesdiv+'/'+a.market)However,SELECT count(*)FROM MyTable AS T1 LEFT JOIN MyOtherTable AS T2 ON T2.MyCol = T1.MyCol will never give you a smaller number than SELECT COUNT(*) FROM MyTable. It will give you a larger number if some rows in MyTable match multiple rows in MyOtherTableIf you put a WHERE clause that references MyOtherTable then that will make the LEFT OUTER JOIN into an INNER JOIN - but you didn't say you have a WHERE clause? |
 |
|
|
|
|
|