| Author |
Topic |
|
shawnmolloy
Yak Posting Veteran
93 Posts |
Posted - 2008-10-19 : 08:02:17
|
I have two tables I'm trying to join:Topics_DiscussionFK [UserID]Topics_UserPK [UserID]Topics_User has 20 rows. Topics_Discussion has 4 rows. I want to see only the 4 rows from Topics_Discussion, with the user data from Topics_User appended to the 4 rows, for a grand total of - you guessed it - 4 rows.Currently, when I use this left join I get 80 rows. This is not the expected behavior.select * from Topics_Discussion dleft join Topics_User u on d.userid = u.userid How can I revise this join to do my bidding? Do I need a DISTINCT clause? I tried inner, outer, and right joins - to no avail.Thanks,-- shawn |
|
|
webfred
Master Smack Fu Yak Hacker
8781 Posts |
Posted - 2008-10-19 : 08:32:19
|
| In this case left join returns all rows from Topics_Discussion and brings NULL for the columns of Topics_User when there are no matching userid.You can add:WHERE u.userid IS NOT NULL to exclude the not-matching-pairs.WebfredPlanning replaces chance by mistake |
 |
|
|
shawnmolloy
Yak Posting Veteran
93 Posts |
Posted - 2008-10-19 : 09:46:30
|
I get the same result after adding the not null where clause:select * from Topics_Discussion dleft join Topics_User u on d.userid = u.useridwhere u.userid IS NOT NULL Here is a sample of the data if this helps:Topics_Discussion:userid id----------- -----------61 161 261 361 4Topics_User:userid nickname----------- -----------------------61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 Shawn61 ShawnAgain, I'm seeing 80 rows from these 20 rows in USER plus the 4 rows in DISUCSSION.Thanks. |
 |
|
|
webfred
Master Smack Fu Yak Hacker
8781 Posts |
Posted - 2008-10-19 : 09:53:44
|
| Now i see...You can use a common table with distinct values to join:;with my_topics_user (userid, nickname) as (select distinct userid, nickname from topics_user)select * from Topics_Discussion dleft join my_topics_user u on d.userid = u.useridwhere u.userid IS NOT NULLWebfredPlanning replaces chance by mistake |
 |
|
|
shawnmolloy
Yak Posting Veteran
93 Posts |
Posted - 2008-10-19 : 10:06:27
|
| Cool, thanks WebFred - that does the trick. The whole "With" thing is kinda weird though. I don't understand why I can't just use a straight forward join with a distinct clause.So what kind of join is it called when you use "with"? What exactly does "with" do to the two tables?Thanks! |
 |
|
|
webfred
Master Smack Fu Yak Hacker
8781 Posts |
Posted - 2008-10-19 : 10:15:54
|
| A common table expression is only one way to solve your problem from above.It's just a resultset that you can use as a table.I like the readability of this way.For more info see:http://msdn.microsoft.com/en-us/library/ms190766(SQL.90).aspxGreetingsWebfredPlanning replaces chance by mistake |
 |
|
|
shawnmolloy
Yak Posting Veteran
93 Posts |
Posted - 2008-10-19 : 11:03:01
|
Common Table Expression, huh? I like it! Thanks for this new piece of knowledge, Fred.Hey one last question, if you don't mind?If I want to expand this query with another join, I assume I'd do this:WITH my_topics_user (userid, nickname) AS (SELECT DISTINCT userid, nickname FROM [WiseTopic_topics_user]) SELECT e.*, d.* FROM [WiseTopic_Topics_Discussion] dLEFT JOIN my_topics_user u on d.userid = u.useridLEFT JOIN [WiseTopic_Topics_Category] e on e.categoryid = d.categoryidwhere u.userid IS NOT NULL But there are two problems:1) How do I add the columns from "e" (the new table; category)2) Why now is the data redundant? What I mean is... now the results look like:categoryId title------------- -------------------1 Politics2 Aliens1 Politics2 AliensI musta done something screwy...... |
 |
