{"id":18635,"date":"2018-03-03T14:17:00","date_gmt":"2018-03-03T14:17:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/premier_developer\/?p=18635"},"modified":"2019-02-14T20:18:28","modified_gmt":"2019-02-15T03:18:28","slug":"using-join-with-max-to-write-efficient-queries","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/premier-developer\/using-join-with-max-to-write-efficient-queries\/","title":{"rendered":"Using JOIN with MAX to write efficient queries"},"content":{"rendered":"<p>In this post, Senior Application Development Manager, <a href=\"https:\/\/www.linkedin.com\/in\/leshka\/\">Alexei Govorine<\/a>,&nbsp; demonstrates how to use SQL JOIN and MAX in a query.<\/p>\n<hr>\n<p>How to join two SQL tables and display the latest results.<\/p>\n<p>Recently a customer has asked me to help them with a query design. The question was how to join two tables and display the latest results from one of them in a single query.<\/p>\n<p>The answer is to use <b>JOIN<\/b> and <b>MAX<\/b> statements in a query. <\/p>\n<p>To demonstrate the correct syntax, let consider:  We need to display the latest student GPA records from the data that is contained in two tables: Student and StudentGrades. <\/p>\n<p>Not all students may have grade records and mostly of them may have multiple entries.<\/p>\n<p>Table: Student Table: StudentGrades<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p><b>id<\/b><\/p>\n<\/td>\n<td width=\"72\" valign=\"top\">\n<p><b>first<\/b><\/p>\n<\/td>\n<td width=\"66\" valign=\"top\">\n<p><b>last<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>1<\/p>\n<\/td>\n<td width=\"72\" valign=\"top\">\n<p>John<\/p>\n<\/td>\n<td width=\"66\" valign=\"top\">\n<p>Smith<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>2<\/p>\n<\/td>\n<td width=\"72\" valign=\"top\">\n<p>Mary<\/p>\n<\/td>\n<td width=\"66\" valign=\"top\">\n<p>Johnson<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>3<\/p>\n<\/td>\n<td width=\"72\" valign=\"top\">\n<p>Michael<\/p>\n<\/td>\n<td width=\"66\" valign=\"top\">\n<p>White<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>4<\/p>\n<\/td>\n<td width=\"72\" valign=\"top\">\n<p>Maria<\/p>\n<\/td>\n<td width=\"66\" valign=\"top\">\n<p>Garcia<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>5<\/p>\n<\/td>\n<td width=\"72\" valign=\"top\">\n<p>David<\/p>\n<\/td>\n<td width=\"66\" valign=\"top\">\n<p>Jones<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p><b>Id<\/b><\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p><b>student_id<\/b><\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p><b>school_year<\/b><\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p><b>gpa<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>1<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>1<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2016 Q1<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.6<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>2<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>1<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2016 Q2<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.7<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>3<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>1<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2016 Q3<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.7<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>4<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>1<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2017 Q1<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.6<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>5<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>1<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2017 Q2<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>4.0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>6<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>1<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2017 Q3<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.9<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>7<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>2<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2016 Q1<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>8<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>2<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2016 Q2<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.3<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>9<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>2<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2016 Q3<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.5<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>10<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>2<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2017 Q1<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.5<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>11<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>2<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2017 Q2<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.9<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>12<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>2<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2017 Q3<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>13<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>4<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2017 Q1<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.3<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>14<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>5<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2016 Q1<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.4<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>15<\/p>\n<\/td>\n<td width=\"80\" valign=\"top\">\n<p>5<\/p>\n<\/td>\n<td width=\"88\" valign=\"top\">\n<p>2016 Q1<\/p>\n<\/td>\n<td width=\"42\" valign=\"top\">\n<p>3.7<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><br><\/p>\n<p><pre>SELECT s.id, s.first, s.last, sd.school_year, sd.gpa FROM Student s <p>LEFT OUTER JOIN StudentGrades sd ON s.id=sd.student_id<\/p><\/pre>\n<p>Sixteen student grade records will be returned by using only a LEFT OUTER JOIN in the query.<\/p>\n<p>Altering the query to include a subquery with MAX on record id, results with student latest GPA data.<\/p>\n<p><pre>SELECT s.id, s.first, s.last, sd.school_year, sd.gpa FROM Student s<p>LEFT OUTER JOIN StudentGrades sd ON s.id=sd.student_id <p>AND <b>sd<\/b><b>.<\/b><b>record_id <\/b><b>=<\/b><b> <\/b><b>(<\/b><b>SELECT <\/b><b>MAX<\/b><b>(<\/b><b>record_id<\/b><b>)<\/b> FROM StudentGrades <p>WHERE student_id=sd.student_id)<\/p><\/pre>\n<p><br><\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p><b>id<\/b><\/p>\n<\/td>\n<td width=\"78\" valign=\"top\">\n<p><b>first<\/b><\/p>\n<\/td>\n<td width=\"78\" valign=\"top\">\n<p><b>last<\/b><\/p>\n<\/td>\n<td width=\"96\" valign=\"top\">\n<p><b>school_year<\/b><\/p>\n<\/td>\n<td width=\"54\" valign=\"top\">\n<p><b>gpa<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>1<\/p>\n<\/td>\n<td width=\"78\" valign=\"top\">\n<p>John<\/p>\n<\/td>\n<td width=\"78\" valign=\"top\">\n<p>Smith<\/p>\n<\/td>\n<td width=\"96\" valign=\"top\">\n<p>2017Q3<\/p>\n<\/td>\n<td width=\"54\" valign=\"top\">\n<p>3.9<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>2<\/p>\n<\/td>\n<td width=\"78\" valign=\"top\">\n<p>Mary<\/p>\n<\/td>\n<td width=\"78\" valign=\"top\">\n<p>Johnson<\/p>\n<\/td>\n<td width=\"96\" valign=\"top\">\n<p>2017Q3<\/p>\n<\/td>\n<td width=\"54\" valign=\"top\">\n<p>3.1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>3<\/p>\n<\/td>\n<td width=\"78\" valign=\"top\">\n<p>Michael<\/p>\n<\/td>\n<td width=\"78\" valign=\"top\">\n<p>White<\/p>\n<\/td>\n<td width=\"96\" valign=\"top\">\n<p>NULL<\/p>\n<\/td>\n<td width=\"54\" valign=\"top\">\n<p>NULL<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>4<\/p>\n<\/td>\n<td width=\"78\" valign=\"top\">\n<p>Maria<\/p>\n<\/td>\n<td width=\"78\" valign=\"top\">\n<p>Garcia<\/p>\n<\/td>\n<td width=\"96\" valign=\"top\">\n<p>2017Q1<\/p>\n<\/td>\n<td width=\"54\" valign=\"top\">\n<p>3.3<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"36\" valign=\"top\">\n<p>5<\/p>\n<\/td>\n<td width=\"78\" valign=\"top\">\n<p>David<\/p>\n<\/td>\n<td width=\"78\" valign=\"top\">\n<p>Jones<\/p>\n<\/td>\n<td width=\"96\" valign=\"top\">\n<p>2016Q1<\/p>\n<\/td>\n<td width=\"54\" valign=\"top\">\n<p>3.7<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><br><\/p>\n<p>Alternative we could use MAX function on some other column like the date data was entered and in conjunction with ORDER BY and WHERE statements to address more complicated situations.<\/p>\n<p>For additional information on MAX and other aggregate SQL functions see <a href=\"https:\/\/docs.microsoft.com\/en-us\/sql\/t-sql\/functions\/max-transact-sql\">https:\/\/docs.microsoft.com\/en-us\/sql\/t-sql\/functions\/max-transact-sql<\/a><\/p>\n<hr>\n<p><a href=\"https:\/\/blogs.msdn.com\/b\/premier_developer\/archive\/2014\/09\/15\/welcome.aspx\"><strong>Premier Support for Developers<\/strong><\/a> provides strategic technology guidance, critical support coverage, and a range of essential services to help teams optimize development lifecycles and improve software quality.&nbsp; Contact your Application Development Manager (ADM) or <a href=\"https:\/\/blogs.msdn.microsoft.com\/premier_developer\/contact-us\/\"><b>email us<\/b><\/a> to learn more about what we can do for you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post, Senior Application Development Manager, Alexei Govorine,&nbsp; demonstrates how to use SQL JOIN and MAX in a query. How to join two SQL tables and display the latest results. Recently a customer has asked me to help them with a query design. The question was how to join two tables and display the [&hellip;]<\/p>\n","protected":false},"author":582,"featured_media":37840,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[8],"tags":[10,3],"class_list":["post-18635","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data","tag-sql","tag-team"],"acf":[],"blog_post_summary":"<p>In this post, Senior Application Development Manager, Alexei Govorine,&nbsp; demonstrates how to use SQL JOIN and MAX in a query. How to join two SQL tables and display the latest results. Recently a customer has asked me to help them with a query design. The question was how to join two tables and display the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/18635","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/users\/582"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/comments?post=18635"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/posts\/18635\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media\/37840"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/media?parent=18635"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/categories?post=18635"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/premier-developer\/wp-json\/wp\/v2\/tags?post=18635"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}