|
|
webfred
Master Smack Fu Yak Hacker
8781 Posts |
Posted - 2008-10-19 : 11:16:57
|
| A short while ago i was surprised to see that your table Topics_User has so many entrys for the same User. I expected only one entry for one user...Now there is a new table and i wanna know if there are redundant entries too.The best practice is alwas to show the structure of the tables, example of data in each table and in relation to the example data what the resultset should contain.WebfredPlanning replaces chance by mistake |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-10-19 : 13:10:25
|
quote: Originally posted by webfred A common table expression is only one way to solve your problem from above.It's just a resultset that you can use as a table.I like the readability of this way.For more info see:http://msdn.microsoft.com/en-us/library/ms190766(SQL.90).aspxGreetingsWebfredPlanning replaces chance by mistake
why do you think CTE is needed for getting distinct rows? wont below work?select * from Topics_Discussion dinner join (select distinct userid, nickname from Topics_User) u on d.userid = u.userid also if you want only matching rows why use left join and look for not null rows? isnt it enough just to do an inner join as in above? |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-10-19 : 13:15:24
|
quote: Originally posted by shawnmolloy Common Table Expression, huh? I like it! Thanks for this new piece of knowledge, Fred.Hey one last question, if you don't mind?If I want to expand this query with another join, I assume I'd do this:WITH my_topics_user (userid, nickname) AS (SELECT DISTINCT userid, nickname FROM [WiseTopic_topics_user]) SELECT e.*, d.* FROM [WiseTopic_Topics_Discussion] dLEFT JOIN my_topics_user u on d.userid = u.useridLEFT JOIN [WiseTopic_Topics_Category] e on e.categoryid = d.categoryidwhere u.userid IS NOT NULL But there are two problems:1) How do I add the columns from "e" (the new table; category)2) Why now is the data redundant? What I mean is... now the results look like:categoryId title------------- -------------------1 Politics2 Aliens1 Politics2 AliensI musta done something screwy......
the above output can be obtained just by doing belowSELECT e.*, d.* FROM [WiseTopic_Topics_Discussion] dINNER JOIN (SELECT DISTINCT userid, nickname FROM [WiseTopic_topics_user]) u on d.userid = u.useridLEFT JOIN [WiseTopic_Topics_Category] e on e.categoryid = d.categoryid and if category table also has duplicates use thisSELECT e.*, d.* FROM [WiseTopic_Topics_Discussion] dINNER JOIN (SELECT DISTINCT userid, nickname FROM [WiseTopic_topics_user]) u on d.userid = u.useridLEFT JOIN (SELECT DISTINCT categoryid,title FROM [WiseTopic_Topics_Category]) e on e.categoryid = d.categoryid |
 |
|
|
webfred
Master Smack Fu Yak Hacker
8781 Posts |
Posted - 2008-10-19 : 13:18:45
|
| Hello Visa,i have never intended that CTE is absolute needed but I Like It.I have no preference for left join or (inner) join. I think it doesn't matter.GreetingsWebfredPlanning replaces chance by mistake |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-10-19 : 13:22:32
|
quote: Originally posted by webfred Hello Visa,i have never intended that CTE is absolute needed but I Like It.I have no preference for left join or (inner) join. I think it doesn't matter.GreetingsWebfredPlanning replaces chance by mistake
Ok. i was asking if it was really required. I always prefered to use derived tables to take distinct values as in above.Regarding joins i think its always better to use inner join when looking for exact matches as inner join seems to perform much better than left join. |
 |
|
|
webfred
Master Smack Fu Yak Hacker
8781 Posts |
Posted - 2008-10-19 : 13:27:48
|
OK, i will take that in mind the next time. And in the join above it would be useful for the output to include u.nickname in selectlist wouldn't it?WebfredPlanning replaces chance by mistake |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-10-19 : 13:50:43
|
quote: Originally posted by webfred OK, i will take that in mind the next time. And in the join above it would be useful for the output to include u.nickname in selectlist wouldn't it?WebfredPlanning replaces chance by mistake
yup. if OP needs it also. i just copied code posted and just changed the join & cte. dont know what all values OP wants. |
 |
|
|
shawnmolloy
Yak Posting Veteran
93 Posts |
Posted - 2008-10-21 : 23:27:33
|
| Visakh. I changed my stored proc to use the join query example you have above and it produced the same results. I like that syntax much better as well, its easier to get your head around. Derived tables are the way to go.And also, next time I post I'll be sure to post my database table structure as well. Speaking of, whats the best way to translate that info from the database to a forum post? I've tried changing the results in Query Analyzer to "Results to Text" (as opposed to grid) and pasting it, but that never works well. I could take a screen shot of the table schemas but that is a pain. Or I could just list out the column names and types, but is there a standard format for doing that?Thanks. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-10-22 : 00:17:51
|
quote: Originally posted by shawnmolloy Visakh. I changed my stored proc to use the join query example you have above and it produced the same results. I like that syntax much better as well, its easier to get your head around. Derived tables are the way to go.And also, next time I post I'll be sure to post my database table structure as well. Speaking of, whats the best way to translate that info from the database to a forum post? I've tried changing the results in Query Analyzer to "Results to Text" (as opposed to grid) and pasting it, but that never works well. I could take a screen shot of the table schemas but that is a pain. Or I could just list out the column names and types, but is there a standard format for doing that?Thanks.
no need of taking the screen shot. just copy from query analyser with option set to results to text and paste it here and remember to enclose with code tags (for this select the entire code you pasted and click # button on top menu). Also for instructions of how to post a question refer below link.http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx |
 |
|
|
shawnmolloy
Yak Posting Veteran
93 Posts |
Posted - 2008-10-22 : 01:36:51
|
| Thanks for the link; its a good read. 1. State the question2. Post the DDL3. Post sample DML5. Post the expected resultsGood rules to post by, I'll keep them in mind. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2008-10-22 : 01:44:45
|
quote: Originally posted by shawnmolloy Thanks for the link; its a good read. 1. State the question2. Post the DDL3. Post sample DML5. Post the expected resultsGood rules to post by, I'll keep them in mind.
Cheers This will also help us to give quick and accurate solutions for your questions. |
 |
|
|
|