12.07.2015 Views

Querying Microsoft® SQL Server® 2012 - Advanced Technology ...

Querying Microsoft® SQL Server® 2012 - Advanced Technology ...

Querying Microsoft® SQL Server® 2012 - Advanced Technology ...

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

OFFICIAL MICROSOFT LEARNING PRODUCT10774A<strong>Querying</strong> Microsoft® <strong>SQL</strong> Server® <strong>2012</strong>


ii <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong>Information in this document, including URL and other Internet Web site references, is subject to changewithout notice. Unless otherwise noted, the example companies, organizations, products, domain names,e-mail addresses, logos, people, places, and events depicted herein are fictitious, and no association withany real company, organization, product, domain name, e-mail address, logo, person, place or event isintended or should be inferred. Complying with all applicable copyright laws is the responsibility of theuser. Without limiting the rights under copyright, no part of this document may be reproduced, stored inor introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical,photocopying, recording, or otherwise), or for any purpose, without the express written permission ofMicrosoft Corporation.Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual propertyrights covering subject matter in this document. Except as expressly provided in any written licenseagreement from Microsoft, the furnishing of this document does not give you any license to thesepatents, trademarks, copyrights, or other intellectual property.The names of manufacturers, products, or URLs are provided for informational purposes only andMicrosoft makes no representations and warranties, either expressed, implied, or statutory, regardingthese manufacturers or the use of the products with any Microsoft technologies. The inclusion of amanufacturer or product does not imply endorsement of Microsoft of the manufacturer or product. Linksmay be provided to third party sites. Such sites are not under the control of Microsoft and Microsoft is notresponsible for the contents of any linked site or any link contained in a linked site, or any changes orupdates to such sites. Microsoft is not responsible for webcasting or any other form of transmissionreceived from any linked site. Microsoft is providing these links to you only as a convenience, and theinclusion of any link does not imply endorsement of Microsoft of the site or the products containedtherein.© <strong>2012</strong> Microsoft Corporation. All rights reserved.Microsoft and the trademarks listed at http://www.microsoft.com/about/legal/en/us/IntellectualProperty/Trademarks/EN-US.aspx are trademarks of the Microsoft group of companies. All other trademarks areproperty of their respective ownersProduct Number: 10774APart Number: X18-29114Released: 05/<strong>2012</strong>


MICROSOFT LICENSE TERMSOFFICIAL MICROSOFT LEARNING PRODUCTSMICROSOFT OFFICIAL COURSE Pre-Release and Final Release VersionsThese license terms are an agreement between Microsoft Corporation and you. Please read them. They apply tothe Licensed Content named above, which includes the media on which you received it, if any. These licenseterms also apply to any updates, supplements, internet based services and support services for the LicensedContent, unless other terms accompany those items. If so, those terms apply.BY DOWNLOADING OR USING THE LICENSED CONTENT, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPTTHEM, DO NOT DOWNLOAD OR USE THE LICENSED CONTENT.If you comply with these license terms, you have the rights below.1. DEFINITIONS.a. “Authorized Learning Center” means a Microsoft Learning Competency Member, Microsoft IT AcademyProgram Member, or such other entity as Microsoft may designate from time to time.b. “Authorized Training Session” means the Microsoft-authorized instructor-led training class using onlyMOC Courses that are conducted by a MCT at or through an Authorized Learning Center.c. “Classroom Device” means one (1) dedicated, secure computer that you own or control that meets orexceeds the hardware level specified for the particular MOC Course located at your training facilities orprimary business location.d. “End User” means an individual who is (i) duly enrolled for an Authorized Training Session or PrivateTraining Session, (ii) an employee of a MPN Member, or (iii) a Microsoft full-time employee.e. “Licensed Content” means the MOC Course and any other content accompanying this agreement.Licensed Content may include (i) Trainer Content, (ii) sample code, and (iii) associated media.f. “Microsoft Certified Trainer” or “MCT” means an individual who is (i) engaged to teach a training sessionto End Users on behalf of an Authorized Learning Center or MPN Member, (ii) currently certified as aMicrosoft Certified Trainer under the Microsoft Certification Program, and (iii) holds a MicrosoftCertification in the technology that is the subject of the training session.g. “Microsoft IT Academy Member” means a current, active member of the Microsoft IT AcademyProgram.h. “Microsoft Learning Competency Member” means a Microsoft Partner Network Program Member ingood standing that currently holds the Learning Competency status.i. “Microsoft Official Course” or “MOC Course” means the Official Microsoft Learning Product instructorledcourseware that educates IT professionals or developers on Microsoft technologies.


j. “Microsoft Partner Network Member” or “MPN Member” means a silver or gold-level Microsoft PartnerNetwork program member in good standing.k. “Personal Device” means one (1) device, workstation or other digital electronic device that youpersonally own or control that meets or exceeds the hardware level specified for the particular MOCCourse.l. “Private Training Session” means the instructor-led training classes provided by MPN Members forcorporate customers to teach a predefined learning objective. These classes are not advertised orpromoted to the general public and class attendance is restricted to individuals employed by orcontracted by the corporate customer.m. “Trainer Content” means the trainer version of the MOC Course and additional content designatedsolely for trainers to use to teach a training session using a MOC Course. Trainer Content may includeMicrosoft PowerPoint presentations, instructor notes, lab setup guide, demonstration guides, betafeedback form and trainer preparation guide for the MOC Course. To clarify, Trainer Content does notinclude virtual hard disks or virtual machines.2. INSTALLATION AND USE RIGHTS. The Licensed Content is licensed not sold. The Licensed Content islicensed on a one copy per user basis, such that you must acquire a license for each individual thataccesses or uses the Licensed Content.2.1 Below are four separate sets of installation and use rights. Only one set of rights apply to you.a. If you are a Authorized Learning Center:i. If the Licensed Content is in digital format for each license you acquire you may either:1. install one (1) copy of the Licensed Content in the form provided to you on a dedicated, secureserver located on your premises where the Authorized Training Session is held for access anduse by one (1) End User attending the Authorized Training Session, or by one (1) MCT teachingthe Authorized Training Session, or2. install one (1) copy of the Licensed Content in the form provided to you on one (1) ClassroomDevice for access and use by one (1) End User attending the Authorized Training Session, or byone (1) MCT teaching the Authorized Training Session.ii. You agree that:1. you will acquire a license for each End User and MCT that accesses the Licensed Content,2. each End User and MCT will be presented with a copy of this agreement and each individualwill agree that their use of the Licensed Content will be subject to these license terms prior totheir accessing the Licensed Content. Each individual will be required to denote theiracceptance of the EULA in a manner that is enforceable under local law prior to their accessingthe Licensed Content,3. for all Authorized Training Sessions, you will only use qualified MCTs who hold the applicablecompetency to teach the particular MOC Course that is the subject of the training session,4. you will not alter or remove any copyright or other protective notices contained in theLicensed Content,


5. you will remove and irretrievably delete all Licensed Content from all Classroom Devices andservers at the end of the Authorized Training Session,6. you will only provide access to the Licensed Content to End Users and MCTs,7. you will only provide access to the Trainer Content to MCTs, and8. any Licensed Content installed for use during a training session will be done in accordancewith the applicable classroom set-up guide.b. If you are a MPN Member.i. If the Licensed Content is in digital format for each license you acquire you may either:1. install one (1) copy of the Licensed Content in the form provided to you on (A) one (1)Classroom Device, or (B) one (1) dedicated, secure server located at your premises wherethe training session is held for use by one (1) of your employees attending a training sessionprovided by you, or by one (1) MCT that is teaching the training session, or2. install one (1) copy of the Licensed Content in the form provided to you on one (1)Classroom Device for use by one (1) End User attending a Private Training Session, or one (1)MCT that is teaching the Private Training Session.ii. You agree that:1. you will acquire a license for each End User and MCT that accesses the Licensed Content,2. each End User and MCT will be presented with a copy of this agreement and each individualwill agree that their use of the Licensed Content will be subject to these license terms priorto their accessing the Licensed Content. Each individual will be required to denote theiracceptance of the EULA in a manner that is enforceable under local law prior to theiraccessing the Licensed Content,3. for all training sessions, you will only use qualified MCTs who hold the applicablecompetency to teach the particular MOC Course that is the subject of the training session,4. you will not alter or remove any copyright or other protective notices contained in theLicensed Content,5. you will remove and irretrievably delete all Licensed Content from all Classroom Devices andservers at the end of each training session,6. you will only provide access to the Licensed Content to End Users and MCTs,7. you will only provide access to the Trainer Content to MCTs, and8. any Licensed Content installed for use during a training session will be done in accordancewith the applicable classroom set-up guide.c. If you are an End User:You may use the Licensed Content solely for your personal training use. If the Licensed Content is indigital format, for each license you acquire you may (i) install one (1) copy of the Licensed Content inthe form provided to you on one (1) Personal Device and install another copy on another PersonalDevice as a backup copy, which may be used only to reinstall the Licensed Content; or (ii) print one (1)copy of the Licensed Content. You may not install or use a copy of the Licensed Content on a deviceyou do not own or control.


d. If you are a MCT.i. For each license you acquire, you may use the Licensed Content solely to prepare and deliver anAuthorized Training Session or Private Training Session. For each license you acquire, you mayinstall and use one (1) copy of the Licensed Content in the form provided to you on one (1) PersonalDevice and install one (1) additional copy on another Personal Device as a backup copy, which maybe used only to reinstall the Licensed Content. You may not install or use a copy of the LicensedContent on a device you do not own or control.ii.Use of Instructional Components in Trainer Content. You may customize, in accordance with themost recent version of the MCT Agreement, those portions of the Trainer Content that are logicallyassociated with instruction of a training session. If you elect to exercise the foregoing rights, youagree: (a) that any of these customizations will only be used for providing a training session, (b) anycustomizations will comply with the terms and conditions for Modified Training Sessions andSupplemental Materials in the most recent version of the MCT agreement and with this agreement.For clarity, any use of “customize” refers only to changing the order of slides and content, and/ornot using all the slides or content, it does not mean changing or modifying any slide or content.2.2 Separation of Components. The Licensed Content components are licensed as a single unit and youmay not separate the components and install them on different devices.2.3 Reproduction/Redistribution Licensed Content. Except as expressly provided in the applicableinstallation and use rights above, you may not reproduce or distribute the Licensed Content or any portionthereof (including any permitted modifications) to any third parties without the express written permissionof Microsoft.2.4 Third Party Programs. The Licensed Content may contain third party programs or services. Theselicense terms will apply to your use of those third party programs or services, unless other terms accompanythose programs and services.2.5 Additional Terms. Some Licensed Content may contain components with additional terms,conditions, and licenses regarding its use. Any non-conflicting terms in those conditions and licenses alsoapply to that respective component and supplements the terms described in this Agreement.3. PRE-RELEASE VERSIONS. If the Licensed Content is a pre-release (“beta”) version, in addition to the otherprovisions in this agreement, then these terms also apply:a. Pre-Release Licensed Content. This Licensed Content is a pre-release version. It may not contain thesame information and/or work the way a final version of the Licensed Content will. We may change itfor the final version. We also may not release a final version. Microsoft is under no obligation toprovide you with any further content, including the final release version of the Licensed Content.b. Feedback. If you agree to give feedback about the Licensed Content to Microsoft, either directly orthrough its third party designee, you give to Microsoft without charge, the right to use, share andcommercialize your feedback in any way and for any purpose. You also give to third parties, withoutcharge, any patent rights needed for their products, technologies and services to use or interface withany specific parts of a Microsoft software, Microsoft product, or service that includes the feedback. Youwill not give feedback that is subject to a license that requires Microsoft to license its software,technologies, or products to third parties because we include your feedback in them. These rights


survive this agreement.c. Term. If you are an Authorized Training Center, MCT or MPN, you agree to cease using all copies of thebeta version of the Licensed Content upon (i) the date which Microsoft informs you is the end date forusing the beta version, or (ii) sixty (60) days after the commercial release of the Licensed Content,whichever is earliest (“beta term”). Upon expiration or termination of the beta term, you willirretrievably delete and destroy all copies of same in the possession or under your control.4. INTERNET-BASED SERVICES. Classroom Devices located at Authorized Learning Center’s physical locationmay contain virtual machines and virtual hard disks for use while attending an Authorized TrainingSession. You may only use the software on the virtual machines and virtual hard disks on a ClassroomDevice solely to perform the virtual lab activities included in the MOC Course while attending theAuthorized Training Session. Microsoft may provide Internet-based services with the software includedwith the virtual machines and virtual hard disks. It may change or cancel them at any time. If thesoftware is pre-release versions of software, some of its Internet-based services may be turned on bydefault. The default setting in these versions of the software do not necessarily reflect how the featureswill be configured in the commercially released versions. If Internet-based services are included with thesoftware, they are typically simulated for demonstration purposes in the software and no transmissionover the Internet takes place. However, should the software be configured to transmit over the Internet,the following terms apply:a. Consent for Internet-Based Services. The software features described below connect to Microsoft orservice provider computer systems over the Internet. In some cases, you will not receive a separatenotice when they connect. You may switch off these features or not use them. By using these features,you consent to the transmission of this information. Microsoft does not use the information to identifyor contact you.b. Computer Information. The following features use Internet protocols, which send to the appropriatesystems computer information, such as your Internet protocol address, the type of operating system,browser and name and version of the software you are using, and the language code of the devicewhere you installed the software. Microsoft uses this information to make the Internet-based servicesavailable to you.• Accelerators. When you use click on or move your mouse over an Accelerator, the title and full webaddress or URL of the current webpage, as well as standard computer information, and any contentyou have selected, might be sent to the service provider. If you use an Accelerator provided byMicrosoft, the information sent is subject to the Microsoft Online Privacy Statement, which isavailable at go.microsoft.com/fwlink/?linkid=31493. If you use an Accelerator provided by a thirdparty, use of the information sent will be subject to the third party’s privacy practices.• Automatic Updates. This software contains an Automatic Update feature that is on by default. Formore information about this feature, including instructions for turning it off, seego.microsoft.com/fwlink/?LinkId=178857. You may turn off this feature while the software isrunning (“opt out”). Unless you expressly opt out of this feature, this feature will (a) connect toMicrosoft or service provider computer systems over the Internet, (b) use Internet protocols to sendto the appropriate systems standard computer information, such as your computer’s Internetprotocol address, the type of operating system, browser and name and version of the software youare using, and the language code of the device where you installed the software, and (c)automatically download and install, or prompt you to download and/or install, current Updates tothe software. In some cases, you will not receive a separate notice before this feature takes effect.


By installing the software, you consent to the transmission of standard computer information andthe automatic downloading and installation of updates.• Auto Root Update. The Auto Root Update feature updates the list of trusted certificate authorities.you can switch off the Auto Root Update feature.• Customer Experience Improvement Program (CEIP), Error and Usage Reporting; Error Reports. Thissoftware uses CEIP and Error and Usage Reporting components enabled by default thatautomatically send to Microsoft information about your hardware and how you use this software.This software also automatically sends error reports to Microsoft that describe which softwarecomponents had errors and may also include memory dumps. You may choose not to use thesesoftware components. For more information please go to.• Digital Certificates. The software uses digital certificates. These digital certificates confirm theidentity of Internet users sending X.509 standard encrypted information. They also can be used todigitally sign files and macros, to verify the integrity and origin of the file contents. The softwareretrieves certificates and updates certificate revocation lists. These security features operate onlywhen you use the Internet.• Extension Manager. The Extension Manager can retrieve other software through the internet fromthe Visual Studio Gallery website. To provide this other software, the Extension Manager sends toMicrosoft the name and version of the software you are using and language code of the devicewhere you installed the software. This other software is provided by third parties to Visual StudioGallery. It is licensed to users under terms provided by the third parties, not from Microsoft. Readthe Visual Studio Gallery terms of use for more information.• IPv6 Network Address Translation (NAT) Traversal service (Teredo). This feature helps existinghome Internet gateway devices transition to IPv6. IPv6 is a next generation Internet protocol. Ithelps enable end-to-end connectivity often needed by peer-to-peer applications. To do so, eachtime you start up the software the Teredo client service will attempt to locate a public TeredoInternet service. It does so by sending a query over the Internet. This query only transfers standardDomain Name Service information to determine if your computer is connected to the Internet andcan locate a public Teredo service. If you· use an application that needs IPv6 connectivity or· configure your firewall to always enable IPv6 connectivityby default standard Internet Protocol information will be sent to the Teredo service at Microsoft atregular intervals. No other information is sent to Microsoft. You can change this default to use non-Microsoft servers. You can also switch off this feature using a command line utility named “netsh”.• Malicious Software Removal. During setup, if you select “Get important updates for installation”,the software may check and remove certain malware from your device. “Malware” is malicioussoftware. If the software runs, it will remove the Malware listed and updated atwww.support.microsoft.com/?kbid=890830. During a Malware check, a report will be sent toMicrosoft with specific information about Malware detected, errors, and other information aboutyour device. This information is used to improve the software and other Microsoft products andservices. No information included in these reports will be used to identify or contact you. You maydisable the software’s reporting functionality by following the instructions found at


www.support.microsoft.com/?kbid=890830. For more information, read the Windows MaliciousSoftware Removal Tool privacy statement at go.microsoft.com/fwlink/?LinkId=113995.• Microsoft Digital Rights Management. If you use the software to access content that has beenprotected with Microsoft Digital Rights Management (DRM), then, in order to let you play thecontent, the software may automatically request media usage rights from a rights server on theInternet and download and install available DRM updates. For more information, seego.microsoft.com/fwlink/?LinkId=178857.• Microsoft Telemetry Reporting Participation. If you choose to participate in Microsoft TelemetryReporting through a “basic” or “advanced” membership, information regarding filtered URLs,malware and other attacks on your network is sent to Microsoft. This information helps Microsoftimprove the ability of Forefront Threat Management Gateway to identify attack patterns andmitigate threats. In some cases, personal information may be inadvertently sent, but Microsoft willnot use the information to identify or contact you. You can switch off Telemetry Reporting. Formore information on this feature, see http://go.microsoft.com/fwlink/?LinkId=130980.• Microsoft Update Feature. To help keep the software up-to-date, from time to time, the softwareconnects to Microsoft or service provider computer systems over the Internet. In some cases, youwill not receive a separate notice when they connect. When the software does so, we check yourversion of the software and recommend or download updates to your devices. You may not receivenotice when we download the update. You may switch off this feature.• Network Awareness. This feature determines whether a system is connected to a network by eitherpassive monitoring of network traffic or active DNS or HTTP queries. The query only transfersstandard TCP/IP or DNS information for routing purposes. You can switch off the active queryfeature through a registry setting.• Plug and Play and Plug and Play Extensions. You may connect new hardware to your device, eitherdirectly or over a network. Your device may not have the drivers needed to communicate with thathardware. If so, the update feature of the software can obtain the correct driver from Microsoft andinstall it on your device. An administrator can disable this update feature.• Real Simple Syndication (“RSS”) Feed. This software start page contains updated content that issupplied by means of an RSS feed online from Microsoft.• Search Suggestions Service. When you type a search query in Internet Explorer by using the InstantSearch box or by typing a question mark (?) before your search term in the Address bar, you will seesearch suggestions as you type (if supported by your search provider). Everything you type in theInstant Search box or in the Address bar when preceded by a question mark (?) is sent to yoursearch provider as you type it. In addition, when you press Enter or click the Search button, all thetext that is in the search box or Address bar is sent to the search provider. If you use a Microsoftsearch provider, the information you send is subject to the Microsoft Online Privacy Statement,which is available at go.microsoft.com/fwlink/?linkid=31493. If you use a third-party searchprovider, use of the information sent will be subject to the third party’s privacy practices. You canturn search suggestions off at any time in Internet Explorer by using Manage Add-ons under theTools button. For more information about the search suggestions service, seego.microsoft.com/fwlink/?linkid=128106.• <strong>SQL</strong> Server Reporting Services Map Report Item. The software may include features that retrievecontent such as maps, images and other data through the Bing Maps (or successor branded)


application programming interface (the “Bing Maps APIs”). The purpose of these features is tocreate reports displaying data on top of maps, aerial and hybrid imagery. If these features areincluded, you may use them to create and view dynamic or static documents. This may be done onlyin conjunction with and through methods and means of access integrated in the software. You maynot otherwise copy, store, archive, or create a database of the content available through the BingMaps APIs. you may not use the following for any purpose even if they are available through theBing Maps APIs:• Bing Maps APIs to provide sensor based guidance/routing, or• Any Road Traffic Data or Bird’s Eye Imagery (or associated metadata).Your use of the Bing Maps APIs and associated content is also subject to the additional terms andconditions at http://www.microsoft.com/maps/product/terms.html.• URL Filtering. The URL Filtering feature identifies certain types of web sites based upon predefinedURL categories, and allows you to deny access to such web sites, such as known malicious sites andsites displaying inappropriate or pornographic materials. To apply URL filtering, Microsoft queriesthe online Microsoft Reputation Service for URL categorization. You can switch off URL filtering. Formore information on this feature, see http://go.microsoft.com/fwlink/?LinkId=130980• Web Content Features. Features in the software can retrieve related content from Microsoft andprovide it to you. To provide the content, these features send to Microsoft the type of operatingsystem, name and version of the software you are using, type of browser and language code of thedevice where you run the software. Examples of these features are clip art, templates, onlinetraining, online assistance and Appshelp. You may choose not to use these web content features.• Windows Media Digital Rights Management. Content owners use Windows Media digital rightsmanagement technology (WMDRM) to protect their intellectual property, including copyrights. Thissoftware and third party software use WMDRM to play and copy WMDRM-protected content. If thesoftware fails to protect the content, content owners may ask Microsoft to revoke the software’sability to use WMDRM to play or copy protected content. Revocation does not affect other content.When you download licenses for protected content, you agree that Microsoft may include arevocation list with the licenses. Content owners may require you to upgrade WMDRM to accesstheir content. Microsoft software that includes WMDRM will ask for your consent prior to theupgrade. If you decline an upgrade, you will not be able to access content that requires the upgrade.You may switch off WMDRM features that access the Internet. When these features are off, you canstill play content for which you have a valid license.• Windows Media Player. When you use Windows Media Player, it checks with Microsoft for· compatible online music services in your region;· new versions of the player; and· codecs if your device does not have the correct ones for playing content.You can switch off this last feature. For more information, go towww.microsoft.com/windows/windowsmedia/player/11/privacy.aspx.• Windows Rights Management Services. The software contains a feature that allows you to createcontent that cannot be printed, copied or sent to others without your permission. For moreinformation, go to www.microsoft.com/rms. you may choose not to use this feature


• Windows Time Service. This service synchronizes with time.windows.com once a week to provideyour computer with the correct time. You can turn this feature off or choose your preferred timesource within the Date and Time Control Panel applet. The connection uses standard NTP protocol.• Windows Update Feature. You may connect new hardware to the device where you run thesoftware. Your device may not have the drivers needed to communicate with that hardware. If so,the update feature of the software can obtain the correct driver from Microsoft and run it on yourdevice. You can switch off this update feature.c. Use of Information. Microsoft may use the device information, error reports, and malware reports toimprove our software and services. We may also share it with others, such as hardware and softwarevendors. They may use the information to improve how their products run with Microsoft software.d. Misuse of Internet-based Services. You may not use any Internet-based service in any way that couldharm it or impair anyone else’s use of it. You may not use the service to try to gain unauthorized accessto any service, data, account or network by any means.5. SCOPE OF LICENSE. The Licensed Content is licensed, not sold. This agreement only gives you some rightsto use the Licensed Content. Microsoft reserves all other rights. Unless applicable law gives you morerights despite this limitation, you may use the Licensed Content only as expressly permitted in thisagreement. In doing so, you must comply with any technical limitations in the Licensed Content that onlyallows you to use it in certain ways. Except as expressly permitted in this agreement, you may not:• install more copies of the Licensed Content on devices than the number of licenses you acquired;• allow more individuals to access the Licensed Content than the number of licenses you acquired;• publicly display, or make the Licensed Content available for others to access or use;• install, sell, publish, transmit, encumber, pledge, lend, copy, adapt, link to, post, rent, lease or lend,make available or distribute the Licensed Content to any third party, except as expressly permittedby this Agreement.• reverse engineer, decompile, remove or otherwise thwart any protections or disassemble theLicensed Content except and only to the extent that applicable law expressly permits, despite thislimitation;• access or use any Licensed Content for which you are not providing a training session to End Usersusing the Licensed Content;• access or use any Licensed Content that you have not been authorized by Microsoft to access anduse; or• transfer the Licensed Content, in whole or in part, or assign this agreement to any third party.6. RESERVATION OF RIGHTS AND OWNERSHIP. Microsoft reserves all rights not expressly granted to you inthis agreement. The Licensed Content is protected by copyright and other intellectual property laws andtreaties. Microsoft or its suppliers own the title, copyright, and other intellectual property rights in theLicensed Content. You may not remove or obscure any copyright, trademark or patent notices thatappear on the Licensed Content or any components thereof, as delivered to you.7. EXPORT RESTRICTIONS. The Licensed Content is subject to United States export laws and regulations. Youmust comply with all domestic and international export laws and regulations that apply to the LicensedContent. These laws include restrictions on destinations, End Users and end use. For additionalinformation, see www.microsoft.com/exporting.


8. LIMITATIONS ON SALE, RENTAL, ETC. AND CERTAIN ASSIGNMENTS. You may not sell, rent, lease, lend orsublicense the Licensed Content or any portion thereof, or transfer or assign this agreement.9. SUPPORT SERVICES. Because the Licensed Content is “as is”, we may not provide support services for it.10. TERMINATION. Without prejudice to any other rights, Microsoft may terminate this agreement if you failto comply with the terms and conditions of this agreement. Upon any termination of this agreement, youagree to immediately stop all use of and to irretrievable delete and destroy all copies of the LicensedContent in your possession or under your control.11. LINKS TO THIRD PARTY SITES. You may link to third party sites through the use of the Licensed Content.The third party sites are not under the control of Microsoft, and Microsoft is not responsible for thecontents of any third party sites, any links contained in third party sites, or any changes or updates to thirdparty sites. Microsoft is not responsible for webcasting or any other form of transmission received fromany third party sites. Microsoft is providing these links to third party sites to you only as a convenience,and the inclusion of any link does not imply an endorsement by Microsoft of the third party site.12. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates and support services arethe entire agreement for the Licensed Content.13. APPLICABLE LAW.a. United States. If you acquired the Licensed Content in the United States, Washington state law governsthe interpretation of this agreement and applies to claims for breach of it, regardless of conflict of lawsprinciples. The laws of the state where you live govern all other claims, including claims under stateconsumer protection laws, unfair competition laws, and in tort.b. Outside the United States. If you acquired the Licensed Content in any other country, the laws of thatcountry apply.14. LEGAL EFFECT. This agreement describes certain legal rights. You may have other rights under the laws ofyour country. You may also have rights with respect to the party from whom you acquired the LicensedContent. This agreement does not change your rights under the laws of your country if the laws of yourcountry do not permit it to do so.15. DISCLAIMER OF WARRANTY. THE LICENSED CONTENT IS LICENSED "AS-IS," "WITH ALL FAULTS," AND "ASAVAILABLE." YOU BEAR THE RISK OF USING IT. MICROSOFT CORPORATION AND ITS RESPECTIVEAFFILIATES GIVE NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS UNDER OR IN RELATION TOTHE LICENSED CONTENT. YOU MAY HAVE ADDITIONAL CONSUMER RIGHTS UNDER YOUR LOCAL LAWSWHICH THIS AGREEMENT CANNOT CHANGE. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS,MICROSOFT CORPORATION AND ITS RESPECTIVE AFFILIATES EXCLUDE ANY IMPLIED WARRANTIES ORCONDITIONS, INCLUDING THOSE OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE ANDNON-INFRINGEMENT.16. LIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES. TO THE EXTENT NOT PROHIBITED BYLAW, YOU CAN RECOVER FROM MICROSOFT CORPORATION AND ITS SUPPLIERS ONLY DIRECTDAMAGES UP TO USD$5.00. YOU AGREE NOT TO SEEK TO RECOVER ANY OTHER DAMAGES, INCLUDINGCONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES FROM MICROSOFTCORPORATION AND ITS RESPECTIVE SUPPLIERS.


This limitation applies too anything related to the Licensed Content, services made available through the Licensed Content, orcontent (including code) on third party Internet sites or third-party programs; ando claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence,or other tort to the extent permitted by applicable law.It also applies even if Microsoft knew or should have known about the possibility of the damages. Theabove limitation or exclusion may not apply to you because your country may not allow the exclusion orlimitation of incidental, consequential or other damages.Please note: As this Licensed Content is distributed in Quebec, Canada, some of the clauses in this agreementare provided below in French.Remarque : Ce le contenu sous licence étant distribué au Québec, Canada, certaines des clauses dans cecontrat sont fournies ci-dessous en français.EXONÉRATION DE GARANTIE. Le contenu sous licence visé par une licence est offert « tel quel ». Touteutilisation de ce contenu sous licence est à votre seule risque et péril. Microsoft n’accorde aucune autre garantieexpresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la protection duesconsommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garantiesimplicites de qualité marchande, d’adéquation à un usage particulier et d’absence de contrefaçon sont exclues.LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES. Vouspouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquementà hauteur de 5,00 $ US. Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, ycompris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.Cette limitation concerne:• tout ce qui est relié au le contenu sous licence , aux services ou au contenu (y compris le code)figurant sur des sites Internet tiers ou dans des programmes tiers ; et• les réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilitéstricte, de négligence ou d’une autre faute dans la limite autorisée par la loi en vigueur.Elle s’applique également, même si Microsoft connaissait ou devrait connaître l’éventualité d’un tel dommage.Si votre pays n’autorise pas l’exclusion ou la limitation de responsabilité pour les dommages indirects,accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l’exclusion ci-dessus ne s’appliquerapas à votre égard.EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous pourriez avoir d’autres droits prévuspar les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre payssi celles-ci ne le permettent pas.Revised March <strong>2012</strong>


xiv <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong>


<strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> xvAcknowledgementsMicrosoft Learning would like to acknowledge and thank the following for their contribution towardsdeveloping this title. Their effort at various stages in the development has ensured that you have a goodclassroom experience.Design and DevelopmentThis course was designed and developed by SolidQ. SolidQ is a global provider of consulting, mentoringand training services for Microsoft Data Management, Business Intelligence and Collaboration platforms.Chris Randall – AuthorChris Randall is Director of Training, USA for SolidQ. He has worked with <strong>SQL</strong> Server since 1996, asa trainer, consultant and speaker. Chris has contributed content to courses on T-<strong>SQL</strong>, SSIS and BIArchitecture, has taught thousands of students in classes and at conferences worldwide, including <strong>SQL</strong>PASS, <strong>SQL</strong> Saturday and several conferences for Microsoft Certified Trainers. Chris has recently consultedwith a large global nonprofit enterprise on integrating with the Microsoft SharePoint and BI stack, andhas guided the adoption of <strong>SQL</strong> Server Analysis Services and Reporting Services into the products of anindependent software vendor. He holds the MCT and MCITP certifications for the <strong>SQL</strong> Server 2008portfolio.Grega Jerkič – AuthorGrega Jerki is an independent consultant, mentor and trainer working for SolidQ. For last 10 years, he hasbeen developing, architecting and managing different projects focusing on data warehousing, MDM, dataintegration, analytical / planning solutions and predictive analytics mostly with Microsoft technology. Heinvented and was lead architect for a predefined business intelligence solution on top of ERP MicrosoftDynamics NAV – BI4Dynamics. The solution is now used worldwide by more than 150+ clients and gottwo awards by Microsoft for best business intelligence solution for CEE region.Grega also manages the leading business intelligence consulting company in Slovenia called IN516HT andis a regular speaker at different <strong>SQL</strong> and business intelligence conferences.Itzik Ben-Gan – Subject Matter ExpertItzik Ben-Gan is a Mentor and Co-Founder of SolidQ. A <strong>SQL</strong> Server Microsoft MVP (Most ValuableProfessional) since 1999, Itzik has delivered numerous training events around the world focused on T-<strong>SQL</strong><strong>Querying</strong>, Query Tuning and Programming. Itzik is the author of several books including T-<strong>SQL</strong>Fundamentals, Microsoft <strong>SQL</strong> Server <strong>2012</strong> High-Performance T-<strong>SQL</strong> Using Window Functions, and others.He has written many articles for <strong>SQL</strong> Server Pro as well as articles and whitepapers for MSDN. Itzik'sspeaking activities include major community events around the world such as TechEd and <strong>SQL</strong> PASS. Itzikis the author of SolidQ's <strong>Advanced</strong> T-<strong>SQL</strong> <strong>Querying</strong>, Programming and Tuning course along with being aprimary resource within the company for their T-<strong>SQL</strong> related activities.


xvi <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong>Technical ReviewChris Barker – Technical ReviewerChris Barker is an MCT working in the New Zealand market and currently employed as a staff trainer atAuldhouse, one of New Zealand’s major CPLS training centers in Wellington. Chris’ background includesprogramming from the early 1970s—his first program was written in assembly language and debugged inbinary (literally)! While focusing training on programming (mostly .NET) and databases (mostly Microsoft<strong>SQL</strong> Server) Chris has also been an infrastructure trainer and has both Novell and Microsoft networkingqualifications.


<strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> xviiContentsModule 1: Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Lesson 1: Introducing Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-3Lesson 2: Getting Started with <strong>SQL</strong> Server Management Studio 1-10Lab: Working with <strong>SQL</strong> Server <strong>2012</strong> Tools 1-20Module 2: Getting Started with <strong>SQL</strong> AzureLesson 1: Overview of <strong>SQL</strong> Azure 2-3Module 3: Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Lesson 1: Introducing T-<strong>SQL</strong> 3-3Lesson 2: Understanding Sets 3-21Lesson 3: Understanding Predicate Logic 3-25Lesson 4: Understanding the Logical Order of Operations in SELECTStatements 3-28Lab: Introduction to T-<strong>SQL</strong> <strong>Querying</strong> 3-35Module 4: Writing SELECT QueriesLesson 1: Writing Simple SELECT Statements 4-3Lesson 2: Eliminating Duplicates with DISTINCT 4-10Lesson 3: Using Column and Table Aliases 4-18Lesson 4: Writing Simple CASE Expressions 4-25Lab: Writing Basic SELECT Statements 4-30Module 5: <strong>Querying</strong> Multiple TablesLesson 1: Understanding Joins 5-3Lesson 2: <strong>Querying</strong> with Inner Joins 5-11Lesson 3: <strong>Querying</strong> with Outer Joins 5-18Lesson 4: <strong>Querying</strong> with Cross Joins and Self-Joins 5-24Lab: <strong>Querying</strong> Multiple Tables 5-34Module 6: Sorting and Filtering DataLesson 1: Sorting Data 6-3Lesson 2: Filtering Data with Predicates 6-10Lesson 3: Filtering with TOP and OFFSET-FETCH 6-17Lesson 4: Working with Unknown Values 6-24Lab: Sorting and Filtering Data 6-29


xviii <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong>Module 7: Working with <strong>SQL</strong> Server <strong>2012</strong> Data TypesLesson 1: Introducing <strong>SQL</strong> Server <strong>2012</strong> Data Types 7-3Lesson 2: Working with Character Data 7-15Lesson 3: Working with Date and Time Data 7-27Lab: Working with <strong>SQL</strong> Server <strong>2012</strong> Data Types 7-36Module 8: Using Built-In FunctionsLesson 1: Writing Queries with Built-In Functions 8-3Lesson 2: Using Conversion Functions 8-11Lesson 3: Using Logical Functions 8-21Lesson 4: Using Functions to Work with NULL 8-26Lab: Using Built-In Functions 8-31Module 9: Grouping and Aggregating DataLesson 1: Using Aggregate Functions 9-3Lesson 2: Using the GROUP BY Clause 9-13Lesson 3: Filtering Groups with HAVING 9-21Lab: Grouping and Aggregating Data 9-26Module 10: Using SubqueriesLesson 1: Writing Self-Contained Subqueries 10-3Lesson 2: Writing Correlated Subqueries 10-10Lesson 3: Using the EXISTS Predicate with Subqueries 10-15Lab: Using Subqueries 10-20Module 11: Using Table ExpressionsLesson 1: Using Views 11-3Lesson 2: Using Inline Table-Valued Functions 11-9Lesson 3: Using Derived Tables 11-14Lesson 4: Using Common Table Expressions 11-25Lab: Using Table Expressions 11-29Module 12: Using Set OperatorsLesson 1: Writing Queries with the UNION Operator 12-3Lesson 2: Using EXCEPT and INTERSECT 12-9Lesson 3: Using APPLY 12-15Lab: Using Set Operators 12-23Module 13: Using Window Ranking, Offset, and Aggregate FunctionsLesson 1: Creating Windows with OVER 13-3Lesson 2: Exploring Window Functions 13-15Lab: Using Window Ranking, Offset, and Aggregate Functions 13-26


<strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> xixModule 14: Pivoting and Grouping SetsLesson 1: Writing Queries with PIVOT and UNPIVOT 14-3Lesson 2: Working with Grouping Sets 14-10Lab: Pivoting and Grouping Sets 14-18Module 15: <strong>Querying</strong> <strong>SQL</strong> Server MetadataLesson 1: <strong>Querying</strong> System Catalog Views and Functions 15-3Lesson 2: Executing System Stored Procedures 15-11Lesson 3: <strong>Querying</strong> Dynamic Management Objects 15-19Lab: <strong>Querying</strong> <strong>SQL</strong> Server Metadata 15-25Module 16: Executing Stored ProceduresLesson 1: <strong>Querying</strong> Data with Stored Procedures 16-3Lesson 2: Passing Parameters to Stored Procedures 16-7Lesson 3: Creating Simple Stored Procedures 16-12Lesson 4: Working with Dynamic <strong>SQL</strong> 16-17Lab: Executing Stored Procedures 16-23Module 17: Programming with T-<strong>SQL</strong>Lesson 1: T-<strong>SQL</strong> Programming Elements 17-3Lesson 2: Controlling Program Flow 17-11Lab: Programming with T-<strong>SQL</strong> 17-17Module 18: Implementing Error HandlingLesson 1: Using TRY / CATCH Blocks 18-3Lesson 2: Working with Error Information 18-7Lab: Implementing Error Handling 18-13Module 19: Implementing TransactionsLesson 1: Transactions and the Database Engine 19-3Lesson 2: Controlling Transactions 19-10Lab: Implementing Transactions 19-18Module 20: Improving Query PerformanceLesson 1: Factors in Query Performance 20-3Lesson 2: Displaying Query Performance Data 20-15Lab: Improving Query Performance 20-24


xx <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong>Appendix: Lab Answer KeysModule 1 Lab: Working with <strong>SQL</strong> Server <strong>2012</strong> Tools L1-1Module 3 Lab: Introduction to T-<strong>SQL</strong> <strong>Querying</strong> L3-7Module 4 Lab: Writing Basic SELECT Statements L4-15Module 5 Lab: <strong>Querying</strong> Multiple Tables L5-25Module 6 Lab: Filtering and Sorting Data L6-33Module 7 Lab: Working with <strong>SQL</strong> Server Data Types L7-43Module 8 Lab: Using Built-In Functions L8-53Module 9 Lab: Grouping and Aggregating Data L9-61Module 10 Lab: Using Subqueries L10-71Module 11 Lab: Using Table Expressions L11-79Module 12 Lab: Using Set Operators L12-91Module 13 Lab: Using Window Ranking, Offset andAggregate Functions L13-101Module 14 Lab: Pivoting and Grouping Sets L14-109Module 15 Lab: <strong>Querying</strong> <strong>SQL</strong> Server Metadata L15-119Module 16 Lab: Executing Stored Procedures L16-125Module 17 Lab: Programming with T-<strong>SQL</strong> L17-135Module 18 Lab: Implementing Error Handling L18-145Module 19 Lab: Implementing Transactions L19-153Module 20 Lab: Improving Query Performance L20-159


About This Course xxiAbout This CourseThis section provides you with a brief description of the course, audience, suggested prerequisites, andcourse objectives.Course DescriptionThis 5-day instructor led course provides students with the technical skills required to write basicTransact-<strong>SQL</strong> queries for Microsoft® <strong>SQL</strong> Server® <strong>2012</strong>. This course is the foundation for all <strong>SQL</strong> Serverrelateddisciplines; namely, Database Administration, Database Development and Business Intelligence.This course helps people prepare for exam 70-461.All the labs for this course can be performed using the provided virtual machines. However, if you have aMicrosoft Windows Azure account and the classroom virtual machines connect to the internet you may beable to connect to your Windows Azure server and database from the classroom. Many of the labs in thiscourse are enabled for you to perform the lab while connected to your own Windows Azure database inthe cloud. Your instructor should be able to provide a current list of Microsoft Windows Azure enabledlabs.AudienceThis course is intended for Database Administrators, Database Developers, and Business Intelligenceprofessionals. The course will very likely be well attended by <strong>SQL</strong> power users who aren’t necessarilydatabase-focused or plan on taking the exam; namely, report writers, business analysts and clientapplication developers.Student PrerequisitesThis course requires that you meet the following prerequisites:• Working knowledge of relational databases.• Basic knowledge of the Microsoft Windows® operating system and its core functionality.Course ObjectivesAfter completing this course, students will be able to:• Write SELECT Queries• Query Multiple Tables• Use Built-In Functions• Use Subqueries• Execute Stored Procedures• Use Set Operators• Implement Error Handling• Implementing Transactions• Use Table Expressions• Sort and Filter Data• Use Window Ranking, Offset and Aggregate Functions• Query <strong>SQL</strong> Server Metadata• Program with T-<strong>SQL</strong>• Improve Query Performance


xxiiAbout This CourseCourse OutlineThis section provides an outline of the course:Module 1, “Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>”Module 2, “Getting Started with <strong>SQL</strong> Azure”Module 3, “Introduction to T-<strong>SQL</strong> <strong>Querying</strong>”Module 4, “Writing SELECT Queries”Module 5, “<strong>Querying</strong> Multiple Tables”Module 6, “Sorting and Filtering DataModule 7, “Working with <strong>SQL</strong> Server <strong>2012</strong> Data Types”Module 8, “Using Built-In Functions”Module 9, “Grouping and Aggregating Data”Module 10, “Using Subqueries”Module 11, “Using Table ExpressionsModule 12, “Using Set Operators”Module 13, “Using Window Ranking, Offset, and Aggregate Functions”Module 14, “Pivoting and Grouping Sites”Module 15, “<strong>Querying</strong> <strong>SQL</strong> Server Metadata”Module 16, “Executing Stored Procedures”Module 17, “Programming with T-<strong>SQL</strong>”Module 18, “Implementing Error Handling”Module 19, “Implementing Transactions”Module 20, “Improving Query Performance”


About This Course xxiiiCourse MaterialsThe following materials are included with your kit:• Course Handbook A succinct classroom learning guide that provides all the critical technicalinformation in a crisp, tightly-focused format, which is just right for an effective in-class learningexperience.• Lessons: Guide you through the learning objectives and provide the key points that are critical tothe success of the in-class learning experience.• Labs: Provide a real-world, hands-on platform for you to apply the knowledge and skills learnedin the module.• Module Reviews and Takeaways: Provide improved on-the-job reference material to boostknowledge and skills retention.• Lab Answer Keys: Provide step-by-step lab solution guidance at your fingertips when it’sneeded.• Course Companion Content on the http://www.microsoft.com/learning/companionmoc/ Site:Searchable, easy-to-navigate digital content with integrated premium on-line resources designed tosupplement the Course Handbook.• Modules: Include companion content, such as questions and answers, detailed demo steps andadditional reading links, for each lesson. Additionally, they include Lab Review questions andanswers and Module Reviews and Takeaways sections, which contain the review questions andanswers, best practices, common issues and troubleshooting tips with answers, and real-worldissues and scenarios with answers.• Resources: Include well-categorized additional resources that give you immediate access to themost up-to-date premium content on TechNet, MSDN®, Microsoft Press®.• Student Course files on the http://www.microsoft.com/learning/companionmoc/ Site: Includesthe Allfiles.exe, a self-extracting executable file that contains all the files required for the labs anddemonstrations.• Course evaluation At the end of the course, you will have the opportunity to complete an onlineevaluation to provide feedback on the course, training facility, and instructor.To provide additional comments or feedback on the course, send e-mail to support@mscourseware.com.To inquire about the Microsoft Certification Program, send e-mail to mcphelp@microsoft.com.


xxivAbout This CourseVirtual Machine EnvironmentThis section provides the information for setting up the classroom environment to support the businessscenario of the course.Virtual Machine ConfigurationIn this course, you will use Microsoft Hyper-V® to perform the labs.The following table shows the role of each virtual machine used in this course:Virtual machine10774A-MIA-DC1RoleDomain Controller10774A-MIA-<strong>SQL</strong>1 <strong>SQL</strong> Server VM for Modules 1-20MT11-MSL-TMG1Threat Mitigation Gateway to enable VMs to connect to theinternet. Necessary if students will connect to Windows Azure.Software ConfigurationThe following software is installed on each VM:• Microsoft <strong>SQL</strong> Server <strong>2012</strong> (only on the 10774A-MIA-<strong>SQL</strong>1)Course FilesThere are files associated with the labs in this course. The lab files are located in the folder F:\10774A_Labson the student computers.Classroom SetupEach classroom computer will have the same virtual machine configured in the same way.Course Hardware LevelTo ensure a satisfactory student experience, Microsoft Learning requires a minimum equipmentconfiguration for trainer and student computers in all Microsoft Certified Partner for Learning Solutions(CPLS) classrooms in which Official Microsoft Learning Product courseware are taught. This course requireshardware level 6.


1-1Module 1Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Contents:Lesson 1: Introducing Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-3Lesson 2: Getting Started with <strong>SQL</strong> Server Management Studio 1-10Lab: Working with <strong>SQL</strong> Server <strong>2012</strong> Tools 1-20


1-2 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Module OverviewBefore you begin to learn how to write queries with Microsoft® <strong>SQL</strong> Server® <strong>2012</strong>, it is useful tounderstand the overall <strong>SQL</strong> Server database platform, including its basic architecture, the various editionsavailable for <strong>SQL</strong> Server <strong>2012</strong>, and the tools a query writer will use. This module will also prepare you touse <strong>SQL</strong> Server Management Studio, <strong>SQL</strong> Server's primary development and administration tool, toconnect to <strong>SQL</strong> Server instances and create, organize, and execute queries.ObjectivesAfter completing this module, you will be able to:• Describe the architecture and editions of <strong>SQL</strong> Server <strong>2012</strong>.• Work with <strong>SQL</strong> Server Management Studio.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-3Lesson 1Introducing Microsoft <strong>SQL</strong> Server <strong>2012</strong>In this lesson, you will learn about the basic architecture and concepts of Microsoft <strong>SQL</strong> Server <strong>2012</strong>. Youwill learn how instances, services, and databases interact, which editions of <strong>SQL</strong> Server <strong>2012</strong> are available,what their distinguishing features are, and how databases are structured. This will help prepare you tobegin working with <strong>SQL</strong> Server queries in upcoming modules.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the basic architecture of <strong>SQL</strong> Server.• Describe the versions of <strong>SQL</strong> Server.• Describe the editions of <strong>SQL</strong> Server.• Describe the role and structure of <strong>SQL</strong> Server databases.


1-4 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong><strong>SQL</strong> Server ArchitectureThis topic will introduce you to the basic elements that make up <strong>SQL</strong> Server <strong>2012</strong>. While there are manycomponents that ship with <strong>SQL</strong> Server <strong>2012</strong>, this course focuses on writing queries against the databaseengine. Therefore, this lesson will similarly focus on those elements of <strong>SQL</strong> Server <strong>2012</strong> that you will mostfrequently encounter when writing queries.ServicesIn Windows, services are applications that start without user interaction, typically at computer startup.When <strong>SQL</strong> Server is installed, multiple services are set up on the computer. These include some or all ofthe following, depending on the options chosen during installation:• <strong>SQL</strong> Server <strong>2012</strong> database engine, which is responsible for executing commands submitted in theTransact-<strong>SQL</strong>, or T-<strong>SQL</strong>, language, database management, memory and disk allocation, and othercore features of <strong>SQL</strong> Server.• <strong>SQL</strong> Server Agent, which is responsible for executing scheduled jobs, monitoring the system fordefined alert conditions, and other administrative tasks.• Business intelligence components, which include <strong>SQL</strong> Server Reporting Services, <strong>SQL</strong> Server AnalysisServices, and <strong>SQL</strong> Server Integration Services.A myriad of other services and support applications may be installed when <strong>SQL</strong> Server is set up. As a querywriter, you will primarily be interacting with the <strong>SQL</strong> Server <strong>2012</strong> database engine, which we will refer tosimply as <strong>SQL</strong> Server.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-5InstancesThe basic unit of installation and program execution for <strong>SQL</strong> Server is an instance. An instance is a copy ofthe <strong>SQL</strong>SERVR.EXE executable program, which runs as a Windows service. Logically, an instance representsthe programs and resource allocations that support a single copy of <strong>SQL</strong> Server running on a computer,such as memory, configuration files, and CPU. Multiple instances of <strong>SQL</strong> Server may be installed side-bysideon a single computer, whether the computer is a physical or a virtual server. Each instance is isolatedfrom other instances on the same computer, including disk files used, security permissions, and resourcesallocated. The exception to this is shared components such as management tools and documentation.One of the instances may be set up as the default instance, which means you will access it using only thename of the host computer. All other instances on the same computer must be named instances, whichyou will access using a combination of the host name and the instance name.Note You will work with instance names in a later lesson in this module.It is important to understand that an instance of <strong>SQL</strong> Server, as an installed copy of the database engine,is a container for databases. An instance can contain one or many databases. Logically, databases exist alevel down from instances in a hierarchy of <strong>SQL</strong> Server objects. A database cannot span multiple instances.Tools<strong>SQL</strong> Server ships with a number of tools to manage, develop with, and query the database engine. Youwill find shortcuts to many of these tools on the Windows Start menu in the subfolders for Microsoft <strong>SQL</strong>Server <strong>2012</strong>. In this course, you will primarily work with <strong>SQL</strong> Server Management Studio, or SSMS. SSMS isan integrated management, development, and querying application with many features for exploring andworking with your databases. Other tools you may encounter include:• <strong>SQL</strong>CMD, a command-line client that allows you to submit T-<strong>SQL</strong> commands as an alternative tousing the graphical SSMS application.• <strong>SQL</strong> Server Configuration Manager, which while primarily a tool for administrators, also includesfeatures useful for managing <strong>SQL</strong> Server software installed on client machines, such as the ability tocreate and manage aliases to <strong>SQL</strong> Servers.• <strong>SQL</strong> Server Installation Center, which provides the ability to add, remove, and modify <strong>SQL</strong> Serverprogram features, if you have permission to do so.


1-6 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong><strong>SQL</strong> Server Versions<strong>SQL</strong> Server <strong>2012</strong> is only the latest version in the history of <strong>SQL</strong> Server development. Originally developedfor the OS/2 operating system (versions 1.0 and 1.1), versions 4.21 and later of <strong>SQL</strong> Server moved to theWindows® operating system.<strong>SQL</strong> Server's engine received a major rewrite for version 7.0, and subsequent versions have continued toimprove and extend <strong>SQL</strong> Server's capabilities from the workgroup to the largest enterprises.Note Although its name might suggest it, <strong>SQL</strong> Server 2008 R2 is not a service pack for<strong>SQL</strong> Server 2008. It is an independent version (version number 10.5) with enhanced multiservermanagement capabilities as well as new business intelligence features.Question: Have you worked with any versions of <strong>SQL</strong> Server prior to <strong>SQL</strong> Server <strong>2012</strong>?


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-7<strong>SQL</strong> Server Editions<strong>SQL</strong> Server ships in several editions that provide different feature sets targeting different businessscenarios. In the <strong>SQL</strong> Server <strong>2012</strong> release, the number of editions has been streamlined from previousversions. The main editions are:• Enterprise, which is the flagship edition. It contains all of <strong>SQL</strong> Server <strong>2012</strong>'s features, includingbusiness intelligence services and support for virtualization.• Standard, which includes the core database engine as well as core reporting and analyticscapabilities. However, it supports fewer processor cores and does not offer all of the availability,security, and data warehousing features found in the Enterprise edition.• Business Intelligence, which is a new edition. It provides the core database engine, full reportingand analytics capabilities, and full business intelligence services. However, like the Standard edition, itsupports fewer processor cores and does not offer all of the availability, security, and datawarehousing features.<strong>SQL</strong> Server <strong>2012</strong> also offers other editions, such as Parallel Data Warehouse, Web, Developer, and Express,each targeted for specific use cases.This course uses core database engine features found in all editions.For More Information See the <strong>SQL</strong> Server <strong>2012</strong> Editions guide athttp://go.microsoft.com/fwlink/?LinkId=242834.Question: What edition of <strong>SQL</strong> Server <strong>2012</strong> are you or will you be using in yourorganization?


1-8 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong><strong>SQL</strong> Server DatabasesDatabases in <strong>SQL</strong> Server are containers for data and objects, including tables, views, stored procedures,user accounts, and other management objects. A <strong>SQL</strong> Server database is always a single logical entity,backed by multiple physical files.When client applications send requests to the database engine as T-<strong>SQL</strong> statements, <strong>SQL</strong> Server performsall file, memory, and processor utilization on the client's behalf. Clients never directly access database files,unlike in desktop database applications.<strong>SQL</strong> Server supports two types of databases: system and user. T<strong>SQL</strong><strong>2012</strong>, the sample database you will beusing to write queries, is a user database. <strong>SQL</strong> Server's system databases include:• master, the system configuration database.• msdb, the configuration database for the <strong>SQL</strong> Server Agent service and other system services.• model, the template for new user databases.• tempdb, used by the database engine to store temporary data such as work tables. This database isdropped and recreated each time <strong>SQL</strong> Server restarts - never store anything you need to depend onin it!• Resource, a hidden system configuration database that provides system objects to other databases.Database administrators and developers can create user databases to hold data and objects forapplications. You connect to a user database to execute your queries. You will need security credentials tolog in to <strong>SQL</strong> Server and a database account with permissions to access data objects in the database.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-9About the Course Sample DatabaseIn this course, most of your queries will be written against a sample database named T<strong>SQL</strong><strong>2012</strong>. Thisdatabase is designed as a small, low-complexity database suitable for learning to write T-<strong>SQL</strong> queries. Itcontains several types of objects:• User-defined schemas, which are containers for tables and views. (You will learn about schemas laterin this course.)• Tables, which relate to other tables via foreign key constraints.• Views, which display aggregated information.The T<strong>SQL</strong><strong>2012</strong> database is modeled to resemble a sales-tracking application for a small business. Some ofthe tables you will use include:• Sales.Orders, which stores data typically found in the header of an invoice (order ID, customer ID,order date, etc.).• Sales.OrderDetails, which stores transaction detail about each order (parent order ID, product ID, unitprice, etc.).• Sales.Customers, which stores information about customers (company name, contact details, etc.).• HR.Employees, which stores information about the company's employees (name, birthdate, hire date,etc.).Other tables are supplied to add context to these tables, such as additional product information.


1-10 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Lesson 2Getting Started with <strong>SQL</strong> Server Management StudioIn this lesson, you will learn how to use <strong>SQL</strong> Server Management Studio (SSMS) to connect to an instanceof <strong>SQL</strong> Server, explore the databases contained in the instance, and work with script files that containT-<strong>SQL</strong> queries.Lesson ObjectivesAfter completing this lesson, you will be able to:• Use SSMS to connect to on-premises <strong>SQL</strong> Server instances.• Explore a <strong>SQL</strong> Server instance using Object Explorer.• Create and organize script files.• Execute T-<strong>SQL</strong> queries.• Use Books Online.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-11Starting SSMSSSMS is an integrated management, development, and querying application with many features forexploring and working with your databases. SSMS is based on the Visual Studio shell. If you haveexperience with Visual Studio, you will likely feel comfortable with SSMS.To start SSMS, you may:• Use its shortcut on the Windows Start menu in the <strong>SQL</strong> Server <strong>2012</strong> subfolder.• Enter its filename, SSMS.EXE, in a command prompt window.• Type ‘‘SSMS’’ in the Search Programs and Files box.By default, SSMS will display a Connect to Server dialog box. Using this box you can specify the server (orinstance) name and your security credentials. If you use the Options button to access the ConnectionProperties tab, you can also supply the database to which you wish to connect. However, you can exploremany of SSMS's features without initially connecting to a <strong>SQL</strong> Server instance, so you may also cancel theConnect to Server box and connect to a server later.Once SSMS is running, you may wish to explore some of its settings, such as those found in the Tools,Options box. SSMS can be customized in many ways, such as setting a default font, enabling line numbersfor scripts, and controlling the behavior of SSMS's many windows.For More Information See Books Online at http://go.microsoft.com/fwlink/?LinkId=242835.


1-12 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Connecting to <strong>SQL</strong> ServerIn order to connect to an instance of <strong>SQL</strong> Server, you need to specify several items, no matter which toolyou use to connect:• The name of the instance to which you want to connect in the form hostname\instancename. Forexample, MIA-<strong>SQL</strong>\Proseware would connect to the Proseware instance on the Windows servernamed MIA-<strong>SQL</strong>. If you are connecting to the default instance, you may omit the hostname. ForMicrosoft Windows Azure, the server name is a four-part name in the form.database.windows.net.• The name of the database. If you do not specify a database name, you will be connected to thedatabase designated as your account's default by the database administrator, or to the masterdatabase if no default has been specifically assigned. In Windows Azure, it is important to connect tothe correct database since you may not change connections between user databases once connected.You must disconnect and reconnect to the desired database.• The authentication mechanism required by the server. This may be Windows Authentication, in whichyour Windows network credentials will be passed to <strong>SQL</strong> Server (no entry required), or <strong>SQL</strong> ServerAuthentication, in which a username and password for your account must be created by a databaseadministrator (you enter them at connection time). <strong>SQL</strong> Server Authentication is the only mechanismsupported by Windows Azure.Question: Which authentication method do you use to log in to <strong>SQL</strong> Server in yourorganization?


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-13Working with Object ExplorerObject Explorer is a graphical tool for managing <strong>SQL</strong> Server instances and databases. It is one of severalSSMS window panes available from the View menu. Object Explorer provides direct interaction with most<strong>SQL</strong> Server data objects, such as tables, views, and procedures. Right-clicking an object, such as a table,will display context-sensitive commands, including query-generators and script generators for objectdefinitions.Note Any operation performed in SSMS requires appropriate permissions granted by adatabase administrator. Being able to see an object or command does not necessarily implypermission to use the object or issue the command.<strong>SQL</strong> Server query writers most commonly use Object Explorer to learn about the structure and definitionof the data objects they want to use in their queries. For example, to learn the names of columns in atable, you follow these steps:1. Connect to the <strong>SQL</strong> Server, if necessary.2. Expand the Databases folder to expose the list of databases.3. Expand the relevant database to expose the Tables folder.4. Expand the Tables folder to view the list of tables in the database.5. Locate the table you are interested in and expand it to find the Columns folder. The Columns folderwill display the names, data types, and other information about the columns that make up the table.You can even drag the name of a database, table, or column into the query window to have itentered and avoid typing it yourself.Note Selecting objects in the Object Explorer pane does not change any connectionsmade in other windows.


1-14 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Working with Script Files and ProjectsSSMS allows you to create and save T-<strong>SQL</strong> code in text files, typically given a .sql file extension. Like otherWindows applications that open, edit, and save files, SSMS provides access to file management throughthe File menu and through standard toolbar buttons.In addition to directly manipulating individual script files, SSMS provides a mechanism for initially savinggroups of files together and for opening, saving, and closing them together. This mechanism uses severalconceptual layers to work with T-<strong>SQL</strong> script files and related documents, and uses the Solution Explorerpane to display and control them:Object Parent DescriptionSolution None Top-level container for projects. Stored as a text file with an .ssmsslnextension, which references components contained within it. May containmultiple projects. Displayed in Solution Explorer at the top of the objecthierarchy.Project Solution Container for T-<strong>SQL</strong> scripts (called queries), stored database connectionmetadata, and miscellaneous files. Stored as a text file with an .ssmssqlprojextension, which references component scripts and other files.Script Project T-<strong>SQL</strong> script file with a .sql extension. The core item of work in SSMS.The benefits to using scripts organized in projects and solutions include the ability to open multiple scriptfiles in SSMS at once. You can open the solution or project file from within SSMS or Windows Explorer.To create a new solution, click the File menu and click New Project. (There is no ‘‘New Solution’’command.) Specify a name for the initial project, its parent solution, and whether you want the project tobe stored in a subfolder below the solution file in the location you indicate. Click OK to create the parentobjects.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-15To interact with Solution Explorer, open the pane (if necessary) from the View menu. To create a newscript that will be stored as part of the project, right-click the Queries folder in the project and click NewQuery.Note Using the New Query toolbar button or the new query commands on the File menuwill create a new script temporarily stored with the solution in the Miscellaneous Files folder.If you wish to move an existing open query document into a solution currently open inSolution Explorer, you will need to save the file. Then you can drag the query into theproject tree to save it in the Queries folder. This will make a copy of the script file and placeit into the solution.It is important to remember to save the solution when exiting SSMS or opening another solution in orderto preserve changes to the solution's file inventory. Saving a script using the Save toolbar button or theSave .sql command on the File menu will only save changes to the contents of the currentscript file. To save the entire solution and all its files, use the Save All command on the File menu or whenprompted to save the .ssmssln and .ssmssqlproj files on exit.


1-16 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Executing QueriesTo execute T-<strong>SQL</strong> code in SSMS, you first need to open the .sql file that contains the queries, or type yourquery into a new query window. Then decide how much of the code in the script is to be executed:• Select the code you wish to execute.• If nothing is selected, SSMS will execute the entire script, which is the default behavior.Once you have decided what you wish to execute, you can run the code by doing one of the following:• Clicking the Execute button on the SSMS toolbar.• Clicking the Query menu, then clicking Execute.• Pressing the F5 key, the Alt+X keyboard shortcut, or the Ctrl+E keyboard shortcut.By default, SSMS will display your results in a new pane of the query window. The location andappearance of the results can be changed in the Options box accessible from the Tools menu. To togglethe display of the results and return to a full-screen T-<strong>SQL</strong> editor, use the Ctrl+R keyboard shortcut.SSMS provides several formats for the display of query results:• Grid, which is a spreadsheet-like view of the results, with row numbers and resizable columns. You canuse Ctrl+D to select this before executing a query.• Text, which is a Windows Notepad-like display that pads column widths. You can use Ctrl+T to selectthis before executing a query.• File, which allows you to directly save query results to a text file with an .rpt extension. Executing thequery will prompt for a location for the results file. The file may then be opened by any applicationthat can read text files, such as Windows Notepad and SSMS itself. You can use Ctrl+Shift+F to selectthis before executing a query.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-17Using Books OnlineBooks Online (often abbreviated BOL) is the product documentation for <strong>SQL</strong> Server. BOL includes helpfulinformation on <strong>SQL</strong> Server's architecture and concepts, as well as syntax reference for T-<strong>SQL</strong>. BOL can beaccessed from the Help menu in SSMS. In a script window, context-sensitive help for T-<strong>SQL</strong> keywords isavailable by selecting the keyword and pressing Shift+F1.Books Online can be browsed directly on Microsoft's website at http://go.microsoft.com/fwlink/?LinkId=233779. Optionally, it can be downloaded and installed locally, then viewed in the Help Viewapplication installed with <strong>SQL</strong> Server and client tools.Note Previous versions of <strong>SQL</strong> Server provided the option to install Books Online locallyduring <strong>SQL</strong> Server setup. In <strong>SQL</strong> Server <strong>2012</strong>, Books Online does not ship with the productinstallation media, so it must be downloaded and installed separately from <strong>SQL</strong> Server itself.The first time Help is invoked, you will be prompted to specify whether you wish to view Books Onlinecontent online or locally. This setting may be changed later by using the Help Library Manager, located inthe Windows Start menu in the <strong>SQL</strong> Server <strong>2012</strong> folder and the Documentation & Community subfolder.For detailed instructions on how to download, install, and configure Books Online for local offline use,see the topic "Get Started with Microsoft Books Online for <strong>SQL</strong> Server" at http://go.microsoft.com/fwlink/?LinkId=242836.


1-18 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Demonstration: Introducing Microsoft <strong>SQL</strong> Server <strong>2012</strong>Demonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the ServerName text box and click Connect.2. If the Object Explorer pane is not visible, click View and click Object Explorer.3. Expand the Databases folder to see the list of databases.4. Expand the AdventureWorks2008R2 database.5. Expand the Tables folder.6. Expand the Sales.Customer table.7. Expand the Columns folder.8. Show the list of columns, and point out the data type information for the ModifiedDate column.9. If the Solution Explorer pane is not visible, click View and click Solution Explorer. It will be empty,initially.10. Click the File menu, click New, click Project.11. In the New Project box, under Installed Templates, click <strong>SQL</strong> Server Management StudioProjects.12. In the middle pane, click <strong>SQL</strong> Server Scripts.13. In the Name box, type Module 1 Demonstration.14. In the Location box, type or browse to F:\10774A_Labs\10774A_01_PRJ.15. Point out the solution name, then click OK.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-1916. In the Solution Explorer pane, right-click Queries, then click New Query.17. Type the following T-<strong>SQL</strong> code:USE AdventureWorks2008R2;GOSELECT CustomerID, AccountNumberFROM Sales.Customer;18. Select the code and click Execute on the toolbar.19. Point out the results pane.20. Click File, and then click Save All.21. Click File, and then click Close Solution.22. Click File, click Recent Projects and Solutions, and then click Module 01 Demonstration.ssmssln.23. Point out the Solution Explorer pane.


1-20 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Lab: Working with <strong>SQL</strong> Server <strong>2012</strong> ToolsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the ‘‘Press CTRL+ALT+DELETE to log on’’message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the ‘‘Press CTRL+ALT+DELETE to log on’’message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-217. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.Lab ScenarioThe Adventure Works Cycles Bicycle Manufacturing Company has adopted <strong>SQL</strong> Server <strong>2012</strong> as itsrelational database management system of choice. You are an information worker who will be required tofind and retrieve business data from several <strong>SQL</strong> Server databases. In this lab, you will begin to explore thenew environment and become acquainted with the tools for querying <strong>SQL</strong> Server.


1-22 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Exercise 1: Working with <strong>SQL</strong> Server Management StudioScenarioThe first exercise will focus on getting familiar with the <strong>SQL</strong> Server development tool.The main tasks for this exercise are as follows:1. Open Microsoft <strong>SQL</strong> Server Management Studio.2. Configure the editor settings. Task 1: Open Microsoft <strong>SQL</strong> Server Management Studio• Using <strong>SQL</strong> Server Management Studio (SSMS), connect to Proseware using Windows authentication (ifyou are connecting to an on-premises instance of <strong>SQL</strong> Server) or <strong>SQL</strong> Server authentication (if you areusing Windows Azure).• Close the Object Explorer and Solution Explorer windows.• Using the View menu, show the Object Explorer and Solution Explorer windows in SSMS. Task 2: Configure the editor settings• On the Tools menu, choose Options to open the Options window in SSMS and change the font sizeto 14 for the text editor.• Change several additional settings in the Options window:• Disable IntelliSense.• Change the tab size to 6 spaces for T-<strong>SQL</strong>.• Enable the option to include column headers when copying the result from the grid. Look underQuery Results, <strong>SQL</strong> Server, Results to Grid for the check box Include column headers whencopying or saving the results.Results: After this exercise, you should be able to open SSMS and configure different editor settings.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-23Exercise 2: Creating and Organizing T-<strong>SQL</strong> ScriptsScenarioUsually you will organize your T-<strong>SQL</strong> code in multiple query files inside one project. You will practice howto create a project and add different query files to it.The main tasks for this exercise are as follows:1. Create a project.2. Create a new query file and add it to the project. Task 1: Create a project• Create a new project called MyFirstProject and store it in the folder F:\10774A_Labs\10774A_01_PRJ.• Add a new query file to the created project and name it MyFirstQueryFile.sql.• Save the project and the query file by clicking the Save All option. Task 2: Add an additional query file• Add an additional query file called MySecondQueryFile.sql to the created project and save it.• Open Windows Explorer, navigate to the project folder, and observe the created files in the filesystem.• Back in SSMS, using Solution Explorer, remove the query file MySecondQueryFile.sql from the createdproject. (Choose the Remove option, not Delete.)• Again look in the file system. Is the file MySecondQueryFile.sql still there?• Now back in SSMS, remove the file MyFirstQueryFile.sql and this time choose the Delete option.Observe the files in Windows Explorer. What is different this time? Task 3: Reopen the created project• Save the project, close SSMS, reopen SSMS, and open the project MyFirstProject.• Drag and drop the query file MySecondQueryFile.sql from Windows Explorer to the Queries folderunder the project MyFirstProject in Solution Explorer. (Note: If the Solution Explorer window is notvisible, enable it as you did in exercise 1). Save the project.Results: After this exercise, you should have a basic understanding of how to create a project in SSMS andadd query files to it.


1-24 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Exercise 3: Using Books OnlineScenarioTo be effective in your training and exercises to come, you will practice how to use Books Online toefficiently check for T-<strong>SQL</strong> syntax.The main tasks for this exercise are as follows:1. Launch Books Online from the Windows Start menu.2. Configure offline usage.3. Search for the SELECT statement’s syntax.4. Copy some sample code, and paste it into the SSMS query editor.5. Use SSMS’s context-sensitive help. Task 1: Launch Books Online• Launch <strong>SQL</strong> Server Documentation (Books Online) from the Windows Start menu.• Configure Books Online to use the local help (offline) option and not the online help option. Task 2: Search for the SELECT syntax• Using the Index tab, find the syntax for the SELECT statement [<strong>SQL</strong> Server].• Browse the SELECT statement’s definition. Click the SELECT Examples (Transact-<strong>SQL</strong>) link underReference in the See Also section.• Back in SSMS, create a new query file named MyThirdQueryFile.sql and add it to the projectMyFirstProject. Copy and paste the first SELECT code sample from Books Online to the createdquery file. Task 3: Use context-sensitive help• Close Books Online.• In the query file MyThirdQueryFile.sql, highlight the ORDER BY clause and open Books Online bypressing the F1 key.• Browse the ORDER BY definition in Books Online.• Save the project and close it.Results: After this exercise, you should have an understanding how to open Books Online and usecontext-sensitive help.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 1-25Module ReviewReview Questions1. Can a <strong>SQL</strong> Server database be stored across multiple instances?2. If no T-<strong>SQL</strong> code is selected in a script window, which lines will be run when you click the Executebutton?3. What does a <strong>SQL</strong> Server Management Studio solution contain?


1-26 Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>


2-1Module 2Getting Started with <strong>SQL</strong> AzureContents:Lesson 1: Overview of <strong>SQL</strong> Azure 2-3


2-2 Getting Started with <strong>SQL</strong> AzureModule OverviewMicrosoft® <strong>SQL</strong> Azure is a cloud-based database service from Microsoft. A part of Microsoft's WindowsAzure platform-as-a-service solution, <strong>SQL</strong> Azure offers the database management services of onpremisesMicrosoft <strong>SQL</strong> Server® without requiring a local physical infrastructure. Just as you can writequeries against on-premises <strong>SQL</strong> Server, you will also be able to write most queries against a databasehosted by <strong>SQL</strong> Azure.In this module, you will learn how to set up an account, provision a server, and create a database in<strong>SQL</strong> Azure so that you will be prepared to perform the lab exercises in this course either on a local virtualmachine or in a <strong>SQL</strong> Azure database.ObjectivesAfter completing this module, you will be able to:• Describe the basic features of <strong>SQL</strong> Azure.• Connect to <strong>SQL</strong> Azure with <strong>SQL</strong> Server Management Studio (SSMS).


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 2-3Lesson 1Overview of <strong>SQL</strong> Azure<strong>SQL</strong> Azure is the database part of Microsoft's cloud platform, which provides cost-effective scalability,high availability, and reduced management overhead. <strong>SQL</strong> Azure can be used to augment an existing onpremises<strong>SQL</strong> Server infrastructure or support new applications without requiring local database servers tobe set up.In this lesson, you will learn some core concepts supporting <strong>SQL</strong> Azure, and some distinctions between<strong>SQL</strong> Azure and on-premises <strong>SQL</strong> Server. This lesson is not designed to be a comprehensive treatment of<strong>SQL</strong> Azure; it is intended to provide a basic foundation for those who will be writing queries against eithercloud-based or on-premises <strong>SQL</strong> Server databases.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the role of <strong>SQL</strong> Azure compared to on-premises <strong>SQL</strong> Server.• Describe key differences between <strong>SQL</strong> Azure and on-premises editions of <strong>SQL</strong> Server.• Describe how to connect to <strong>SQL</strong> Azure with SSMS.


2-4 Getting Started with <strong>SQL</strong> AzureWhat Is <strong>SQL</strong> Azure?<strong>SQL</strong> Azure is the database component of Microsoft's Windows Azure platform. <strong>SQL</strong> Azure is a rapidlydeveloping toolset, which at the time of this writing, includes database management, reporting, and datasync services, with import-export capabilities in development.Note <strong>SQL</strong> Azure is a moving target. Any information in this module was correct at time ofwriting, but <strong>SQL</strong> Azure may change without notice.A goal of <strong>SQL</strong> Azure is to provide quickly provisioned databases that scale to meet the needs of abusiness. Another goal is to remove the need to manage physical servers, including the operating system,from database management, which lets administrators primarily focus on the logical management of<strong>SQL</strong> Server. In contrast, in an on-premises deployment, administrators’ focus is split between the logicalmanagement and the physical management.Note The abstraction of physical servers from logical servers will be a key factor indifferentiating which features of <strong>SQL</strong> Server are supported by <strong>SQL</strong> Azure. For example,<strong>SQL</strong> Azure does not support access to the server's file system, which means that databasecreation statements that reference local files on an on-premises server will need to bemodified to run in <strong>SQL</strong> Azure.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 2-5From the perspective of the <strong>SQL</strong> Server query writer, <strong>SQL</strong> Azure operates much like a traditional onpremises<strong>SQL</strong> Server, with a few key distinctions, which will be covered in this lesson. You will be able towrite SELECT queries against tables and views, and invoke functions and stored procedures againstdatabases hosted in <strong>SQL</strong> Azure just as you would locally.For More Information Additional reading can be found on the <strong>SQL</strong> Azure Landing Pageat http://go.microsoft.com/fwlink/?LinkId=242837.


2-6 Getting Started with <strong>SQL</strong> AzureKey Concepts in <strong>SQL</strong> AzureBeyond the relational database engine provided by <strong>SQL</strong> Azure, it is necessary to understand the modelbehind the Azure platform so that you can set up your own account, provision a server, and createdatabases.There is a relationship between three core objects in <strong>SQL</strong> Azure: the account, the server, and the database.Azure objectAzure Account<strong>SQL</strong> Azure Server<strong>SQL</strong> AzureDatabaseDescriptionAccounts are the unit of subscription and billing. All Azure activity is metered andassigned to an account. You will first create an account, and then add servers. AnAzure account may have zero or more servers.<strong>SQL</strong> Azure servers, which belong to an account, are provisioned and assigned aDomain Name System (DNS) name, administrator accounts, and firewall rules.<strong>SQL</strong> Azure servers may have zero or more databases created within.<strong>SQL</strong> Azure databases, like databases in on-premises <strong>SQL</strong> Server, are containersfor data objects such as tables, views, functions, and procedures, as well as usersecurity accounts. Unlike on-premises <strong>SQL</strong> Server, <strong>SQL</strong> Azure does not exposesystem databases other than master.Therefore, the process of creating a <strong>SQL</strong> Azure database begins at the account level.Note Due to the relationship between account, server, and database, operations that spandatabases or span servers (e.g., cross-database queries, replication, or other high availabilitysetups) are not supported in <strong>SQL</strong> Azure. Therefore, careful evaluation of on-premisesapplications is needed before migrating to <strong>SQL</strong> Azure.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 2-7Key Distinctions Between <strong>SQL</strong> Server Azure and On-Premises <strong>SQL</strong> ServerAs you have learned, a goal of <strong>SQL</strong> Azure is the abstraction of the logical database administration fromthe physical administration. In <strong>SQL</strong> Azure, Microsoft administers physical hardware and storage. Yourorganization's administrators will still manage security, implement databases, and create database objectssuch as tables, views, and indexes. However, there are some key distinctions between how some of thesetasks are performed in a <strong>SQL</strong> Azure environment:Administrative task On-Premises <strong>SQL</strong> AzureServer-level securityaccount managementConfiguringauthenticationmechanismFirewall managementHardware and resourcemanagementLogins created at instance level.Mapped to Windows accounts orgroups.Can choose Windows Authenticationand/or <strong>SQL</strong> Server Authentication foraccount types and connections.Firewalls managed on physical serverusing operating system commands,typically limited to opening up wellknownports.Administrators have access to a widerange of monitoring and other typesof tools in order to manage low-levelresource usage. Backup and restorerequired for disaster recovery.Administrative accounts created inAzure Management Portal. Noconcept of instance-level userlogins.<strong>SQL</strong> Server Authentication onlymechanism supported. All access viausername/password combinations.By default, no access to <strong>SQL</strong> Azuredatabase except throughManagement Portal. Specific IPaddresses and ranges must beallowed to connect.Very limited access to server-levelinformation due to abstractionmodel. No support for backup andrestore.


2-8 Getting Started with <strong>SQL</strong> AzureIn addition, not all <strong>SQL</strong> Server database engine features are supported by <strong>SQL</strong> Azure, including multidatabaseand multi-server capabilities.For More Information For information on what T-<strong>SQL</strong> statements are currentlysupported, see http://go.microsoft.com/fwlink/?LinkId=242842. For more information on<strong>SQL</strong> Azure security administration, see http://go.microsoft.com/fwlink/?LinkId=242843.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 2-9Connecting to <strong>SQL</strong> Azure with SSMSNow that you have opened a Windows Azure account, provisioned a <strong>SQL</strong> Azure server, and created adatabase, you will be able to connect to your <strong>SQL</strong> Azure database from SSMS. While the process is quitesimilar to connecting to an on-premises <strong>SQL</strong> Server, there are some differences:• In the Connect to Server box, specify the <strong>SQL</strong> Azure server's four-part name in the form.database.windows.net.• In the Authentication box, choose <strong>SQL</strong> Server Authentication. Connecting to <strong>SQL</strong> Azure usingWindows Authentication is not supported.• In the Login box, provide the name of the <strong>SQL</strong> Azure administrator account in the AzureManagement Portal. Later, once individual user accounts have been created, you can use one of theminstead of an administrator account.• By default, you will connect to the master database. To connect to a user database instead, click theOptions button to expand the Connect to Server box and reveal the Connection Properties panel,which you can use to enter the name of the desired database.Note Remember that once a connection to a user database is made, you cannot switch toanother database without disconnecting and reconnecting to the next database. Switchingfrom the master database to a user database is supported by the SSMS GUI, but not in codewith the USE statement.


2-10 Getting Started with <strong>SQL</strong> AzureDemonstration: Connecting to <strong>SQL</strong> Azure with <strong>SQL</strong> ServerManagement StudioDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type in the Server Name text box, set Authentication to <strong>SQL</strong> Server Authentication, enter validadministrator credentials, and click Connect.1. From the File menu, click Open, click Project/Solution, navigate to F:\10774A_Labs\10774A_02_PRJ\10774A_2_PRJ.ssmssln and click Open.2. From the View menu, click Solution Explorer.3. To create and populate the sample database on the <strong>SQL</strong> Azure server, open the script file00 - -Setup.sql from within Solution Explorer and follow the instruction that are embedded asinline comments.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 2-11Module Review and TakeawaysReview Questions1. What authentication mechanism does <strong>SQL</strong> Azure use?2. How do you switch from one user database to another on a <strong>SQL</strong> Azure server?3. What choices are there for creating a database on a <strong>SQL</strong> Azure server


2-12 Getting Started with <strong>SQL</strong> Azure


3-1Module 3Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Contents:Lesson 1: Introducing T-<strong>SQL</strong> 3-3Lesson 2: Understanding Sets 3-21Lesson 3: Understanding Predicate Logic 3-25Lesson 4: Understanding the Logical Order of Operations in SELECT Statements 3-28Lab: Introduction to T-<strong>SQL</strong> <strong>Querying</strong> 3-35


3-2 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Module OverviewTransact-<strong>SQL</strong>, or T-<strong>SQL</strong>, is the language in which you will write your queries for Microsoft® <strong>SQL</strong> Server®<strong>2012</strong>. In this module, you will learn that T-<strong>SQL</strong> has many elements in common with other computerlanguages: commands, variables, functions, operators, and the like. You will also learn that T-<strong>SQL</strong> containssome unique elements that may require some adjustment if your background includes experience withprocedural languages. In order to make the most of your effort in writing T-<strong>SQL</strong> queries, you will alsolearn in this module the process by which <strong>SQL</strong> Server evaluates your queries. Understanding the logicalorder of operations of SELECT statements will be vital to learning how to write effective queries.ObjectivesAfter completing this module, you will be able to:• Describe the elements of T-<strong>SQL</strong> and their role in writing queries.• Describe the use of sets in <strong>SQL</strong> Server.• Describe the use of predicate logic in <strong>SQL</strong> Server.• Describe the logical order of operations in SELECT statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-3Lesson 1Introducing T-<strong>SQL</strong>In this lesson, you will learn the role of T-<strong>SQL</strong> in writing SELECT statements. You will learn about many ofthe elements of the T-<strong>SQL</strong> language and which elements will be useful to you in writing queries.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe Microsoft’s implementation of the standard <strong>SQL</strong> language.• Categorize <strong>SQL</strong> statements into their dialects.• Identify the elements of T-<strong>SQL</strong>, including predicates, operators, expressions, and comments.


3-4 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>About T-<strong>SQL</strong>T-<strong>SQL</strong> is Microsoft’s implementation of the industry standard Structured Query Language. Originallydeveloped to support the new relational data model at International Business Machines (IBM) in theearly 1970s, <strong>SQL</strong> has gone on to wide adoption in the industry. <strong>SQL</strong> became a standard of the AmericanNational Standards Institute (ANSI) and of the International Organization for Standardization (ISO) in the1980s.The ANSI standard has gone through several revisions, including <strong>SQL</strong>-89 and <strong>SQL</strong>-92, whose specificationsare either fully or partly supported by T-<strong>SQL</strong>. <strong>SQL</strong> Server <strong>2012</strong> also implements features from laterstandards, such as ANSI <strong>SQL</strong>-2008. Microsoft, like many vendors, has also extended the language toinclude <strong>SQL</strong> Server-specific features and functions.Besides Microsoft’s implementation as T-<strong>SQL</strong> in <strong>SQL</strong> Server, Oracle implements <strong>SQL</strong> as PL/<strong>SQL</strong>, IBMimplements it as <strong>SQL</strong> PL, and Sybase maintains its own implementation of T-<strong>SQL</strong>.An important concept to understand when working with T-<strong>SQL</strong> is that it is a set-based and declarativelanguage, not a procedural language. When you write a query to retrieve data from <strong>SQL</strong> Server, youdescribe the data you wish to display; you do not tell <strong>SQL</strong> Server exactly how to retrieve it. Instead ofproviding a procedural list of steps to take, you provide the attributes of the data you seek. For example, ifyou want to retrieve a list of customers who are located in Portland, a procedural method might look likethis:1) Open a cursor to consume rows, one at a time2) Fetch the first cursor record.3) Examine first row.4) If the city is Portland, return the row.5) Move to next row.6) If the city is Portland, return the row.7) Fetch the next record8) (Repeat until end of table is reached).


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-5Your procedural code must not only contain the logic to select the data that meets your needs, but youmust also determine and execute a well-performing path through the data.Note This course mentions cursors for comparative purposes, but does not providetraining on writing code with them. See Books Online for definitions and concernsregarding the use of cursors at http://go.microsoft.com/fwlink/?LinkId=242838.With a declarative language such as T-<strong>SQL</strong>, you will provide the attributes and values that describe the setyou wish to retrieve, such as the following pseudo-code:Display all customers whose city is Portland.With T-<strong>SQL</strong>, the <strong>SQL</strong> Server <strong>2012</strong> database engine will determine the optimal path to access the data andreturn a matching set. Your role is to learn to write efficient and accurate T-<strong>SQL</strong> code in order to properlydescribe the set you wish to retrieve.If you have a background in other programming environments, adopting a new mindset may present achallenge. This course has been designed to help you bridge the gap between procedural and set-baseddeclarative T-<strong>SQL</strong>.Note Sets will be discussed later in this module.


3-6 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Categories of T-<strong>SQL</strong> StatementsT-<strong>SQL</strong> statements can be organized into several categories:• Data Manipulation Language, or DML, is the set of T-<strong>SQL</strong> statements that focus on querying andmodifying data. This includes SELECT, the primary focus of this course, as well as modificationstatements such as INSERT, UPDATE, and DELETE. You will learn about SELECT statements throughoutthis course.• Data Definition Language, or DDL, is the set of T-<strong>SQL</strong> statements that handle the definition andlifecycle of database objects, such as tables, views, and procedures. This includes statements such asCREATE, ALTER, and DROP.• Data Control Language, or DCL, is the set of T-<strong>SQL</strong> statements used to manage security permissionsfor users and objects. DCL includes statements such as GRANT, REVOKE, and DENY.Note DCL commands are beyond the scope of this course. For more information about<strong>SQL</strong> Server <strong>2012</strong> security, including DCL, see Microsoft Official Course 10775: AdministeringMicrosoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases.For More Information Additional information on DML, DDL, and DCL commands can befound in Books Online at http://go.microsoft.com/fwlink/?LinkId=208761.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-7T-<strong>SQL</strong> Language ElementsLike many programming languages, T-<strong>SQL</strong> contains many elements that you will use in your queries.You will use predicates to filter rows, operators to perform comparisons, functions and expressions tomanipulate data or retrieve system information, and comments to document your code. If you need to gobeyond writing SELECT statements to create stored procedures, triggers, and other objects, you may useelements such as control-of-flow statements, variables to temporarily store values, and batch separators.The next several topics in this lesson will introduce you to many of these elements.Note The purpose of this lesson is to introduce many elements of the T-<strong>SQL</strong> language,which will be presented here at a high conceptual level. Subsequent modules in this coursewill provide more detailed explanations.


3-8 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>T-<strong>SQL</strong> Language Elements: Predicates and OperatorsThe T-<strong>SQL</strong> language provides elements for specifying and evaluating logical expressions. In SELECTstatements, you can use logical expressions to define filters for WHERE and HAVING clauses. You will writethese expressions using predicates and operators.Predicates supported by T-<strong>SQL</strong> include the following:• IN, used to determine whether a value matches any value in a list or subquery• BETWEEN, used to specify a range of values• LIKE, used to match characters against a patternOperators include several common categories:• Comparison for equality and inequality tests: =, , >=, , !< (Note that !>, !< and != arenot ISO standard. It is a best practice to use standard options when they exist.)• Logical, for testing the validity of a condition: AND, OR, NOT• Arithmetic, for performing mathematical operations: +, -, *, /, % (modulo)• Concatenation, for combining character strings: +• Assignment, for setting a value: =


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-9As with other mathematical environments, operators are subject to rules governing precedence. Thefollowing table describes the order in which T-<strong>SQL</strong> operators are evaluated:Order of EvaluationOperators1 ( ) Parentheses2 *, /, % (Multiply, Divide, Modulo)3 +, - (Add/Positive/Concatenate, Subtract/Negative)4 =, , >=, , !< (Comparison)5 NOT6 AND7 BETWEEN, IN, LIKE, OR8 = (Assignment)For More Information Information on other categories of operators, including bitwise,unary, and scope assignment, can be found in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242845.


3-10 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>T-<strong>SQL</strong> Language Elements: Functions<strong>SQL</strong> Server <strong>2012</strong> provides a wide range of functions available to your T-<strong>SQL</strong> queries. They range fromscalar functions such as SYSDATETIME, which return a single-valued result, to functions that operate onand return entire sets, such as the windowing functions you will learn about later in this course.As with operators, <strong>SQL</strong> Server functions can be organized into categories. Here are some commoncategories of scalar (single-value) functions available to you as you write your queries:• String functions• SUBSTRING, LEFT, RIGHT, LEN, DATALENGTH• REPLACE, REPLICATE• UPPER, LOWER, RTRIM, LTRIM• Date and time functions• GETDATE, SYSDATETIME, GETUTCDATE• DATEADD, DATEDIFF• YEAR, MONTH, DAY• Aggregate functions• SUM, MIN, MAX, AVG• COUNT, COUNTBIG• Mathematical functions• RAND, ROUND, POWER, ABS• CEILING, FLOOR


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-11Note The purpose of this lesson is to introduce many elements of the T-<strong>SQL</strong> language,which will be presented here at a high conceptual level. Subsequent modules in this coursewill provide more detailed explanations.For More Information Additional information on these functions, with sample code, canbe found in Books Online at http://go.microsoft.com/fwlink/?LinkId=233912.


3-12 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>T-<strong>SQL</strong> Language Elements: VariablesLike many programming languages, T-<strong>SQL</strong> provides a means of temporarily storing a value of a specificdata type. However, unlike other programming environments, all user-created variables are local to theT-<strong>SQL</strong> batch that created them, and visible only to that batch. There are no global or public variablesavailable to users in <strong>SQL</strong> Server.To create a local variable in T-<strong>SQL</strong>, you must provide a name, a data type, and an initial value. The namemust start with a single @ (at) symbol, and the data type must be system-supplied or user-defined andstored in the database your code will run against.Note You may find references in <strong>SQL</strong> Server literature, websites, etc., to so-called ‘‘systemvariables,’’ named with a double @@, such as @@ERROR. It is more accurate to refer tothese as system functions, since users may not assign a value to them. This course willdifferentiate user variables prefixed with a single @ from system functions prefixed with@@.If your variable is not initialized in the DECLARE statement, it will be created with a value of NULL and youcan subsequently assign a value with the SET statement. <strong>SQL</strong> Server 2008 introduced the capability toname and initialize a variable in the same statement.The following example creates a local integer variable called MyVar and assigns it an initial value of 30:DECLARE @MyVar int = 30;The following example creates a local date variable called MyDate and separately assigns it an initial valueof 15 Feb <strong>2012</strong>:DECLARE @MyDate date;SET @MyDate = '<strong>2012</strong>0215';


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-13You will learn more about data types, including dates, and about T-<strong>SQL</strong> variables, later in this course.Note If persistent storage or global visibility for a value is needed, consider creating atable in a database for that purpose. <strong>SQL</strong> Server provides both session-temporary andpermanent storage in databases. See http://go.microsoft.com/fwlink/?LinkId=209273 formore information on temporary tables and objects.


3-14 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>T-<strong>SQL</strong> Language Elements: ExpressionsT-<strong>SQL</strong> provides the use of combinations of identifiers, symbols, and operators that are evaluated by<strong>SQL</strong> Server to return a single result. These combinations are known as expressions.Expressions are a very useful and powerful tool for use in your queries. In SELECT statements, you mayuse expressions:• In the SELECT clause to operate on and/or manipulate columns• As CASE Expressions to replace values matching a logical expression with another value• In the WHERE clause to construct predicates for filtering rows• As table expressions to create temporary sets used for further processingNote The purpose of this lesson is to introduce many elements of the T-<strong>SQL</strong> language,which will be presented here at a high conceptual level. Subsequent modules in this coursewill provide more detailed explanations.Expressions may be based on a scalar (single-value) function, on a constant value, or on variables. Multipleexpressions may be joined using operators if they have the same data type or may be converted from alower precedence to a higher precedence (e.g., int to money).


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-15The following example of an expression operates on a column to add an integer to the results of the YEARfunction on a datetime column:SELECT YEAR(orderdate) AS currentyear, YEAR(orderdate) + 1 AS nextyearFROM Sales.Orders;Note The preceding example uses T-<strong>SQL</strong> techniques, such as column aliases and datefunctions, that will be covered later in this course.


3-16 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>T-<strong>SQL</strong> Language Elements: Control of Flow, Errors, and TransactionsWhile T-<strong>SQL</strong> is primarily a data retrieval language and not a procedural language, it does support alimited set of statements that provide some control of flow during execution.Some of the commonly used control-of-flow statements include:• IF . . .ELSE, for providing branching control based on a logical test.• WHILE, for repeating a statement or block of statements while a condition is true.• BEGIN . . .END, for defining the extents of a block of T-<strong>SQL</strong> statements.• TRY . . . CATCH, for defining structure exception handling (error handling).• BEGIN TRANSACTION, for marking a block of statements as part of an explicit transaction. Ended byCOMMIT TRANSACTION or ROLLBACK TRANSACTION.Note Control-of-flow operators are not used in standalone queries. If your primary role isas a report writer, for example, it is unlikely that you will need to use them. However, if yourresponsibilities include creating objects such as stored procedures and triggers, you will findthese elements useful.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-17T-<strong>SQL</strong> Language Elements: CommentsT-<strong>SQL</strong> provides two mechanisms for documenting code or for instructing the database engine to ignorecertain statements. Which method you will use will typically depend on the number of lines of code youwant ignored:• For single lines, or very few lines of code, use the -- (double dash) to precede the text to be markedas a comment. Any text following the dashes will be ignored by <strong>SQL</strong> Server.• For longer blocks of code, enclose the text between /* and */ characters. Any code between thecharacters will be ignored by <strong>SQL</strong> Server.The following example uses the -- (double dash) method to mark comments:-- This entire line of text will be ignored.DECLARE @MyVar int = 30; --only the text following the dashes will be ignored.The following example uses the /* comment block */ method to mark comments:*/*/This is comment text that will be ignored.Many query editing tools, such as SSMS or <strong>SQL</strong>CMD, will color-code commented text in a different colorthan the surrounding T-<strong>SQL</strong> code. In SSMS, use the Tools | Options dialog box to customize the colors andfonts used in the T-<strong>SQL</strong> script editor.


3-18 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>T-<strong>SQL</strong> Language Elements: Batch Separators<strong>SQL</strong> Server client tools, such as SSMS, send commands to the database engine in sets called batches. Ifyou are manually executing code, such as in a query editor, you can choose whether to send all of the textin a script as one batch. You may also choose to insert separators between certain sections of code.The specification of a batch separator is handled by your client tool. For example, the keyword GO is thedefault batch separator in SSMS. You can change this for the current query in Query | Query Options orglobally in Tools | Options | Query Execution.For most simple query purposes, batch separators are not used, as you will be submitting a single query ata time. However, when you need to create and manipulate objects, you may need to separate statementsinto distinct batches. For example, a CREATE VIEW statement may not be included in the same batch asother statements. The following example:CREATE TABLE t1 (col1 int);CREATE VIEW v1 as SELECT * FROM t1;returns the following error:Msg 111, Level 15, State 1, Line 2'CREATE VIEW' must be the first statement in a query batch.Note that user-declared variables are considered local to the batch in which they are declared. If avariable is declared in one batch and is referenced in another batch, the second batch would fail. Forexample, the following statements sent together as one batch work properly:DECLARE @cust int = 5;SELECT custid, companyname, contactnameFROM Sales.CustomersWHERE custid = @custid;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-19However, if a batch separator were inserted between the variable declaration and the query in which thevariable is used, an error would occur. The following example separates the variable declaration from itsuse in a query:DECLARE @cust int = 5;GOSELECT custid, companyname, contactnameFROM Sales.CustomersWHERE custid = @custid;It returns the following error:Msg 137, Level 15, State 2, Line 3Must declare the scalar variable "@custid".Note Variables will be covered in more depth later in this course.


3-20 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Demonstration: T-<strong>SQL</strong> Language ElementsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. From the File menu, click Open, click Project/Solution, navigateto F:\10774A_Labs\10774A_03_PRJ\10774A_03_PRJ.ssmssln, and click Open.2. On the View menu, click Solution Explorer. Open and execute the 00 - -Setup.sql script file fromwithin Solution Explorer.3. Open the 11 - -Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-21Lesson 2Understanding SetsThe purpose of this lesson is to introduce the concepts of the set theory, one of the mathematicalunderpinnings of relational databases, and to help you apply it to how you think about querying<strong>SQL</strong> Server.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the role of sets in a relational database.• Understand the impact of sets on your T-<strong>SQL</strong> queries.• Describe attributes of sets that may require special treatment in your queries.


3-22 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Set Theory and <strong>SQL</strong> ServerThe set theory is one of the mathematical foundations of the relational model and hence is foundationalfor working with <strong>SQL</strong> Server <strong>2012</strong>. While you might be able to go a long way writing queries in T-<strong>SQL</strong>without an appreciation of sets, you may eventually have difficulty expressing some queries in a single,well-performing statement.This lesson will set the stage for you to begin "thinking in sets" and understanding the nature of sets. Inturn, this will make it easier for you to:• Take advantage of set-based statements in T-<strong>SQL</strong>.• Understand why you still need to sort your query output.• Understand why a set-based, declarative approach rather than procedural approach works best with<strong>SQL</strong> Server <strong>2012</strong>.Without delving into the mathematics supporting the set theory, we can define a set, for our purposes, as"a collection of definite, distinct objects considered as a whole." In terms applied to <strong>SQL</strong> Server databases,we can think of a set as a single unit (such as a table) that contains zero or more members of the sametype. For example, a Customers table represents a set, specifically the set of all customers. You will also seethat the results of a SELECT statement also form a set, which will have important ramifications whenlearning about subqueries and table expressions, for example.As you learn more about certain T-<strong>SQL</strong> query statements, it will be important to think of the entire set atall times, instead of thinking of individual members. This will better equip you to write set-based code,instead of thinking one row at a time. Working with sets requires thinking in terms of operations thatoccur "all at once" instead of one-at-a-time. This may be an adjustment for you, depending on yourbackground.After "collection," the next critical term in our definition is "distinct," or unique. All members of a set mustbe unique. In <strong>SQL</strong> Server, uniqueness is typically implemented using keys, such as a primary key column.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-23However, once you start working with subsets of data, it will be important to keep mindful of how you willbe able to uniquely address each member of a set.This brings us back to the consideration of the set as a "whole." Noted <strong>SQL</strong> language author Joe Celkosuggests mentally adding the phrase "Set of all…" in front of the names of <strong>SQL</strong> objects that represent sets("set of all customers," for example). This will help you remember that you are addressing a collection ofelements when you write T-<strong>SQL</strong> code, not just one element at a time.One important consideration is what's omitted from the set theory: any requirement regarding the orderof elements in a set. In short, there is no predefined order in a set. Elements may be addressed (andretrieved) in any order. Applied to your queries, this means that if you need to return results in a certainorder, you will need to use the ORDER BY clause in your SELECT statements. You will learn more aboutORDER BY later in this course.For More Information More information on the set theory and its application to <strong>SQL</strong>Server queries can be found in Chapter 1 of Itzik Ben-Gan’s Inside Microsoft® <strong>SQL</strong> Server®2008: T-<strong>SQL</strong> <strong>Querying</strong> (Microsoft Press, 2009) and Chapter 2 of Itzik Ben-Gan’s Microsoft<strong>SQL</strong> Server 2008: T-<strong>SQL</strong> Fundamentals (Microsoft Press, 2008). For more information on theuse of "Set of all…" see Joe Celko's Thinking in Sets (Morgan Kaufman, 2008).


3-24 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Set Theory Applied to <strong>SQL</strong> Server QueriesGiven the set-based foundation of databases, there are a few considerations and recommendations to beaware of when writing efficient T-<strong>SQL</strong> queries:• Act on the whole set at once. This translates to querying the whole table at once, instead of cursorbasedor iterative processing.• Use declarative, set-based processing. Tell <strong>SQL</strong> Server what you want to retrieve by describing itsattributes, not by navigating to its position.• Ensure that you are addressing elements via their unique identifiers, such as keys, when possible. Forexample, write JOIN clauses referencing unique keys on one side of the relationship.• Provide your own sorting instructions because result sets are not guaranteed to be returned inany order.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-25Lesson 3Understanding Predicate LogicAlong with set theory, predicate logic is another mathematical foundation for the relational databasemodel, and with it, <strong>SQL</strong> Server <strong>2012</strong>. Unlike the set theory, you probably have a fair amount of experiencewith predicate logic, even if you have never used the term to describe it. This lesson will introducepredicate logic and examine its application to querying <strong>SQL</strong> Server.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the role of predicate logic in a relational database.• Understand the use of predicate logic on your T-<strong>SQL</strong> queries.


3-26 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Predicate Logic and <strong>SQL</strong> ServerIn theory, predicate logic is a framework for expressing logical tests that return true or false. A predicate isa property or expression that is true or false. You may have heard this referred to as a Boolean expression.Taken by themselves, predicates make comparisons and express the results as true or false. However, inT-<strong>SQL</strong>, predicates don't stand alone. They are usually embedded in a statement that does something withthe true/false result, such as a WHERE clause to filter rows, a CASE expression to match a value, or even acolumn constraint governing the range of acceptable values for that column in a table's definition.There’s one important omission in the formal definition of a predicate: how to handle unknown, ormissing, values. If a database is set up so that missing values are not permitted (through constraints,or default value assignments), then perhaps this is not an important omission. But in most real-worldenvironments, you will have to account for missing or unknown values, which will require you to extendyour understanding of predicates from two possible outcomes (true or false) to three: true, false, orunknown.The use of NULLs as a mark for missing data will be further discussed in the next topic, as well as later inthis course.For More Information More information on predicate logic and its application to <strong>SQL</strong>Server queries can be found in Chapter 1 of Itzik Ben-Gan’s Inside Microsoft® <strong>SQL</strong> Server®2008: T-<strong>SQL</strong> <strong>Querying</strong> (Microsoft Press 2009) and Chapter 2 of Itzik Ben-Gan’s Microsoft <strong>SQL</strong>Server 2008: T-<strong>SQL</strong> Fundamentals (Microsoft Press 2008).


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-27Predicate Logic Applied to <strong>SQL</strong> Server QueriesAs you have been learning, the ability to use predicates to express comparisons in terms of true, false,or unknown is vital to writing effective queries in <strong>SQL</strong> Server. Although we have been discussing themseparately, predicates do not stand alone, syntactically speaking. You will typically use predicates in any ofthe following roles within your queries:• Filtering data (in WHERE and HAVING clauses)• Providing conditional logic to CASE expressions• Joining tables (in the ON filter)• Defining subqueries (in EXISTS tests, for example)Additionally, predicates have uses outside SELECT statements, such as in CHECK constraints to limit valuespermitted in a column, and in control- -of-flow elements, such as an IF statement.In mathematics, we only need to consider values that are present, so predicates can result only in true orfalse values. (This is known in predicate logic as the law of the excluded middle.) Yet in databases, you willlikely have to account for missing values, and the interaction of T-<strong>SQL</strong> predicates with missing valuesresults in an unknown. Ensure that you have accounted for all three possible outcomes----true, false, orunknown----when you are designing your query logic. You will learn how to use three-valued logic inWHERE clauses later in this course.Note The purpose of this lesson is to introduce many elements of the T-<strong>SQL</strong> language,which will be presented here at a high conceptual level. Subsequent modules in this coursewill provide more detailed explanations.


3-28 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Lesson 4Understanding the Logical Order of Operations in SELECTStatementsT-<strong>SQL</strong> is unusual as a programming language in one key aspect: the order in which you write a statementis not necessarily the order in which the database engine will evaluate and process it. Database enginesmay optimize their execution of a query, as long as the correctness of the result (as determined by thelogical order) is retained. As a result, unless you learn the logical order of operations, you may find bothconceptual and practical obstacles to writing your queries. This lesson will introduce the elements of aSELECT statement, delineate the order in which the elements are evaluated, and then apply thisunderstanding to a practical approach to writing queries.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the elements of a SELECT statement.• Understand the order in which clauses in a SELECT statement are evaluated.• Apply your understanding of the logical order of operations to writing SELECT statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-29Elements of a SELECT StatementIn order to accomplish our goal of understanding the logical order of operations, we need to look ata SELECT statement as a whole, including a number of optional elements. However, this lesson is notdesigned to provide detailed information about these elements. Each part of a SELECT statement will bediscussed in subsequent modules. However, understanding the details of a WHERE clause, for example, isnot required in order to understand its place in the sequence of events.A SELECT statement is made up of a combination of mandatory and optional elements. Strictly speaking,<strong>SQL</strong> Server only requires a SELECT clause in order to execute without error. A SELECT clause without aFROM clause operates as though you were selecting from an imaginary table containing one row. (Youwill see this behavior later in this course when you test variables.) However, since a SELECT clause withouta FROM clause cannot retrieve data from a table, we will treat standalone SELECT clauses as a special casethat is not directly relevant to this lesson. Let's examine the elements, their high-level role in a SELECTstatement, and the order in which they are evaluated by <strong>SQL</strong> Server.Not all elements will be present in every SELECT query. However, when an element is present, it will alwaysbe evaluated in the same order with respect to the other elements present. For example, a WHERE clausewill always be evaluated after the FROM clause and before a GROUP BY clause, if one exists.Let's move on to the discussion of the order of these operations in the next topic.Note For the purposes of this lesson, additional optional elements such as DISTINCT,OVER, and TOP are omitted. They will be introduced and their order discussed in latermodules.


3-30 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Logical Query ProcessingThe order in which a SELECT statement is written is not the order in which the <strong>SQL</strong> Server database engineevaluates and processes the statement. Consider the following query:USE T<strong>SQL</strong><strong>2012</strong>;SELECT empid, YEAR(orderdate) AS orderyearFROM Sales.OrdersWHERE custid =71GROUP BY empid, YEAR(orderdate)HAVING COUNT(*) > 1ORDER BY empid, orderyear;Before we examine the runtime order of operations, let's briefly examine what the query does, althoughdetails on many of the clauses will need to wait until the appropriate module. The first line ensures we'reconnected to the correct database for the query. This line is not being examined for its runtime order. Weneed this to complete (if necessary) before the main SELECT query executes:USE T<strong>SQL</strong><strong>2012</strong>; -- change connection context to sample databaseThe next line is the start of the SELECT statement as we wrote it, but as we'll see, it will not be the first lineevaluated. The SELECT clause returns the empid column and extracts just the year from the orderdatecolumn:SELECT empid, YEAR(orderdate) AS orderyearThe FROM clause identifies which table is the source of the rows for the query:FROM Sales.Orders


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-31The WHERE clause filters the rows out of the Sales.Orders table, keeping only those that satisfy thepredicate:WHERE custid =71The GROUP BY clause groups together the remaining rows by empid and then by the year of the order:GROUP BY empid, YEAR(orderdate)After the groups are established, the HAVING clause filters the groups based on its predicate. Onlyemployees with more than one sale per customer in a given year will pass this filter:HAVING COUNT(*) > 1The final clause, for the purposes of previewing this query, is the ORDER BY, which sorts the output byempid and then by year:ORDER BY empid, orderyear;Now that we've established what each clause does, let's look at the order in which <strong>SQL</strong> Server mustevaluate them:1. The FROM clause is evaluated first, to provide the source rows for the rest of the statement. (Later inthe course we'll see how to join multiple tables together in a FROM clause.) A virtual table is createdand passed to the next step.2. The WHERE clause is next to be evaluated, filtering those rows from the source table that match apredicate. The filtered virtual table is passed to the next step.3. GROUP BY is next, organizing the rows in the virtual table according to unique values found in theGROUP BY list. A new virtual table is created, containing the list of groups, and passed to the nextstep.Note From this point in the flow of operations, only columns in the GROUP BY list oraggregate functions may be referenced by other elements. This will have a significantimpact on the SELECT list.4. The HAVING clause is evaluated next, filtering out entire groups based on its predicate. The virtualtable created in step 3 is filtered and passed to the next step.5. The SELECT clause finally executes, determining which columns will appear in the query results.Note Because the SELECT clause is evaluated after the other steps, any column aliasescreated in the SELECT clause cannot be used in clauses processed in steps 1-4.The last clause to execute in our example is the ORDER BY clause, sorting the rows asdetermined in its column list.


3-32 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>To apply this to our example query, here is the logical order at runtime, with the USE statement omittedfor clarity:5. SELECT empid, YEAR(orderdate) AS orderyear1. FROM Sales.Orders2. WHERE custid =713. GROUP BY empid, YEAR(orderdate)4. HAVING COUNT(*) > 16. ORDER BY empid, orderyear;As we have seen, in T-<strong>SQL</strong> we do not write queries in the same order in which they are logically evaluated.Since the runtime order of evaluation determines what data is available to clauses downstream from oneanother, it's important to understand the true logical order when writing your queries.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-33Applying the Logical Order of Operations to Writing SELECT StatementsNow that you have learned the logical order of operations when a SELECT query is evaluated andprocessed, keep in mind the following considerations when writing a query. Note that some of these mayrefer to details you will learn in subsequent modules:• Decide which tables you will query first, as well as any table aliases you will apply. This will determineyour FROM clause.• Decide which set or subset of rows will be retrieved from the table(s) in the FROM clause, and howyou will express your predicate. This will determine your WHERE clause.• If you will be grouping rows, decide which columns will be grouped on. Remember that only columnsin the GROUP BY clause, as well as aggregate functions such as COUNT, may ultimately be included inthe SELECT clause.• If you need to filter out groups, decide on your predicate and build your HAVING clause. It's theresults of this phase that become the input to the SELECT clause.• If you are not using GROUP BY, determine which columns from the source table(s) you wish todisplay, and use any table aliases you created to refer to them. This will become the core of yourSELECT clause. If you have used a GROUP BY clause, select from the columns in the GROUP BY clause,and add any additional aggregates to the SELECT list.• Finally, remember that sets do not include any ordering, and as a result, you will need to add anORDER BY clause to guarantee a sort order if it's desired.


3-34 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Demonstration: Logical Query ProcessingDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. From the File menu, click Open, click Project/Solution, navigateto F:\10774A_Labs\10774A_03_PRJ\10774A_03_PRJ.ssmssln, and click Open.2. From the View menu, click Solution Explorer. Open and execute the 00 - -Setup.sql script file fromwithin Solution Explorer.3. Open the 21 - -Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-35Lab: Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Lab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the ‘‘Press CTRL+ALT+DELETE to log on’’message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the ‘‘Press CTRL+ALT+DELETE to log on’’message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


3-36 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft® <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft <strong>SQL</strong> Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.13. On the File menu, click Open and click Project / Solution. In the Project Open window, selectproject F:\10774A_Labs\10774A_03_PRJ\10774A_03_PRJ.ssmssln.14. In Solution Explorer, double-click 00 - Setup.sql. (If Solution Explorer is not visible, select SolutionExplorer on the View menu or press Ctrl+Alt+L on the keyboard.)15. When the query window opens, follow the instructions inside the 00 -- Setup.sql to setup theT<strong>SQL</strong><strong>2012</strong> database and populate it with sample data.16. Close the <strong>SQL</strong> Server Management Studio.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports against corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. In order for you to become more comfortable with <strong>SQL</strong> Server querying, theAdventure Works IT department has provided you with a selection of common queries to run against theirdatabases. You will review and execute these queries.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-37Exercise 1: Executing Basic SELECT StatementsScenarioThe T-<strong>SQL</strong> script provided by the IT department includes a SELECT statement that retrieves all rows fromthe HR.Employees table, which includes the firstname, lastname, city, and country columns. You willexecute the T-<strong>SQL</strong> script against the T<strong>SQL</strong><strong>2012</strong> database.The main tasks for this exercise are as follows:1. Open the T-<strong>SQL</strong> script using Microsoft <strong>SQL</strong> Server Management Studio.2. Execute the T-<strong>SQL</strong> script. Task 1: Open the T-<strong>SQL</strong> script using Microsoft <strong>SQL</strong> Server Management Studio• Using <strong>SQL</strong> Server Management Studio (SSMS), connect to Proseware using Windows authentication (ifyou are connecting to an on-premises instance of <strong>SQL</strong> Server) or <strong>SQL</strong> Server authentication (if you areusing <strong>SQL</strong> Azure).• Open the project file F:\10774A_Labs\10774A_03_PRJ\10774A_03_PRJ.ssmssln.• Create and populate database T<strong>SQL</strong><strong>2012</strong>:• For on-premise, database T<strong>SQL</strong><strong>2012</strong> is already created and populated in the VM so no furthersteps are needed. However, if the database was damaged and you would like to create it fromscratch, follow the step below.• For Microsoft <strong>SQL</strong> Azure, follow the step below if you haven’t done so already in module 02.• To create and populate the sample database open the 00 - -Setup.sql script file from within SolutionExplorer and follow the instructions that are embedded as inline comments.• Open the T-<strong>SQL</strong> script 51 - Lab Exercise 1.sql. Task 2: Execute the T-<strong>SQL</strong> script• Execute the script by clicking Execute on the toolbar (or press F5 on the keyboard). This will executethe whole script.• Observe the result and the database context.• Which database is selected in the Available Databases box? Task 3: Execute a part of the T-<strong>SQL</strong> script• Highlight the SELECT statement in the T-<strong>SQL</strong> script under the task 2 description and click Execute.• Observe the result. You should get the same result as in task 2.Tip One way to highlight a portion of code is to hold down the Alt key while drawing arectangle around it with your mouse. The code inside the drawn rectangle will be selected.Try it.Results: After this exercise, you should know how to open the T-<strong>SQL</strong> script and execute the whole scriptor just a specific statement inside the script.


3-38 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Exercise 2: Executing Queries That Filter Data Using PredicatesScenarioThe next T-<strong>SQL</strong> script is very similar to the first one. The SELECT statement retrieves the same columnsfrom the HR.Employees table, but it uses a predicate in the WHERE clause to retrieve only rows that havethe value USA in the country column.The main tasks for this exercise are as follows:1. Execute the T-<strong>SQL</strong> script.2. Apply the needed changes and execute the T-<strong>SQL</strong> script. Task 1: Execute the T-<strong>SQL</strong> script• Close all open script files.• Open the project file F:\10774A_Labs\10774A_03_PRJ\10774A_03_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Execute the whole script.• You get an error. What is the error message? Why do you think you got this error? Task 2: Apply needed changes and execute the T-<strong>SQL</strong> script• Apply the needed changes to the script so that it will run without an error. (Hint: The SELECTstatement is not the problem. Look at what is selected in the Available Databases box.) Test thechanges by executing the whole script.• Observe the result. Notice that the result has fewer rows than the result in exercise 1, task 2. Task 3: Uncomment the USE statement• Comments in T-<strong>SQL</strong> scripts can be written inside the line by specifying --. The text after the twohyphens will be ignored by <strong>SQL</strong> Server. You can also specify a comment as a block starting with /*and ending with */. The text in between is treated as a block comment and is ignored by <strong>SQL</strong> Server.• Uncomment the USE T<strong>SQL</strong><strong>2012</strong>; statement.• Save and close the T-<strong>SQL</strong> script. Open the T-<strong>SQL</strong> script 61 - Lab Exercise 2.sql again. Execute thewhole script.• Why did the script execute with no errors?• Observe the result and notice the database context in the Available Databases box.Results: After this exercise, you should have a basic understanding of database context and how tochange it.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 3-39Exercise 3: Executing Queries That Sort Data Using ORDER BYScenarioThe last T-<strong>SQL</strong> script provided by the IT department has a comment: ‘‘This SELECT statement returns firstname, last name, city and country information for all employees from the USA, ordered by last name.’’The main tasks for this exercise are as follows:1. Execute the T-<strong>SQL</strong> script.2. Uncomment the needed T-<strong>SQL</strong> statements and execute them. Task 1: Execute the T-<strong>SQL</strong> script• Open the project file F:\10774A_Labs\10774A_03_PRJ\10774A_03_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Execute the whole script.• Observe the results. Why is the result window empty? Task 2: Uncomment the needed T-<strong>SQL</strong> statements and execute them• Observe that before the USE statement there are the characters -- which means that the USEstatement is treated as a comment. There is also a block comment around the whole T-<strong>SQL</strong> SELECTstatement. Uncomment both statements.• First execute the USE statement and then execute the statement starting with the SELECT clause.• Observe the results. Notice that the results have the same rows as in exercise 1, task 2, but they aresorted by the lastname column.Results: After this exercise, you should have an understanding how comments can be specified insideT-<strong>SQL</strong> scripts.


3-40 Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Module ReviewReview Questions1. Which category of T-<strong>SQL</strong> statements concerns querying and modifying data?2. What are some examples of aggregate functions supported by T-<strong>SQL</strong>?3. Which SELECT statement element will be processed before a WHERE clause?


4-1Module 4Writing SELECT QueriesContents:Lesson 1: Writing Simple SELECT Statements 4-3Lesson 2: Eliminating Duplicates with DISTINCT 4-10Lesson 3: Using Column and Table Aliases 4-18Lesson 4: Writing Simple CASE Expressions 4-25Lab: Writing Basic SELECT Statements 4-30


4-2 Writing SELECT QueriesModule OverviewThe SELECT statement is used to query tables and views. You may also perform some manipulation of thedata with SELECT before returning the results. It is likely that you will use the SELECT statement more thanany other single statement in T-<strong>SQL</strong>. This module introduces you to the fundamentals of the SELECTstatement, focusing on queries against a single table.ObjectivesAfter completing this module, you will be able to:• Write simple SELECT statements.• Eliminate duplicates using the DISTINCT clause.• Use column and table aliases.• Write simple CASE expressions.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-3Lesson 1Writing Simple SELECT StatementsIn this lesson, you will learn the structure and format of the SELECT statement, as well as enhancementsthat will add functionality and readability to your queries.Lesson ObjectivesAfter completing this lesson, you will be able to:• Understand the elements of the SELECT statement.• Write simple single-table SELECT queries.• Eliminate duplicate rows using the DISTINCT clause.• Add calculated columns to a SELECT clause.


4-4 Writing SELECT QueriesElements of the SELECT StatementThe SELECT and FROM clauses are the primary focus of this module. You will learn more about the otherclauses in later modules of this course. However, your understanding of the order of operations in logicalquery processing, from earlier in the course, will remain important to understanding the proper way towrite SELECT queries.Remember that the FROM, WHERE, GROUP BY, and HAVING clauses will have been evaluated before thecontents of the SELECT clause are processed. Therefore, elements you write in the SELECT clause,especially calculated columns and aliases, will not be visible to the other clauses.For More Information Additional information on SELECT elements can be found athttp://go.microsoft.com/fwlink/?LinkId=242846.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-5Retrieving Columns from a Table or ViewThe SELECT clause specifies the columns from the source table(s) or view(s) that you want to return as theresult set of the query. In addition to columns from the source table, you may add columns in the form ofcalculated expressions.The FROM clause specifies the name of the table or view that is the source of the columns in the SELECTclause. To avoid errors in name resolution, it is a best practice to specify both the schema and objectname of the table, in the form SCHEMA.OBJECT, such as Sales.Customers.If the table or view name contains irregular characters, such as spaces or other special characters, you willneed to delimit, or enclose, the name. T-<strong>SQL</strong> supports the use of the ANSI standard double quotes "SalesOrder Details" and the <strong>SQL</strong> Server-specific square brackets [Sales Order Details].End all statements with a semicolon (;) character. In the current version of <strong>SQL</strong> Server <strong>2012</strong>, semicolons arean optional terminator for most statements. However, future versions will require its use. For those currentusages when a semicolon is required, such as some common table expressions (CTEs) and some ServiceBroker statements, the error messages returned for a missing semicolon are often cryptic. Therefore, youshould adopt the practice of terminating all statements with a semicolon.Note CTEs will be covered later in this course. For information on Service Broker, seeMicrosoft Course 10776: Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases or BooksOnline.


4-6 Writing SELECT QueriesDisplaying ColumnsTo display columns in a query, you need to create a comma-delimited column list. The order of thecolumns in your list will determine their display in the output, regardless of the order in which they aredefined in the source table. This gives your queries the ability to absorb changes that others may make tothe structure of the table, such as adding or reordering the columns.T-<strong>SQL</strong> supports the use of the asterisk, or ‘‘star’’ character (*) to substitute for an explicit column list. Thiswill retrieve all columns from the source table. While suitable for a quick test, avoid using the * inproduction work, as changes made to the table will cause the query to retrieve all current columns in thetable’s current defined order. This could cause bugs or other failures in reports or applications expecting aknown number of columns returned in a defined order.By using an explicit column list in your SELECT clause, you will always get the desired results, as long asthe columns exist in the table. If a column is dropped, you will receive an error that will help you identifythe problem and fix your query.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-7Using Calculations in the SELECT ClauseIn addition to retrieving columns stored in the source table, a SELECT statement can perform calculationsand manipulations. Calculations can manipulate the source column data and can use built-in T-<strong>SQL</strong>functions, which you will learn about later in this course.Since the results will appear in a new column, repeated once per row of the result set, calculatedexpressions in a SELECT clause must be scalar. In other words, they must return only a single value.Calculated expressions may operate on other columns in the same row, on built-in functions, or acombination of the two:SELECT unitprice, qty, (unitprice * qty)FROM Sales.OrderDetails;The results appear as follows:unitpriceqty--------------------- ------ ---------------------14.00 12 168.009.80 10 98.0034.80 5 174.0018.60 9 167.40Note that the new calculated column does not have a name returned with the results. To provide a name,you will use a column alias, which you will learn about later in this module.To use a built-in T-<strong>SQL</strong> function on a column in the SELECT list, you pass the name of the column to thefunction as an input:SELECT empid, lastname, hiredate, YEAR(hiredate)FROM HR.Employees;


4-8 Writing SELECT QueriesThe results:empid lastname hiredate----------- -------------------- ----------------------- -------1 Davis 2002-05-01 00:00:00.000 20022 Funk 2002-08-14 00:00:00.000 20023 Lew 2002-04-01 00:00:00.000 2002You will learn more about date functions, as well as others, later in this course. The use of YEAR in thisexample is provided only to illustrate calculated columns.Note Not all calculations will be recalculated for each row. <strong>SQL</strong> Server may calculate afunction’s result once at the time of query execution, and reuse the value for each row. Thiswill be discussed later in the course.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-9Demonstration: Writing Simple SELECT StatementsDemonstration Setup1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. From the File menu, click Open, click Project/Solution, navigateto F:\10774A_Labs\10774A_04_PRJ\10774A_04_PRJ.ssmssln, and click Open.2. On the View menu, click Solution Explorer. Open and execute the 00 - -Setup.sql script file fromwithin Solution Explorer.3. Open the 11 - -Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


4-10 Writing SELECT QueriesLesson 2Eliminating Duplicates with DISTINCTT-<strong>SQL</strong> queries may display duplicate rows, even if the source table has a key column enforcinguniqueness. Typically, this is the case when you retrieve only a few of the columns in a table. In this lesson,you will learn how to eliminate duplicates using the DISTINCT clause.Lesson ObjectivesIn this lesson, you will learn to:• Understand how T-<strong>SQL</strong> query results are not true sets and may include duplicates.• Understand how DISTINCT may be used to remove duplicate rows from the SELECT results.• Write SELECT DISTINCT clauses.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-11<strong>SQL</strong> Sets and Duplicate RowsWhile the theory of relational databases calls for unique rows in a table, in practice T-<strong>SQL</strong> query resultsare not true sets. The rows retrieved by a query are not guaranteed to be unique, even when they comefrom a source table that uses a primary key to differentiate each row. Nor are the rows guaranteed to bereturned in any particular order, which you will learn how to address with ORDER BY later in this course.Add to this the fact that the default behavior of a SELECT statement is to include the keyword ALL, andyou can begin to see why duplicate values might be returned by a query, especially when you includeonly some of the columns in a table (and omit the unique columns).For example, consider a query that retrieves country names from the Sales.Customers table:SELECT countryFROM Sales.Customers;


4-12 Writing SELECT QueriesA partial result shows many duplicate country names, which at best is too long to be easy to interpret. Atworst, it gives a wrong answer to the question ‘‘How many countries are represented among ourcustomers?’’country-------GermanyMexicoMexicoUKSwedenGermanyGermanyFranceUKAustriaBrazilSpainFranceSweden...GermanyFranceFinlandPoland(91 row(s) affected)The reason for this output is that, by default, a SELECT clause contains a hidden default ALL statement:SELECT ALL countryFROM Sales.Customers;In the absence of further instruction, the query will return one result for each row in the Sales.Customerstable, but since only the country column is specified, you will see only that column for all 91 rows.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-13Understanding DISTINCTReplacing the default SELECT ALL clause with SELECT DISTINCT will filter out duplicates in the result set.SELECT DISTINCT specifies that the result set must contain only unique rows. However, it is important tounderstand that the DISTINCT option operates only on the set of columns returned by the SELECT clause.It does not take into account any other unique columns in the source table. DISTINCT also operates on allof the columns in the SELECT list, not just the first column.The logical order of operations also ensures that the DISTINCT operator will remove rows that may havealready been processed by WHERE, HAVING, and GROUP BY clauses.Continuing the previous example of countries from the Sales.Customers table, to eliminate the duplicatevalues, replace the silent ALL default with DISTINCT:SELECT DISTINCT countryFROM Sales.Customers;


4-14 Writing SELECT QueriesThis will yield the desired results. Note that while the results appear to be sorted, this is not guaranteed by<strong>SQL</strong> Server. The result set now contains only one instance of each unique output row:Country---------ArgentinaAustriaBelgiumBrazilCanadaDenmarkFinlandFranceGermanyIrelandItalyMexicoNorwayPolandPortugalSpainSwedenSwitzerlandUKUSAVenezuela(21 row(s) affected)Note You will learn additional methods for filtering out duplicate values later in thiscourse. Once you have learned them, you may wish to consider the relative performancecosts of filtering with SELECT DISTINCT versus those other means.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-15SELECT DISTINCT SyntaxRemember that DISTINCT looks at rows in the output set, created by the SELECT clause. Therefore, onlyunique combinations of column values will be returned by a SELECT DISTINCT clause. For example, if youquery a table with the following data in it, you might observe that there are only four unique first namesand four unique last names:SELECT firstname, lastnameFROM Sales.Customers;The results:firstname lastname---------- --------------------Sara DavisDon FunkSara LewDon DavisJudy LewJudy FunkYael PeledHowever, a SELECT DISTINCT query against both columns will retrieve all unique combinations of the twocolumns, which in this case is the same seven employees. For a list of unique first names only, execute aSELECT DISTINCT only against the firstname column:SELECT DISTINCT firstnameFROM Sales.Customers;


4-16 Writing SELECT QueriesThe results:firstname----------DonJudySaraYael(4 row(s) affected)A challenge in designing such queries is that while you may need to retrieve a distinct list of values fromone column, you might need to see additional attributes (columns) from other columns. Later in thiscourse, you will see how to combine DISTINCT with the GROUP BY clause as a way of further processingand displaying information about distinct lists of values.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-17Demonstration: Eliminating Duplicates with DISTINCTDemonstration Setup1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. From the File menu, click Open, click Project/Solution, navigateto F:\10774A_Labs\10774A_04_PRJ\10774A_04_PRJ.ssmssln and click Open.2. From the View menu, click Solution Explorer.3. Open the 21 - -Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


4-18 Writing SELECT QueriesLesson 3Using Column and Table AliasesWhen retrieving data from a table or view, a T-<strong>SQL</strong> query will name each column after its source. Ifdesired, columns may be relabeled by the use of aliases in the SELECT clause. However, columns createdwith expressions will not be named automatically. Column aliases may be used to provide custom columnheaders. At the table level, aliases may be used in the FROM clause to provide a convenient way ofreferring to a table elsewhere in the query, enhancing readability.Lesson ObjectivesIn this lesson you will learn how to:• Use aliases to refer to columns in a SELECT list.• Use aliases to refer to columns in a FROM clause.• Understand the impact of the logical order of query processing on aliases.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-19Using Aliases to Refer to ColumnsColumn aliases can be used to relabel columns when returning the results of a query. For example, crypticnames of columns in a table such as qty may be replaced with quantity.Expressions that are not based on a source column in the table will not have a name provided in the resultset. This includes calculated expressions and function calls. While T-<strong>SQL</strong> doesn’t require that a column in aresult set have a name, it’s a good idea to provide one.In T-<strong>SQL</strong>, there are multiple methods of creating a column alias, with identical output results. One methodis to use the AS keyword to separate the column or expression from the alias:SELECT orderid, unitprice, qty AS quantityFROM Sales.OrderDetails;Another method is to assign the alias before the column or expression using the equals sign as theseparator:SELECT orderid, unitprice, quantity = qtyFROM Sales.OrderDetails;Finally, you can simply assign the alias immediately following the column name, although this is not arecommended method:SELECT orderid, unitprice, qty quantityFROM Sales.OrderDetails;While there is no difference in performance or execution, a difference in readability may cause you tochoose one or the other as a convention.


4-20 Writing SELECT QueriesWarning Column aliases can also be accidentally created, by omitting a comma betweentwo column names in the SELECT list. For example the following creates an alias for theunitprice column deceptively labeled quantity:SELECT orderid, unitprice quantityFROM Sales.OrderDetails;The results:orderid quantity----------- ---------------------10248 14.0010248 9.8010248 34.8010249 18.60As you can see, this could be difficult to identify and fix in a client application. The only wayto avoid this problem is to carefully list your columns, separating them properly withcommas and adopting the AS style of aliases to make it easier to spot mistakes.Question: Which style of column aliases do you prefer? Why?


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-21Using Aliases to Refer to TablesAliases may also be used in the FROM clause to refer to a table, which can improve readability and saveredundancy when referencing the table elsewhere in the query. While this module has focused on singletablequeries, which don’t necessarily benefit from table aliases, this technique will prove useful as youlearn more complex queries in subsequent modules.To create a table alias in a FROM clause, you will use syntax similar to several of the column aliastechniques. You may use the keyword AS to separate the table name from the alias. This style is preferred:SELECT orderid, unitprice, qtyFROM Sales.OrderDetails AS OD;You may omit the keyword AS and simply follow the table name with the alias:SELECT orderid, unitprice, qtyFROM Sales.OrderDetails OD;To combine table and column aliases in the same SELECT statement, use the following approach:SELECT OD.orderid, OD.unitprice, OD.qtyFROM Sales.OrderDetails AS OD;Note There is no table alias equivalent to the use of the equals sign (=) in a column alias.Since this module focuses on single-table queries, you might not yet see a benefit to using table aliases. Inthe next module, you will learn how to retrieve data from multiple tables in a single SELECT statement. Inthose queries, the use of table aliases to represent table names will become quite useful.


4-22 Writing SELECT QueriesThe Impact of Logical Processing Order on AliasesAn issue may arise in the use of column aliases: Aliases created in the SELECT clause may not be referredto in other clauses in the query, such as a WHERE or HAVING clause. This is due to the logical order queryprocessing. The WHERE and HAVING clauses are processed before the SELECT clause and its aliases areevaluated. An exception to this is the ORDER BY clause. An example is provided here for illustration andwill run without error:SELECT orderid, unitprice, qty AS quantityFROM Sales.OrderDetailsORDER BY quantity;However, the following example will return an error, as the WHERE clause has been processed before theSELECT clause defines the alias:SELECT orderid, unitprice, qty AS quantityFROM Sales.OrderDetailsWHERE quantity > 10;The resulting error message:Msg 207, Level 16, State 1, Line 1Invalid column name 'quantity'.As a result, you will often need to repeat an expression more than once: in the SELECT clause, where youmay create an alias to name the column, and in the WHERE or HAVING clause.SELECT orderid, YEAR(orderdate) AS orderyearFROM Sales.OrdersWHERE YEAR(orderdate) = '2008'


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-23Additionally, within the SELECT clause, you may not refer to a column alias that was defined in the sameSELECT statement, regardless of column order. The following statement will return an error:SELECT productid, unitprice AS price, price * qty AS totalFROM Sales.OrderDetails;The resulting error:Msg 207, Level 16, State 1, Line 1Invalid column name 'price'.To correct the error, refer to the source column in the calculated column:SELECT productid, unitprice AS price, unitprice * qty AS totalFROM Sales.OrderDetails


4-24 Writing SELECT QueriesDemonstration: Using Column and Table AliasesDemonstration Setup1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. From the File menu, click Open, click Project/Solution, navigateto F:\10774A_Labs\10774A_04_PRJ\10774A_04_PRJ.ssmssln, and click Open.2. From the View menu, click Solution Explorer. Open and execute the 00 - -Setup.sql script file fromwithin Solution Explorer.3. Open the 31 - -Demonstration C.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-25Lesson 4Writing Simple CASE ExpressionsA CASE expression extends the ability of a SELECT clause to manipulate data as it is retrieved. Often whenwriting a query, you need to substitute a value from a column of a table with another value. While youwill learn how to perform this kind of lookup from another table later in this course, you can also performbasic substitutions using simple CASE expressions in the SELECT clause. In real-world environments, CASEis often used to help make cryptic data held in a column more meaningful.A CASE expression returns a scalar (single-valued) value based on conditional logic, often with multipleconditions. As a scalar value, it may be used wherever single values can be used. Besides the SELECTstatement, CASE expressions can be used in WHERE, HAVING, and ORDER BY clauses.Lesson ObjectivesIn this lesson you will learn how to:• Understand the use of CASE expressions in SELECT clauses.• Understand the simple form of a CASE expression.• Write a simple CASE expression in a SELECT clause.


4-26 Writing SELECT QueriesUsing CASE Expressions in SELECT ClausesIn T-<strong>SQL</strong>, CASE expressions return a single, or scalar, value. Unlike in some other programming languages,in T-<strong>SQL</strong> CASE expressions are not statements, nor do they specify the control of programmatic flow.Instead, they are used in SELECT clauses (and other clauses) to return the result of an expression. Theresults appear as a calculated column and should be aliased for clarity.In T-<strong>SQL</strong> queries, CASE expressions are often used to provide an alternative value for one stored in thesource table. For example, a CASE expression might be used to provide a friendly text name for somethingstored as a compact numeric code.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-27Forms of CASE ExpressionsIn T-<strong>SQL</strong>, CASE expressions may take one of two forms: simple CASE or searched (Boolean) CASE.Simple CASE expressions, the subject of this lesson, compare an input value to a list of possible matchingvalues:1. If a match is found, the first matching value is returned as the result of the CASE expression. Multiplematches are not permitted.2. If no match is found, a CASE expression returns the value found in an ELSE clause, if one exists.3. If no match is found and no ELSE clause is present, the CASE expression returns a NULL.For example, the following CASE expression substitutes a descriptive category name for the categoryidvalue stored in the Production.Categories table. Note that is not a JOIN operation, just a simplesubstitution using a single table:SELECT productid, productname, categoryid,CASE categoryidWHEN 1 THEN 'Beverages'WHEN 2 THEN 'Condiments'WHEN 2 THEN 'Confections'ELSE 'Unknown Category'END AS categorynameFROM Production.CategoriesThe results:productid productname categoryid categoryname--------- ------------ ---------- ---------------------101 Tea 1 Beverages102 Mustard 2 Condiments103 Dinner Rolls 9 Unknown Category


4-28 Writing SELECT QueriesNote The preceding example is presented for illustration only and will not run against thesample databases provided with the course.Searched (Boolean) CASE expressions compare an input value to a set of logical predicates or expressions.The expression can contain a range of values to match against. Like a simple CASE expression, the returnvalue is found in the THEN clause of the matching value.Note Due to their dependence on predicate expressions, which will not be covered untillater in this course, further discussion of searched CASE expressions are beyond the scope ofthis lesson. See "CASE (Transact-<strong>SQL</strong>)" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242847


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-29Demonstration: Simple CASE ExpressionsDemonstration Setup1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. From the File menu, click Open, click Project/Solution, navigateto F:\10774A_Labs\10774A_04_PRJ\10774A_04_PRJ.ssmssln, and click Open.2. From the View menu, click Solution Explorer. Open and execute the 00 - -Setup.sql script file fromwithin Solution Explorer.3. Open the 41 - -Demonstration D.sql script file.4. Follow the instructions contained within the comments of the script file.


4-30 Writing SELECT QueriesLab: Writing Basic SELECT StatementsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the ‘‘Press CTRL+ALT+DELETE to log on’’message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the ‘‘Press CTRL+ALT+DELETE to log on’’message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-317. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You have been provided with a set of business requirements for data and willwrite basic T-<strong>SQL</strong> queries to retrieve the specified data from the databases.Important When comparing your results with the provided sample outputs, the columnordering and total number of affected rows should always match. However, remember thatthe order of the rows in the output of a query without an ORDER BY clause is notguaranteed. Therefore, the order of the rows in the sample outputs may be different thanyours. Also, the answer outputs include abbreviated results.


4-32 Writing SELECT QueriesExercise 1: Writing Simple SELECT StatementsScenarioAs a business analyst, you want to get a better understanding of your corporate data. Usually the bestapproach for an initial project is to get an overview of the main tables and columns involved so that youcan better understand different business requirements. After the initial overview of the tables, you willhave to provide a report for the marketing department because the marketing staff would like to sendinvitation letters for a new campaign. You will use the T<strong>SQL</strong><strong>2012</strong> sample database.The main tasks for this exercise are as follows:1. View all the tables in the T<strong>SQL</strong><strong>2012</strong> database in Object Explorer.2. Write a simple SELECT statement that returns all rows and all columns from the Sales.Customers table.3. Write a SELECT statement that returns the contactname, address, postalcode, city, and countrycolumns from the Sales.Customers table. Task 1: View all the tables in the T<strong>SQL</strong><strong>2012</strong> database in Object Explorer• Using SSMS, connect to Proseware using Windows authentication (if you are connecting to an onpremisesinstance of <strong>SQL</strong> Server) or <strong>SQL</strong> Server authentication (if you are using Microsoft <strong>SQL</strong> Azureand ask your instructor for a current list of <strong>SQL</strong> Azure enabled labs).• In Object Explorer, expand the T<strong>SQL</strong><strong>2012</strong> database and expand the Tables folder.• Take a look at the names of the tables in the Sales schema. Task 2: Write a simple SELECT statement• Open the project file F:\10774A_Labs\10774A_04_PRJ\10774A_04_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement that will return all rows and all columns from the Sales.Customers table.Tip You can use drag-and-drop functionality to drag items like table and column namesfrom Object Explorer to the query window. Write the same SELECT statement using thedrag-and-drop functionality.• Execute the written statement and compare the results that you got with the desired results shown inthe file 52 - Lab Exercise 1 - Task 2 Result.txt.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-33 Task 3: Write a SELECT statement that includes specific columns• Expand the Sales.Customers table in Object Explorer and expand the Columns folder. Observe allcolumns in the table.• Write a SELECT statement to return the contactname, address, postalcode, city, and country columnsfrom the Sales.Customers table.• Execute the written statement and compare the results that you got with the desired results shown inthe file 53 - Lab Exercise 1 - Task 3 Result.txt.• What is the number of rows affected by the last query? (Tip: Because you are issuing a SELECTstatement against the whole table, the number of rows will be the same as number of rows for thewhole Sales.Customers table.)Results: After this exercise, you should know how to create simple SELECT statements to analyze existingtables.


4-34 Writing SELECT QueriesExercise 2: Eliminating Duplicates Using DISTINCTScenarioAfter supplying the marketing department with a list of all customers for a new campaign, you get arequest to provide a list of all the different countries that the customers come from.The main tasks for this exercise are as follows:1. Write a SELECT statement showing only the country column from the Sales.Customers table.2. Write a SELECT statement showing only distinct countries.3. Identify how many different countries there are in the Sales.Customers table. Task 1: Write a SELECT statement that includes a specific column• Open the project file F:\10774A_Labs\10774A_04_PRJ\10774A_04_PRJ.ssmssln and T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement against the Sales.Customers table showing only the country column.• Execute the written statement and compare the results that you got with the desired results shown inthe file 62 - Lab Exercise 2 - Task 1 Result.txt. Task 2: Write a SELECT statement that uses the DISTINCT clause• Copy the SELECT statement in Task 1 and modify it to return only distinct values.• Execute the written statement and compare the results that you got with the desired results shown infile 63 - Lab Exercise 2 - Task 2 Result.txt.• How many rows did the query in Task 1 return?• How many rows did the query in Task 2 return?• Under which circumstances do the following queries against the Sales.Customers table return thesame result?SELECT city, region FROM Sales.Customers;SELECT DISTINCT city, region FROM Sales.Customers;• Is the DISTINCT clause being applied to all columns specified in the query or just the first column?Results: After this exercise, you should have an understanding of how to return only the different(distinct) rows in the result set of a query.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-35Exercise 3: Using Table and Column AliasesScenarioAfter getting the initial list of customers, the marketing department would like to have more readabletitles for the columns and a list of all products in the T<strong>SQL</strong><strong>2012</strong> database.The main tasks for this exercise are as follows:1. Write a select statement to return the contactname and contacttitle columns from theSales.Customers table using an alias for the table.2. Write a query to return the contactname, contacttitle, and companyname columns from theSales.Customers table using column aliases.3. Write a query to return all product names using table and column aliases. Task 1: Write a SELECT statement that uses a table alias• Open the project file F:\10774A_Labs\10774A_04_PRJ\10774A_04_PRJ.ssmssln and T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to return the contactname and contacttitle columns from theSales.Customers table, assigning ‘‘C’’ as the table alias. Use the table alias C to prefix the names of thetwo needed columns in the SELECT list. The benefit of using table aliases will become clearer in futuremodules when topics such as joins and subqueries will be introduced.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 72 - Lab Exercise 3 - Task 1 Result.txt. Task 2: Write a SELECT statement that uses column aliases• Write a SELECT statement to return the contactname, contacttitle, and companyname columns.Assign these columns with the aliases Name, Title, and Company Name, respectively, in order toreturn more human-friendly column titles for reporting purposes.• Execute the written statement and compare the results that you got with the desired results shown inthe file 73 - Lab Exercise 3 - Task 2 Result.txt. Notice specifically the titles of the columns in thedesired output. Task 3: Write a SELECT statement that uses a table alias and a column alias• Write a query to display the productname column from the Production.Products table using ‘‘P’’ asthe table alias and Product Name as the column alias.• Execute the written statement and compare the results that you got with the desired results shown inthe file 74 - Lab Exercise 3 - Task 3 Result.txt.


4-36 Writing SELECT Queries Task 4: Analyze and correct the query• A developer has written a query to retrieve two columns (city and region) from the Sales.Customerstable. When the query is executed, it returns only one column. Your task is to analyze the query,correct it to return two columns, and explain why the query returned only one column.SELECT city countryFROM Sales.Customers;• Execute the query exactly as written inside a query window and observe the result.• Correct the query to return the city and country columns from the Sales.Customers table.• Why did the query return only one column? What was the title of the column in the output? What isthe best practice when using aliases for columns to avoid such errors?Results: After this exercise, you know how to use aliases for table and column names.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-37Exercise 4: Using a Simple CASE ExpressionScenarioYour company produces a long list of products, and the members of the marketing department wouldlike to have product category information in their reports. They have supplied you with a documentcontaining the following mapping between the product category IDs and the product category names:categoryidCategoryname1 Beverages2 Condiments3 Confections4 Dairy Products5 Grains/Cereals6 Meat/Poultry7 Produce8 SeafoodBecause of an active marketing campaign, they would like to include product category information intheir reports.The main tasks for this exercise are as follows:1. Write a SELECT statement to retrieve the productname and categoryid columns from theProduction.Products table.2. Modify an existing query to include a simple CASE expression based on the mapping informationsupplied by the marketing department to list the category name for each product. Task 1: Write a SELECT statement• Open the project file F:\10774A_Labs\10774A_04_PRJ\10774A_04_PRJ.ssmssln and T-<strong>SQL</strong> script81 - Lab Exercise 4.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to display the categoryid and productname columns from theProduction.Products table.• Execute the written statement and compare the results that you got with the desired results shown inthe file 82 - Lab Exercise 4 - Task 1 Result.txt.


4-38 Writing SELECT Queries Task 2: Write a SELECT statement that uses a CASE expression• Enhance the SELECT statement in task 1 by adding a CASE expression that generates a result columnnamed categoryname. The new column should hold the translation of the category ID to itsrespective category name based on the mapping table supplied earlier. Use the value ‘‘Other’’ for anycategory IDs not found in the mapping table.• Execute the written statement and compare the results that you got with the desired output shown inthe file 83 - Lab Exercise 4 - Task 2 Result.txt. Task 3: Write a SELECT statement that uses a CASE expression to differentiatecampaign-focused products• Modify the SELECT statement in task 2 by adding a new column named iscampaign. This column willshow the description ‘‘Campaign Products’’ for the categories Beverages, Produce, and Seafood andthe description ‘‘Non-Campaign Products’’ for all other categories.• Execute the written statement and compare the results that you got with the desired results shown inthe file 84 - Lab Exercise 4 - Task 3 Result.txt.Results: After this exercise, you should know how to use CASE expressions to write simple conditionallogic.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 4-39Module Review and TakeawaysReview Questions1. Why is the use of SELECT * not a recommended practice?2. What will happen if you omit a comma between column names in a SELECT clause?3. What kind of result does a simple CASE statement return?Best Practices1. Terminate all T-<strong>SQL</strong> statements with a semicolon. This will make your code more readable, avoidcertain parsing errors, and will protect your code against changes in future versions of <strong>SQL</strong> Server.2. Consider standardizing your code on the AS keyword for labeling column and table aliases. This willmake your code easier to read and avoids accidental aliases.


4-40 Writing SELECT Queries


5-1Module 5<strong>Querying</strong> Multiple TablesContents:Lesson 1: Understanding Joins 5-3Lesson 2: <strong>Querying</strong> with Inner Joins 5-11Lesson 3: <strong>Querying</strong> with Outer Joins 5-18Lesson 4: <strong>Querying</strong> with Cross Joins and Self-Joins 5-24Lab: <strong>Querying</strong> Multiple Tables 5-34


5-2 <strong>Querying</strong> Multiple TablesModule OverviewIn real-world environments, it is likely that the data you need to query is stored in multiple locations.Earlier, you learned how to write basic single-table queries. In this module, you will learn how to writequeries that combine data from multiple sources in Microsoft® <strong>SQL</strong> Server® <strong>2012</strong>. You will do so bywriting queries containing joins, which allow you to retrieve data from two (or more) tables based on datarelationships between the tables.ObjectivesAfter completing this module, you will be able to:• Describe how multiple tables may be queried in a SELECT statement using joins.• Write queries that use inner joins.• Write queries that use outer joins.• Write queries that use self-joins and cross joins.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-3Lesson 1Understanding JoinsIn this lesson, you will learn the fundamentals of joins in <strong>SQL</strong> Server <strong>2012</strong>. You will learn how theFROM clause in a T-<strong>SQL</strong> SELECT statement creates intermediate virtual tables that will be consumed bysubsequent phases of the query. You will learn how an unrestricted combination of rows from two tablesyields a Cartesian product. You will also learn about the common join types in T-<strong>SQL</strong> multi-table queries.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the relationship between the FROM Clause and virtual tables in a SELECT statement.• Describe a Cartesian product and how it may be created by a join.• Describe the common join types in T-<strong>SQL</strong> queries.• Understand the difference between ANSI <strong>SQL</strong>-89 and <strong>SQL</strong>-92 join syntax.


5-4 <strong>Querying</strong> Multiple TablesThe FROM Clause and Virtual TablesEarlier, you learned about the logical order of operations performed when <strong>SQL</strong> Server <strong>2012</strong> processes aquery. You will recall that the FROM clause of a SELECT statement is the first phase to be processed. Thisclause determines which table or tables will be the source of rows for the query. As you will see in thismodule, this will hold true whether you are querying a single table or bringing together multiple tables asthe source of your query.In order to learn about the additional capabilities of the FROM clause, it will be useful to think of thefunction of the clause as creating and populating a virtual table. This virtual table will hold the output ofthe FROM clause and will be used subsequently by other phases of the SELECT statement, such as theWHERE clause. As you add additional functionality, such as join operators, to a FROM clause, it will behelpful to think of the purpose of the FROM clause elements as either to add rows to, or remove rowsfrom, the virtual table.Note The virtual table created by a FROM clause is a logical entity only. In <strong>SQL</strong> Server<strong>2012</strong>, no physical table is created, whether persistent or temporary, to hold the results ofthe FROM clause, as it is passed to the WHERE clause or other subsequent phases.The syntax for the SELECT statement that you have used in earlier queries in this course has appeared asfollows:SELECT ...FROM AS ;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-5You learned earlier that the FROM clause is processed first, and as a result, any table aliases you createthere may be referenced in the SELECT clause. You will see numerous examples of table aliases in thismodule. While they are optional, except in the case of self-join queries, you will quickly see how they canbe a convenient tool when writing your queries. Compare the following two queries, which have the sameoutput, but which differ in their use of aliases. (Note that the examples use a JOIN clause, which will becovered later in this module.) The first query uses no table aliases:USE T<strong>SQL</strong><strong>2012</strong> ;GOSELECT Sales.Orders.orderid, Sales.Orders.orderdate,Sales.OrderDetails.productid,Sales.OrderDetails.unitprice,Sales.OrderDetails.qtyFROM Sales.OrdersJOIN Sales.OrderDetails ON Sales.Orders.orderid = Sales.OrderDetails.orderid ;The second example retrieves the same data but uses table aliases:USE T<strong>SQL</strong><strong>2012</strong> ;GOSELECT o.orderid, o.orderdate,od.productid, od.unitprice,od.qtyFROM Sales.Orders AS oJOIN Sales.OrderDetails AS od ON o.orderid = od.orderid ;As you can see, the use of table aliases improves the readability of the query, without affecting theperformance. It is strongly recommended that you use table aliases in your multi-table queries.Note Once a table as been designated with an alias in the FROM clause, it is a bestpractice to use the alias when referring to columns from that table in other clauses.


5-6 <strong>Querying</strong> Multiple TablesJoin Terminology: Cartesian ProductWhen learning about writing multi-table queries in T-<strong>SQL</strong>, it is important to understand the concept ofCartesian products. In mathematics, a Cartesian product is the product of two sets. The product of a set of2 items and a set of 6 items is a set of 12 items, or 6 x 2. In databases, a Cartesian product is the result ofjoining every row of one input table to every row of another input table. The product of a table with 10rows and a table with 100 rows is a result set with 1,000 rows.For most T-<strong>SQL</strong> queries, a Cartesian product is not the desired outcome. Typically, a Cartesian productoccurs when two input tables are joined without considering any logical relationships between them. Inthe absence of any information about relationships, the <strong>SQL</strong> Server query processor will output allpossible combinations of rows.While this can have some practical applications, such as creating a table of numbers or generating testdata, it is not typically useful and can have severe performance effects. You will learn a useful applicationof Cartesian joins later in this module.Note In the next topic, you will compare two different methods for specifying the syntaxof a join. You will see that one method may lead you toward writing accidental Cartesianproduct queries.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-7Overview of Join TypesTo populate the virtual table produced by the FROM clause in a SELECT statement, <strong>SQL</strong> Server uses joinoperators. These operators add or remove rows from the virtual table, before it is handed off tosubsequent logical phases of the SELECT statement:• A cross join operator (CROSS JOIN) adds all possible combinations of the two input tables' rows to thevirtual table. Any filtering of the rows will happen in a WHERE clause. For most querying purposes,this operator is to be avoided.• An inner join operator (INNER JOIN, or just JOIN) first creates a Cartesian product, and then filters theresults using the predicate supplied in the ON clause, removing any rows from the virtual table thatdo not satisfy the predicate. The inner join type is a very common type of join for retrieving rows withattributes that match across tables, such as matching Customers to Orders by a common custid.• An outer join operator (LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN) first creates aCartesian product, and like an inner join, filters the results to find rows that match in each table.However, all rows from one table are preserved, added back to the virtual table after the initial filter isapplied. NULLs are placed on attributes where no matching values are found.Note Unless otherwise qualified with CROSS or OUTER, the JOIN operator defaults to anINNER join.


5-8 <strong>Querying</strong> Multiple TablesT-<strong>SQL</strong> Syntax ChoicesThrough the history of versions of <strong>SQL</strong> Server, the product has changed to keep pace with changes in theANSI standards for the <strong>SQL</strong> language. One of the most notable places where these changes are visible is inthe syntax for the join operator in a FROM clause.In ANSI <strong>SQL</strong>-89, no ON operator was defined. Joins were represented in a comma-separated list of tables,and any filtering, such as for an inner join, was performed in the WHERE clause. This syntax is stillsupported by <strong>SQL</strong> Server <strong>2012</strong>, but due to the complexity of representing the filters for an outer join inthe WHERE clause, as well as any other filtering, it is not recommended to use this. Additionally, if aWHERE clause is accidentally omitted, ANSI <strong>SQL</strong>-89-style joins can easily become Cartesian products andcause performance problems. The following queries illustrate this syntax and this potential problem:USE T<strong>SQL</strong><strong>2012</strong>;GO/*This is ANSI <strong>SQL</strong>-89 syntax for an inner join, with the filtering performed in the WHEREclause.*/SELECT c.companyname, o.orderdateFROM Sales.Customers AS c, Sales.Orders AS oWHERE c.custid = o.custid;....(830 row(s) affected)/*This is ANSI <strong>SQL</strong>-89 syntax for an inner join, omitting the WHERE clause and causing aninadvertent Cartesian join.*/SELECT c.companyname, o.orderdateFROM Sales.Customers AS c, Sales.Orders AS o;...(75530 row(s) affected)


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-9With the advent of the ANSI <strong>SQL</strong>-92 standard, support for the ON clause was added. T-<strong>SQL</strong> also supportsthis syntax. Joins are represented in the FROM clause by using the appropriate JOIN operator. The logicalrelationship between the tables, which becomes a filter predicate, is represented with the ON clause. Thefollowing example restates the previous query with the newer syntax:SELECT c.companyname, o.orderdateFROM Sales.Customers AS c JOIN Sales.Orders AS oON c.custid = o.custid;Note The ANSI <strong>SQL</strong>-92 syntax makes it more difficult to create accidental Cartesian joins.Once the keyword JOIN has been added, a syntax error will be raised if an ON clause ismissing.


5-10 <strong>Querying</strong> Multiple TablesDemonstration: Understanding JoinsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_05_PRJ\10774A_05_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 - -Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-11Lesson 2<strong>Querying</strong> with Inner JoinsIn this lesson, you will learn how to write inner join queries, the most common type of multi-table query ina business environment. By expressing a logical relationship between the tables, you will retrieve onlythose rows with matching attributes present in both tables.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe inner joins.• Write queries using inner joins.• Describe the syntax of an inner join.


5-12 <strong>Querying</strong> Multiple TablesUnderstanding Inner JoinsT-<strong>SQL</strong> queries that use inner joins are the most common types of queries to solve many businessproblems, especially in highly normalized database environments. To retrieve data that has been storedacross multiple tables, you will often need to reassemble it via inner join queries.As you have previously learned, an inner join begins its logical processing phase as a Cartesian product,which is then filtered to remove any rows that don't match the predicate. In <strong>SQL</strong>-89 syntax, that predicateis in the WHERE clause. In <strong>SQL</strong>-92 syntax, that predicate is within the FROM clause in the ON clause:--ANSI <strong>SQL</strong>-89 syntaxSELECT c.companyname, o.orderdateFROM Sales.Customers AS c, Sales.Orders AS oWHERE c.custid = o.custid;--ANSI <strong>SQL</strong>-92 syntaxSELECT c.companyname, o.orderdateFROM Sales.Customers AS c JOIN Sales.Orders AS oON c.custid = o.custid;From a performance standpoint, you will find that the query optimizer in <strong>SQL</strong> Server <strong>2012</strong> does not favorone syntax over the other. However, as you learn about additional types of joins, especially outer joins,you will likely decide that you prefer to use the <strong>SQL</strong>-92 syntax and filter in the ON clause. Keeping the joinfilter logic in the ON clause and leaving other data filtering in the WHERE clause will make your querieseasier to read and easier to test.Using the ANSI <strong>SQL</strong>-92 syntax, let’s examine the steps by which <strong>SQL</strong> Server <strong>2012</strong> will logically process thisquery. (Line numbers are added for clarity and are not submitted to the query engine for execution.)1) SELECT c.companyname, o.orderdate2) FROM Sales.Customers AS c3) JOIN Sales.Orders AS o4) ON c.custid = o.custid;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-13As you learned earlier, the FROM clause will be processed before the SELECT clause. Therefore, let’s trackthe processing beginning with line 2:• The FROM clause designates the Sales.Customers table as one of the input tables, giving it thealias of 'c'.• The JOIN operator in line 3 reflects the use of an INNER join (the default type in T-<strong>SQL</strong>) anddesignates the Sales.Orders table as the other input table, which has an alias of 'o'.• <strong>SQL</strong> Server will perform a logical Cartesian join on these tables and pass the results to the next phasein the virtual table. (Note that the physical processing of the query may not actually perform theCartesian product operation, depending on the optimizer's decisions.)• Using the ON clause, <strong>SQL</strong> Server will filter the virtual table, retaining only those rows where a custidvalue from the c table (Sales.Customers has been replaced by the alias) matches a custid from the ptable (Sales.Orders has been replaced by an alias).• The remaining rows are left in the virtual table and handed off to the next phase in the SELECTstatement. In this example, the virtual table is next processed by the SELECT clause, and only twocolumns are returned to the client application.• The result? A list of customers that have placed orders. Any customers that have never placed anorder have been filtered out by the ON clause, as have any orders that happen to have a customer IDthat doesn't correspond to an entry in the customer list.


5-14 <strong>Querying</strong> Multiple TablesInner Join SyntaxWhen writing queries using inner joins, consider the following guidelines:• As you have seen, table aliases are preferred not only for the SELECT list, but also for expressing theON clause.• Inner joins may be performed on a single matching attribute, such as an orderid, or they may beperformed on multiple matching attributes, such as the combination of orderid and productid. Joinsthat match multiple attributes are called composite joins.• The order in which tables are listed and joined in the FROM clause does not matter to the <strong>SQL</strong> Serveroptimizer. (This will not be the case for OUTER JOIN queries in the next topic.) Conceptually, joins willbe evaluated from left to right.• Use the JOIN keyword once for each two tables in the FROM list. For a two-table query, specify onejoin. For a three-table query, you will use JOIN twice: once between the first two tables, and onceagain between the output of the first two and the third table.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-15Inner Join ExamplesThe following are some examples of inner joins:This query performs a join on a single matching attribute, relating the categoryid from theProduction.Categories table to the categoryid from the Production.Products table:SELECT c.categoryid, categoryname, p.productid, p.productnameFROM Production.Categories AS cJOIN Production.Products AS pON c.categoryid = p.categoryid;This query performs a composite join on two matching attributes, relating city and country attributes fromSales.Customers to HR.Employees. Note the use of the DISTINCT operator to filter out duplicateoccurrences of city, country:SELECT DISTINCT e.city, e.countryFROM Sales.Customers AS cJOIN HR.Employees AS eON c.city = e.city AND c.country = e.country;Note The demonstration code for this lesson also uses the DISTINCT operator to filterduplicates.


5-16 <strong>Querying</strong> Multiple TablesThis next example shows how an inner join may be extended to include more than two tables. Note thatthe Sales.OrderDetails table is joined not to the Sales.Orders table, but to the output of the JOIN betweenSales.Customers and Sales.Orders. Each instance of JOIN...ON performs its own population and filtering ofthe virtual output table. It is up to the <strong>SQL</strong> Server query optimizer to decide in which order the joins andfiltering will be performed.SELECT c.custid, c.companyname, o.orderid, o.orderdate, od.productid, od.qtyFROM Sales.Customers AS cJOIN Sales.Orders AS oON c.custid = o.custidJOIN Sales.OrderDetails AS odON o.orderid = od.orderid;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-17Demonstration: <strong>Querying</strong> with Inner JoinsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_05_PRJ\10774A_05_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 - -Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


5-18 <strong>Querying</strong> Multiple TablesLesson 3<strong>Querying</strong> with Outer JoinsIn this lesson, you will learn how to write queries that use outer joins. While not as common as inner joins,the use of outer joins in a multi-table query can provide you with an alternative view of your businessdata. As with inner joins, you will express a logical relationship between the tables. However, you willretrieve not only rows with matching attributes, but all rows present in one of the tables, whether or notthere is a match in the other table.Lesson ObjectivesAfter completing this lesson, you will be able to:• Understand the purpose and function of outer joins.• Be able to write queries using outer joins.• Be able to combine an OUTER JOIN operator in a FROM clause with a nullability test in a WHEREclause in order to reveal non-matching rows.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-19Understanding Outer JoinsIn the previous lesson, you learned how to use inner joins to match rows in separate tables. As you saw,<strong>SQL</strong> Server built the results of an inner join query by filtering out rows that failed to meet the conditionsexpressed in the ON clause predicate. The result is that only rows that matched from both tables weredisplayed. With an outer join, you may choose to display all the rows from one table as well as those thatmatch from the second table. Let's look at an example, then explore the process.First, let’s examine the following query, written as an inner join:USE AdventureWorks2008R2;GOSELECT c.CustomerID, soh.SalesOrderIDFROM Sales.Customer AS c JOIN Sales.SalesOrderHeader AS sohON c.CustomerID = soh.CustomerID--(31465 row(s) affected)Note that this example uses the AdventureWorks2008R2 database for these samples. When written as aninner join, the query returns 31,465 rows. These rows represent a match between customers and orders.Only those CustomerIDs that appear in both tables will appear in the results. Only customers that haveplaced orders will be returned.Now, let’s examine the following query, written as an outer left join:USE AdventureWorks2008R2;GOSELECT c.CustomerID, soh.SalesOrderIDFROM Sales.Customer AS c LEFT OUTER JOIN Sales.SalesOrderHeader AS sohON c.CustomerID = soh.CustomerID--(32166 row(s) affected)


5-20 <strong>Querying</strong> Multiple TablesThis example uses a LEFT OUTER JOIN operator, which as you will learn, directs the query processor topreserve all rows from the table on the left (Sales.Customer) and display the SalesOrderID values formatching rows in Sales.SalesOrderHeader. However, there are more rows returned in this example. Allcustomers are returned, whether or not they have placed an order. As you will see in this lesson, an outerjoin will display all the rows from one side of the join or another, whether they match or not.What does an outer join query display in columns where there was no match? In this example, there areno matching orders for 701 customers. In the place of the SalesOrderID column, <strong>SQL</strong> Server will outputNULL where values are otherwise missing.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-21Outer Join SyntaxWhen writing queries using outer joins, consider the following guidelines:• As you have seen, table aliases are preferred not only for the SELECT list, but also for expressing theON clause.• Outer joins are expressed using the keywords LEFT, RIGHT, or FULL preceding OUTER JOIN. Thepurpose of the keyword is to indicate which table (on which side of the keyword JOIN) should bepreserved and have all its rows displayed, match or no match.• As with inner joins, outer joins may be performed on a single matching attribute, such as an orderid,or they may be performed on multiple matching attributes, such as orderid and productid.• Unlike inner joins, the order in which tables are listed and joined in the FROM clause does matter, asit will determine whether you choose LEFT or RIGHT for your join.• Multi-table joins are more complex when an OUTER JOIN is present. The presence of NULLs in theresults of an outer join may cause issues if the intermediate results are then joined via an inner join toa third table. Rows with NULLs may be filtered out by the second join's predicate.• To display only rows where no match exists, add a test for NULL in a WHERE clause following anOUTER JOIN predicate.


5-22 <strong>Querying</strong> Multiple TablesOuter Join ExamplesThe following are some examples of outer joins:This query displays all customers and provides information about each customer's orders if any exist:USE T<strong>SQL</strong><strong>2012</strong>;GOSELECT c.custid, c.companyname, o.orderid, o.orderdateFROM Sales.Customers AS cLEFT OUTER JOIN Sales.Orders AS oON c.custid =o.custid;This query displays only customers that have never placed an order:SELECT c.custid, c.companyname, o.orderid, o.orderdateFROM Sales.Customers AS cLEFT OUTER JOIN Sales.Orders AS oON c.custid =o.custidWHERE o.orderid IS NULL;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-23Demonstration: <strong>Querying</strong> with Outer JoinsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_05_PRJ\10774A_05_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 31 - -Demonstration C.sql script file.4. Follow the instructions contained within the comments of the script file.


5-24 <strong>Querying</strong> Multiple TablesLesson 4<strong>Querying</strong> with Cross Joins and Self-JoinsIn this lesson, you will learn some additional types of joins, which are useful in some more specializedscenarios.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe a use for a cross join.• Write queries that use cross joins.• Describe a use for a self-join.• Write queries that use self-joins.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-25Understanding Cross JoinsCross join queries create a Cartesian product. So far in this module, you have learned that Cartesianproducts are to be avoided. Although you have seen a means to create one with ANSI <strong>SQL</strong>-89 syntax, youhaven't seen how or why to create one with ANSI <strong>SQL</strong>-92. This topic will revisit cross joins and Cartesianproducts.To explicitly create a Cartesian product, you would use the CROSS JOIN operator. This will create a resultset with all possible combinations of input rows:SELECT ...FROM table1 AS t1 CROSS JOIN table2 AS t2;While this is not typically a desired output, there are a few practical applications for writing an explicitcross join:• Creating a table of numbers, with a row for each possible value in a range.• Generating large volumes of data for testing. When cross joined to itself, a table with as few as 100rows can readily generate 10,000 output rows with very little work on your part.


5-26 <strong>Querying</strong> Multiple TablesCross Join SyntaxWhen writing queries with CROSS JOIN, consider the following:• There is no matching of rows performed, and therefore no ON clause is required.• To use ANSI <strong>SQL</strong>-92 syntax, separate the input table names with the CROSS JOIN operator.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-27Cross Join ExamplesThe following is an example of using CROSS JOIN to create all combinations of two input sets. Using theT<strong>SQL</strong><strong>2012</strong> sample, this will take 9 employee first names and 9 employee last names to generate 81combinations:SELECT e1.firstname, e2.lastnameFROM HR.Employees e1 CROSS JOIN HR.Employees e2;


5-28 <strong>Querying</strong> Multiple TablesUnderstanding Self-JoinsThe joins you have learned about to this point have involved separate multiple tables. There may bescenarios in which you need to compare and retrieve data stored in the same table. For example, in aclassic human resources application, an Employees table might include information about the supervisorof each employee in the employee's own row. Each supervisor is also listed as an employee. To retrievethe employee information and match it up to the related supervisor, you can use the table twice in yourquery, joining it to itself for the purposes of the query.There are other scenarios in which you will want to compare rows within a table with one another. As youhave seen, it's fairly easy to compare columns within the same row using T-<strong>SQL</strong>, but it is less obvious howto compare values from different rows (such as a row which stores a starting time with another row in thesame table that stores a corresponding stop time). Self-joins are a useful technique for these types ofqueries.In order to accomplish tasks like this, you will want to consider the following guidelines:• Create two instances of the same table in the FROM clause, and join them as needed, using inneror outer joins.• Use table aliases to create two separate aliases for the same table. At least one table must havean alias.• Use the ON clause to provide a filter using separate columns from the same table.The following example, which you will examine closely in the next topic, illustrates these guidelines. Thisquery retrieves employees and their matching manager information from the Employees table joined toitself:SELECT e.empid ,e.lastname AS empname,e.title,e.mgrid, m.lastname AS mgrnameFROM HR.Employees AS eJOIN HR.Employees AS mON e.mgrid=m.empid;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-29This yields results like the following:empid empname title mgrid mgrname----- ------------ --------------------- ----- -------2 Funk Vice President, Sales 1 Davis3 Lew Sales Manager 2 Funk4 Peled Sales Representative 3 Lew5 Buck Sales Manager 2 Funk6 Suurs Sales Representative 5 Buck7 King Sales Representative 5 Buck8 Cameron Sales Representative 3 Lew9 Dolgopyatova Sales Representative 5 Buck


5-30 <strong>Querying</strong> Multiple TablesSelf-Join SyntaxYou write self-join queries much like you write inner or outer joins. The primary difference is that thetables on both sides of the JOIN operator will actually be references to the same table. Pay particularattention to your aliasing and which columns you use in the ON clause in order to ensure that you arejoining the table to itself properly. Try using the terms in the business problem (such as employee andmanager) to help keep it clear which table you need to refer to.All of the queries you have seen in this module so far have been written using an equality operator tomatch rows. Joins that use equality operators are referred to as equijoins. However, there are numerousscenarios in which the use of an inequality operator in a self-join can open up opportunities forinteresting queries.When a join condition uses other operators, such as , , the join is called a non-equijoin. Whenjoining a table to itself, using an inequality operator (, ) will filter out those rows where thecolumns being compared in the ON clause are equal to each other. This will create unique pairs of valuesin the column being compared.For example, consider a table of numbers with only one column, n, and only three rows:SELECT n FROM T;The results:n--123


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-31A cross-join query that created a Cartesian product would produce all combinations of the values:SELECT T1.n, T2.nFROM T AS T1 CROSS JOIN T AS T2;The results:n n- -1 12 13 11 22 23 21 32 33 3(9 row(s) affected)To create only unique combinations of the pairs, create a predicate T1.n < T2.n in the JOIN clause toproduce three rows:SELECT T1.n, T2.nFROM T AS T1 JOIN T AS T2ON T1.n < T2.n;The results:n n- -1 21 32 3(3 row(s) affected)


5-32 <strong>Querying</strong> Multiple TablesSelf-Join ExamplesThe following are some examples of self-joins:This query returns all employees along with the name of each employee’s manager when a managerexists (inner join). Note that a manager appears who is not also listed an employee:SELECT e.empid ,e.lastname AS empname,e.title,e.mgrid, m.lastname AS mgrnameFROM HR.Employees AS eJOIN HR.Employees AS mON e.mgrid=m.empid;This query returns all employees with the name of each manager (outer join). This restores the missingemployee, who turns out to be a CEO with no manager:SELECT e.empid ,e.lastname AS empname,e.title,e.mgrid, m.lastname AS mgrnameFROM HR.Employees AS eLEFT OUTER JOIN HR.Employees AS mON e.mgrid=m.empid;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-33Demonstration: <strong>Querying</strong> with Cross Joins and Self-JoinsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_05_PRJ\10774A_05_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 41 - -Demonstration D.sql script file.4. Follow the instructions contained within the comments of the script file.


5-34 <strong>Querying</strong> Multiple TablesLab: <strong>Querying</strong> Multiple TablesLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the ‘‘Press CTRL+ALT+DELETE to log on’’message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the ‘‘Press CTRL+ALT+DELETE to log on’’message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-357. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You have been provided with a set of business requirements for data and youwill write T-<strong>SQL</strong> queries to retrieve the specified data from the databases. You notice that the data isstored in separate tables, so you will need to write queries using various join operations.


5-36 <strong>Querying</strong> Multiple TablesExercise 1: Writing Queries That Use Inner JoinsScenarioYou no longer need the mapping information between categoryid and categoryname that was supplied inmodule 4 because you now have the Production.Categories table with the needed mapping rows. Write aSELECT statement using an inner join to retrieve the productname column from the Production.Productstable and the categoryname column from the Production.Categories table.The main tasks for this exercise are as follows:1. Write a SELECT statement that uses an inner join.2. Answer questions. Task 1: Write a SELECT statement that uses an inner join• Open the project file F:\10774A_Labs\10774A_05_PRJ\10774A_05_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement that will return the productname column from the Production.Productstable (use table alias ‘‘p’’) and the categoryname column from the Production.Categories table (usetable alias ‘‘c’’) using an inner join.• Execute the written statement and compare the results that you got with the desired results shown inthe file 52 - Lab Exercise 1 - Task 1 Result.txt.• Which column did you specify as a predicate in the ON clause of the join? Why?• Let us say that there is a new row in the Production.Categories table and this new product categorydoes not have any products associated with it in the Production.Products table. Would this row beincluded in the result of the SELECT statement written in task 1? Please explain.Results: After this exercise, you should know how to use an inner join between two tables.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-37Exercise 2: Writing Queries That Use Multiple-Table Inner JoinsScenarioThe sales department would like a report of all customers that placed at least one order, with detailedinformation about each order. A developer prepared an initial SELECT statement that retrieves the custidand contactname columns from the Sales.Customers table and the orderid column from the Sales.Orderstable. You should observe the supplied statement and add additional information from theSales.OrderDetails table.The main tasks for this exercise are as follows:1. Analyze and correct the query.2. Add the productid, qty, and unitprice columns from the Sales.OrderDetails table. Task 1: Execute the T-<strong>SQL</strong> statement• Open the project file F:\10774A_Labs\10774A_05_PRJ\10774A_05_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• The developer has written this query:SELECTcustid, contactname, orderidFROM Sales.CustomersINNER join Sales.Orders ON Customers.custid = Orders.custid;• Execute the query exactly as written inside a query window and observe the result.• You get an error. What is the error message? Why do you think you got this error? Task 2: Apply the needed changes and execute the T-<strong>SQL</strong> statement• Notice that there are full source table names written as table aliases.• Apply the needed changes to the SELECT statement so that it will run without an error. Test thechanges by executing the T-<strong>SQL</strong> statement.• Observe and compare the results that you got with the recommended results shown in the file62 - Lab Exercise 2 - Task 2 Result.txt. Task 3: Change the table aliases• Copy the T-<strong>SQL</strong> statement from task 2 and modify it to use the table aliases ‘‘C’’ for theSales.Custumers table and ‘‘O’’ for the Sales.Orders table.• Execute the written statement and compare the results with the results in task 2.• Change the prefix of the columns in the SELECT statement with full source table names and executethe statement.• You get an error. Why?• Change the SELECT statement to use the table aliases written at the beginning of the task.


5-38 <strong>Querying</strong> Multiple Tables Task 4: Add an additional table and columns• Copy the T-<strong>SQL</strong> statement from task 3 and modify it to include three additional columns from theSales.OrderDetails table: productid, qty, and unitprice.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 63 - Lab Exercise 2 - Task 4 Result.txt.Results: After this exercise, you should have a better understanding of why aliases are important and howto do a multiple-table join.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-39Exercise 3: Writing Queries That Use Self-JoinsScenarioThe HR department would like a report showing employees and their managers. They would like to seethe lastname, firstname, and title columns from the HR.Employees table for each employee and the samecolumns for the employee’s manager.The main tasks for this exercise are as follows:1. Write a SELECT statement using a self-join to retrieve the needed columns.2. Answer the questions. Task 1: Write a basic SELECT statement• Open the project file F:\10774A_Labs\10774A_05_PRJ\10774A_05_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• In order to better understand the needed tasks, you will first write a SELECT statement against theHR.Employees table showing the empid, lastname, firstname, title, and mgrid columns.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 72 - Lab Exercise 3 - Task 1 Result.txt. Notice the values in the mgrid column. Themgrid column is in a relationship with empid column. This is called a self-referencing relationship. Task 2: Write a query that uses a self-join• Copy the SELECT statement from task 1 and modify it to include additional columns for the managerinformation (lastname, firstname) using a self-join. Assign the aliases mgrlastname and mgrfirstname,respectively, to distinguish the manager names from the employee names.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 73 - Lab Exercise 3 - Task 2 Result.txt. Notice the number of rows returned.• Is it mandatory to use table aliases when writing a statement with a self-join? Can you use a fullsource table name as alias? Please explain.• Why did you get fewer rows in the T-<strong>SQL</strong> statement under task 2 compared to task 1?Results: After this exercise, you should have an understanding of how to write T-<strong>SQL</strong> statements that useself-joins.


5-40 <strong>Querying</strong> Multiple TablesExercise 4: Writing Queries That Use Outer JoinsScenarioThe sales department was satisfied with the report you produced in exercise 2. Now the sales staff wouldlike to change the report to show all customers, even if they did not have any orders, and still includethe information about the orders for the customers that did place orders. You need to write a SELECTstatement to retrieve all rows from Sales.Customers (columns custid and contactname) and the orderidcolumn from the table Sales.Orders.The main task for this exercise is as follows:• Write a SELECT statement using an outer join to retrieve the needed columns. Task 1: Write a SELECT statement that uses an outer join• Open the project file F:\10774A_Labs\10774A_05_PRJ\10774A_05_PRJ.ssmssln and the T-<strong>SQL</strong> script81 - Lab Exercise 4.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the custid and contactname columns from the Sales.Customerstable and the orderid column from the Sales.Orders table. The statement should retrieve all rows fromthe Sales.Customers table.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 82 - Lab Exercise 4 - Task 1 Result.txt.• Notice the values in the column orderid. Are there any missing values (marked as NULL)? Why?Results: After this exercise, you should have a basic understanding of how to write T-<strong>SQL</strong> statements thatuse outer joins.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 5-41Exercise 5: Writing Queries That Use Cross JoinsScenarioThe HR department would like to prepare a personalized calendar for each employee. The IT departmentsupplied you with T-<strong>SQL</strong> code that will generate a table with all dates for the current year. Your job is towrite a SELECT statement that would return all rows in this new calendar date table for each row in theHR.Employees table.1. Execute the provided T-<strong>SQL</strong> statement to generate the HR.Calendar table, which includes thecalendardate column, and to populate the table with date information.2. Write a SELECT statement that uses a cross join to retrieve the needed columns. Task 1: Execute the T-<strong>SQL</strong> statement• Open the project file F:\10774A_Labs\10774A_05_PRJ\10774A_05_PRJ.ssmssln and the T-<strong>SQL</strong> script91 - Lab Exercise 5.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Execute the T-<strong>SQL</strong> code under task 1. Do not worry if you do not understand the provided T-<strong>SQL</strong>code, as it is used here to provide a more realistic example for a cross join in the next task. Task 2: Write a SELECT statement that uses a cross join• Write a SELECT statement to retrieve the empid, firstname, and lastname columns from theHR.Employees table and the calendardate column from the HR.Calendar table.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 92 - Lab Exercise 5 - Task 2 Result.txt.• What is the number of rows returned by the query? There are nine rows in the HR.Employees table.Try to calculate the total number of rows in the HR.Calendar table. Task 3: Drop the HR.Calendar table• Execute the provided T-<strong>SQL</strong> statement to remove the HR.Calendar table.Results: After this exercise, you should have an understanding of how to write T-<strong>SQL</strong> statements that usecross joins.


5-42 <strong>Querying</strong> Multiple TablesModule ReviewReview Questions1. How does an inner join differ from an outer join?2. Which join types include a logical Cartesian product?3. Can a table be joined to itself?Best Practices1. Table aliases should always be defined when joining tables.2. Joins should be expressed using <strong>SQL</strong>-92 syntax, with JOIN and ON keywords.


6-1Module 6Sorting and Filtering DataContents:Lesson 1: Sorting Data 6-3Lesson 2: Filtering Data with Predicates 6-10Lesson 3: Filtering Data with TOP and OFFSET-FETCH 6-17Lesson 4: Working with Unknown Values 6-24Lab: Sorting and Filtering Data 6-29


6-2 Sorting and Filtering DataModule OverviewIn this module, you will learn how to enhance your queries to limit the rows they return and to control theorder in which the rows are displayed.Earlier in this course, you learned that according to relational theory, sets of data do not include anydefinition of a sort order. As a result, if you require the output of a query to be displayed in a certainorder, you will need to add an ORDER BY clause to your SELECT statement. In this module, you will learnhow to write queries using ORDER BY to control the display order.In a previous module, you also learned how to build a FROM clause to return rows from one or moretables. It is unlikely that you will always want to return all rows from the source. For performance reasonsas well as the needs of your client application or report, you will want to limit which rows are returned. Asyou will learn in this module, you can limit rows with a WHERE clause based on a predicate, or you canlimit rows with TOP and OFFSET-FETCH based on number of rows and ordering.As you work with real-world data in your queries, you may encounter situations where values are missing.It is important to write queries that can handle missing values correctly. In this module, you will learnabout handling missing and unknown results.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-3Lesson 1Sorting DataIn this lesson, you will learn how to add an ORDER BY clause to your queries to control the order of rowsdisplayed in your query's output.


6-4 Sorting and Filtering DataUsing the ORDER BY ClauseIn the logical order of query processing, ORDER BY is the last phase of a SELECT statement to execute.ORDER BY provides you with the ability to control the sorting of rows as they are output from the queryto the client application. Without an ORDER BY clause, Microsoft® <strong>SQL</strong> Server® does not guarantee theorder of rows, in keeping with relational theory.To sort the output of your query, you will add an ORDER BY clause to your query in this form:SELECT FROM ORDER BY ASC|DESC;ORDER BY can take several types of elements in its list:• Columns by name. (Additional columns beyond the first specified in the list will be used as tiebreakersfor non-unique values in the first column.)• Column aliases. (Remember that ORDER BY is processed after the SELECT clause and therefore hasaccess to aliases defined in the SELECT list.)• Columns by position in the SELECT clause. (This is not recommended due to diminished readabilityand due to the extra care required to keep the ORDER BY list up to date with any changes made tothe column order in the SELECT list.)• Columns not listed in the SELECT list, but part of tables listed in the FROM clause. (If the query uses aDISTINCT option, then any columns in the ORDER BY list must be found in the SELECT list.)Note ORDER BY may also include a COLLATE clause, which provides a way to sort by aspecific character collation, and not the collation of the column in the table. Collations willbe further discussed later in this course.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-5In addition to specifying which columns should be used to determine the sort order, you may also controlthe direction of the sort through the use of ASC for an ascending sort (A-Z, 0-9) or DESC for a descendingsort (Z-A, 9-0). Ascending sorts are the default. Each column may be provided with a separate order, as inthe following example. Employees will be listed from most recent hire to least recent, with employeeshired on the same date listed alphabetically by last name:USE T<strong>SQL</strong><strong>2012</strong>;GOSELECT hiredate, firstname, lastnameFROM HR.EmployeesORDER BY hiredate DESC, lastname ASC;For More Information Additional documentation on the ORDER BY clause can be foundin Books Online at http://go.microsoft.com/fwlink/?LinkId=220166.


6-6 Sorting and Filtering DataORDER BY Clause SyntaxThe syntax of the ORDER BY clause appears as follows:ORDER BY OFFSET ROW|ROWS FETCH FIRST|NEXT ROW|ROWS ONLYNote The use of the OFFSET-FETCH option in the ORDER BY clause will be covered later inthis module.Most variations of ORDER BY will occur in the ORDER BY list. To specify columns by name with the defaultascending order, use the following syntax:ORDER BY , ;A fragment of code using columns from the T<strong>SQL</strong><strong>2012</strong> Sales.Customers table would look like this:ORDER BY country, region, city;To specify columns by aliases defined in the SELECT clause, use the following syntax:SELECT AS alias1, AS alias2FROM ORDER BY alias1;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-7A query for the T<strong>SQL</strong><strong>2012</strong> Sales.Orders table using column aliases would look like this:SELECT orderid, custid, YEAR(orderdate) AS orderyearFROM Sales.OrdersORDER BY orderyear;Note See the previous topic for the syntax and usage of ASC or DESC to control sortorder.


6-8 Sorting and Filtering DataORDER BY Clause ExamplesThe following are examples of common queries using ORDER BY to sort the output for display. All queriesuse the T<strong>SQL</strong><strong>2012</strong> sample database.A query against the Sales.Orders table, sorting the results by the orderdate column, specified by name:SELECT orderid, custid, orderdateFROM Sales.OrdersORDER BY orderdate;A query against the Sales.Orders table, which defines an alias in the SELECT clause and sorts by thatcolumn's alias:SELECT orderid, custid, YEAR(orderdate) AS orderyearFROM Sales.OrdersORDER BY orderyear DESC;A query against the Sales.Orders table, which sorts the output in descending order of orderdate (i.e., mostrecent to oldest):SELECT orderid, custid, orderdateFROM Sales.OrdersORDER BY orderdate DESC;A query against the HR.Employees table, which sorts the employees in descending order of hiredate (i.e.,most recent tooldest), using lastname to differentiate employees hired on the same date:SELECT hiredate, firstname, lastnameFROM HR.EmployeesORDER BY hiredate DESC, lastname ASC;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-9Demonstration: Sorting DataDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. From the File menu, click Open, click Project/Solution, navigateto F:\10774A_Labs\10774A_06_PRJ\10774A_06_PRJ.ssmssln, and click Open.2. Open the 11 - -Demonstration A.sql script file.3. Follow the instructions contained within the comments of the script file.Question: Does the physical order of rows in a <strong>SQL</strong> Server table guarantee any sort order inqueries using the table?


6-10 Sorting and Filtering DataLesson 2Filtering Data with PredicatesMost of the time when querying <strong>SQL</strong> Server <strong>2012</strong>, you will want to retrieve only a subset of all the rowsstored in the table listed in the FROM clause. This is especially true as data volumes grow. In order to limitwhich rows are returned, you typically will use the WHERE clause in the SELECT statement. In this lesson,you will learn how to construct WHERE clauses to filter out rows that do not match the predicate.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-11Filtering Data in the WHERE Clause with PredicatesIn order to limit the rows that are returned by your query, you will need to add a WHERE clause to yourSELECT statement, following the FROM clause. WHERE clauses are constructed from a search condition,which in turn is written as a predicate expression. The purpose of the predicate is to provide a logical filterthrough which each row must pass. Only rows returning TRUE in the predicate will be output to the nextlogical phase of the query.When writing a WHERE clause, keep the following considerations in mind:• Your predicate must be expressed as a logical condition, evaluating to TRUE or FALSE. (This willchange when working with missing values or NULL. See Lesson 4 for more information.)• Only rows for which the predicate evaluates as TRUE will be passed through the filter.• Values of FALSE or UNKNOWN will be filtered out.• Column aliases declared in the query's SELECT clause cannot be used in the WHERE clause predicate.Remember that the WHERE clause is logically the next phase in query execution after FROM, so it will beprocessed before other clauses such as SELECT. A consequence of this is that your WHERE clause will beunable to refer to column aliases created in the SELECT clause. If you have created expressions in theSELECT list, you will need to repeat the expressions in order to use them in the WHERE clause.For example, the following query, which uses a simple calculated expression in the SELECT list, will executeproperly:SELECT orderid, custid, YEAR(orderdate) AS ordyearFROM Sales.OrdersWHERE YEAR(orderdate) = 2006;


6-12 Sorting and Filtering DataThe following query will fail due to the use of column aliases in the WHERE clause:SELECT orderid, custid, YEAR(orderdate) AS ordyearFROM Sales.OrdersWHERE ordyear = 2006;The error message points to the use of the column alias in line 3 of the batch:Msg 207, Level 16, State 1, Line 3Invalid column name 'ordyear'.From the perspective of query performance, the use of effective WHERE clauses can provide a significantimpact on <strong>SQL</strong> Server. Rather than return all rows to the client for post-processing, a WHERE clause causes<strong>SQL</strong> Server to filter data on the server-side. This can reduce network traffic as well as memory usage onthe client. Additionally, <strong>SQL</strong> Server developers and administrators can create indexes to supportcommonly used predicates, furthering improving performance.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-13WHERE Clause SyntaxIn Books Online, the syntax of the WHERE clause appears as follows:WHERE The most common form of a WHERE clause is as follows:WHERE For example, the following code fragment shows a WHERE clause that will filter only customers fromSpain:SELECT contactname, countryFROM Sales.CustomersWHERE country = N'Spain';Any of the logical operators introduced in the T-<strong>SQL</strong> language module earlier in this course may be usedin a WHERE clause predicate. This example filters orders placed after a specified date:SELECT orderid, orderdateFROM Sales.OrdersWHERE orderdate > '20070101';Note The representation of dates as strings delimited by quotation marks will be coveredin the next module.


6-14 Sorting and Filtering DataIn addition to using logical operators, literals, or constants in a WHERE clause, you may also use several T-<strong>SQL</strong> options in your predicate:Predicates and OperatorsINBETWEENLIKEANDORNOTDescriptionDetermines whether a specified value matches any value in asubquery or a list.Specifies an inclusive range to test.Determines whether a specific character string matches a specifiedpattern.Combines two Boolean expressions and returns TRUE only whenboth expressions are TRUE.Combines two Boolean expressions and returns TRUE if eitherexpression is TRUE.Reverses the result of a search condition.Note The use of LIKE to match patterns in character-based data will be covered in thenext module.The following example shows the use of the OR operator to combine conditions in a WHERE clause:SELECT custid, companyname, countryFROM Sales.CustomersWHERE country = N'UK' OR country = N'Spain';The following example modifies the previous query to use the IN operator for the same results:SELECT custid, companyname, countryFROM Sales.CustomersWHERE country IN (N'UK',N'Spain');The following example uses the NOT operator to reverse the previous condition:SELECT custid, companyname, countryFROM Sales.CustomersWHERE country NOT IN (N'UK',N'Spain');The following example uses logical operators to search within a range of dates:SELECT orderid, custid, orderdateFROM Sales.OrdersWHERE orderdate >= '20070101' AND orderdate < '20080101';


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-15The following example accomplishes the same results using the BETWEEN operator:SELECT orderid, custid, orderdateFROM Sales.OrdersWHERE orderdate BETWEEN '20061231' AND '20080101';Note The use of comparison operators with date and time data types requires specialconsideration. For more information, see the next module.


6-16 Sorting and Filtering DataDemonstration: Filtering Data with PredicatesDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. From the File menu, click Open, click Project/Solution, navigateto F:\10774A_Labs\10774A_06_PRJ\10774A_06_PRJ.ssmssln, and click Open.2. Open the 21 - -Demonstration B.sql script file.3. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-17Lesson 3Filtering Data with TOP and OFFSET-FETCHIn the previous lesson, you wrote queries that filtered rows based on data stored within them. You canalso write queries that filter ranges of rows, either based on a specific number to retrieve or one range ofrows at a time. In this lesson, you will learn how to limit ranges of rows in the SELECT clause using a TOPoption. You will also learn how to limit ranges of rows using the OFFSET-FETCH option of an ORDER BYclause.


6-18 Sorting and Filtering DataFiltering in the SELECT Clause Using the TOP OptionWhen returning rows from a query, you may need to limit the total number of rows returned as well asfilter with a WHERE clause. The TOP option, a Microsoft-proprietary extension of the SELECT clause, willlet you specify a number of rows to return, either as an ordinal number or as a percentage of all candidaterows.The simplified syntax of the TOP option is as follows:SELECT TOP (N) FROM WHERE ;For example, to retrieve only the five most recent orders from the Sales.Orders table in the T<strong>SQL</strong><strong>2012</strong>database, use the following query:SELECT TOP (5) orderid, custid, orderdateFROM Sales.OrdersORDER BY orderdate DESC;Note that the TOP operator depends on an ORDER BY clause to provide meaningful precedence to therows selected. In the absence of ORDER BY, there is no guarantee which rows will be returned. In theprevious example, any five orders might be returned if there wasn’t an ORDER BY clause.In addition to specifying a fixed number of rows to be returned, the TOP keyword also accepts the WITHTIES option, which will retrieve any rows with values that might be found in the selected top N rows. Forexample, the following query will return five rows with the most recent order dates:SELECT TOP (5) orderid, custid, orderdateFROM Sales.OrdersORDER BY orderdate DESC;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-19The results show five rows with two distinct orderdate values:orderid custid orderdate----------- ----------- -----------------------11077 65 2008-05-06 00:00:00.00011076 9 2008-05-06 00:00:00.00011075 68 2008-05-06 00:00:00.00011074 73 2008-05-06 00:00:00.00011073 58 2008-05-05 00:00:00.000(5 row(s) affected)However, by adding the WITH TIES option to the TOP clause, you will see that more rows qualify for thesecond-oldest order date:SELECT TOP (5) WITH TIES orderid, custid, orderdateFROM Sales.OrdersORDER BY orderdate DESC;This modified query returns the following results:orderid custid orderdate----------- ----------- -----------------------11077 65 2008-05-06 00:00:00.00011076 9 2008-05-06 00:00:00.00011075 68 2008-05-06 00:00:00.00011074 73 2008-05-06 00:00:00.00011073 58 2008-05-05 00:00:00.00011072 20 2008-05-05 00:00:00.00011071 46 2008-05-05 00:00:00.00011070 44 2008-05-05 00:00:00.000(8 row(s) affected)As you can see, whether to include WITH TIES will depend on your knowledge of the source data and itspotential for unique values.To return a percentage of the row count, instead of a fixed number, use the PERCENT option with TOP.For example, if the Sales.Orders table contains 830 orders, the following query will return 83 rows:SELECT TOP (10) PERCENT orderid, custid, orderdateFROM Sales.OrdersORDER BY orderdate DESC;TOP (N) PERCENT may also be used with the WITH TIES option.Note TOP (N) PERCENT will round up to the nearest integer for purposes of row counts.For More Information Additional information about the TOP clause can be found inBooks Online at http://go.microsoft.com/fwlink/?LinkId=242848.


6-20 Sorting and Filtering DataFiltering in the ORDER BY Clause Using OFFSET-FETCHWhile the TOP option is used by many <strong>SQL</strong> Server professionals as a method for retrieving only a certainrange of rows, it has its disadvantages as well:• TOP is proprietary to T-<strong>SQL</strong> and <strong>SQL</strong> Server.• TOP does not support skipping a range of rows.• Since TOP depends on an ORDER BY clause, you cannot use one sort order to establish the rowsfiltered by TOP and another sort order to determine the display of the output.To address a number of these concerns, Microsoft has added a new option to <strong>SQL</strong> Server <strong>2012</strong>: theOFFSET-FETCH extension to the ORDER BY clause.Like TOP, OFFSET-FETCH allows you to return only a range of the rows selected by your query. However itadds the functionality to supply a starting point (an offset) and a value to specify how many rows youwould like to return (a fetch value). This provides a convenient technique for paging through results.When paging, you will need to consider that each query with an OFFSET-FETCH clause runsindependently of any previous or subsequent query; there is no server-side state maintained. You willneed to track your position through a result set via client-side code.As you will see in the next topic, OFFSET-FETCH has been written to allow a more natural Englishlanguagesyntax.For More Information For additional information about the OFFSET-FETCH clause, seethe section "Using OFFSET and FETCH to limit the rows returned" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242849.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-21OFFSET-FETCH SyntaxThe syntax for the OFFSET-FETCH clause is as follows:OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS }[FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW |ROWS } ONLY]To use OFFSET-FETCH, you will supply a starting OFFSET value (which may be zero) and an optionalnumber of rows to return, as in the following example. This example will skip the first 10 rows and thenreturn the next 10 rows, as determined by the order date:SELECT orderid, custid, orderdateFROM Sales.OrdersORDER BY orderdate, orderid DESCOFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;As you can see in the syntax definition, the OFFSET clause is required, but the FETCH clause is not. If theFETCH clause is omitted, all rows following OFFSET will be returned. Additionally, you will find that thekeywords ROW and ROWS are interchangeable, as are FIRST and NEXT, which allows a more naturalsyntax.To ensure the accuracy of your results, especially as you ‘‘move’’ from page to page of data, it is importantto construct an ORDER BY clause that will provide unique ordering and yield a deterministic result.Although unlikely due to <strong>SQL</strong> Server’s query optimizer, it is technically possible for a row to appear onmore than one page unless the range of rows is deterministic.Note To use OFFSET-FETCH for paging, you may supply the OFFSET value as well as rowcount expressions in the form of variables or parameters. You will learn more aboutvariables and stored procedure parameters in later modules of this course.


6-22 Sorting and Filtering DataThe following are some examples of using OFFSET-FETCH in T-<strong>SQL</strong> queries. All queries use the T<strong>SQL</strong>2010sample database:To retrieve the 50 most recent rows as determined by the order date, this query starts with an offset ofzero. It will return a result similar to a SELECT TOP(50) query:SELECT orderid, custid, empid, orderdateFROM Sales.OrdersORDER BY orderdate DESCOFFSET 0 ROWS FETCH FIRST 50 ROWS ONLY;This query will retrieve rows 51-100 of a result set:SELECT orderid, custid, empid, orderdateFROM Sales.OrdersORDER BY orderdate DESCOFFSET 50 ROWS FETCH NEXT 50 ROWS ONLY;Note Unlike examples found in any previous modules, examples of OFFSET-FETCH mustbe executed by <strong>SQL</strong> Server <strong>2012</strong> or later. OFFSET-FETCH is not supported in <strong>SQL</strong> Server2008 R2 or earlier.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-23Demonstration: Filtering Data with TOP and OFFSET-FETCHDemonstration Steps1. In the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. From the File menu, click Open, click Project/Solution, navigateto F:\10774A_Labs\10774A_06_PRJ\10774A_06_PRJ.ssmssln and click Open.2. Open the 31 - -Demonstration C.sql script file.3. Follow the instructions contained within the comments of the script file.


6-24 Sorting and Filtering DataLesson 4Working with Unknown ValuesUnlike traditional Boolean logic, predicate logic in <strong>SQL</strong> Server needs to account for missing values anddeal with cases where the result of a predicate is unknown. In this lesson, you will learn how three-valuedlogic accounts for unknown and missing values, how <strong>SQL</strong> Server uses NULL to mark missing values, andhow to test for NULL in your queries.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-25Three-Valued LogicEarlier in this course, you learned that <strong>SQL</strong> Server uses predicate logic as a framework for logical tests thatreturn TRUE or FALSE. This is true for logical expressions where all values being tested are present. If youknow the values of both X and Y, you can safely determine whether X>Y is TRUE or FALSE.However, in <strong>SQL</strong> Server, not all data being compared may be present. You need to plan for and act on thepossibility that some data is missing or unknown. Values in <strong>SQL</strong> Server may be missing but applicable,such as the value of a middle initial that has not been supplied for an employee. It may also be missingbut inapplicable, such as the value of a middle initial for an employee who has no middle name. In bothcases, <strong>SQL</strong> Server will mark the missing value as NULL. A NULL is neither TRUE nor FALSE. It is a mark forUNKNOWN, which represents the third value in three-valued logic.As discussed above, you can determine whether X>Y is TRUE or FALSE when you know the values of bothX and Y. But what if Y is missing? What does <strong>SQL</strong> Server return for the expression X>Y when Y is missing?<strong>SQL</strong> Server will return an UNKNOWN, marked as NULL. You will need to account for the possible presenceof NULL in your predicate logic as well as in the values stored in columns marked with NULL. You willneed to write queries that use three-valued logic to account for three possible outcomes: TRUE, FALSE,and UNKNOWN.


6-26 Sorting and Filtering DataHandling NULL in QueriesOnce you have acquired a conceptual understanding of three-valued logic and NULL, you need tounderstand the different mechanisms <strong>SQL</strong> Server uses for handling NULLs. Keep in mind the followingguidelines:• Query filters, such as ON, WHERE, and the HAVING clause, treat NULL like a FALSE result. A WHEREclause that tests for a = N will not return rows when the comparison is FALSE. Norwill it return rows when either the column value or the value of N is NULL. Note the output of thefollowing queries:SELECT empid, lastname, regionFROM HR.EmployeesORDER BY region ASC; --Ascending sort order explicitly included for clarityThis returns the following, with all employees whose region is missing (marked as NULL) sorted first:empid lastname region----------- -------------------- ---------------5 Buck NULL6 Suurs NULL7 King NULL9 Dolgopyatova NULL8 Cameron WA1 Davis WA2 Funk WA3 Lew WA4 Peled WANote A common question about controlling the display of NULL in queries is whetherNULLs can be forced to the end of a result set. As you can see, the ORDER BY clause sortsthe NULLs together and first, and you cannot override this behavior.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-27• ORDER BY treats NULLs as if they were the same value and always sorts NULLs together, putting themfirst in a column. Make sure you test the results of any queries in which the column being used forsort order contains NULLs, and understand the impact of ascending and descending sorts on NULLs.• In ANSI-compliant queries, a NULL is never equivalent to another value, even another NULL. Querieswritten to test NULL with an equality will fail to return correct results. Note the following example:SELECT empid, lastname, regionFROM HR.EmployeesWHERE region = NULL;This returns inaccurate results:empid lastname region----------- -------------------- ---------------(0 row(s) affected)• Use the IS NULL (or IS NOT NULL) operator rather than equals (not equals), as in the followingexample:SELECT empid, lastname, regionFROM HR.EmployeesWHERE region IS NULL;This returns correct results:empid lastname region----------- -------------------- ---------------5 Buck NULL6 Suurs NULL7 King NULL9 Dolgopyatova NULL(4 row(s) affected)


6-28 Sorting and Filtering DataDemonstration: Working with NULLDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. From the File menu, click Open, click Project/Solution, navigateto F:\10774A_Labs\10774A_06_PRJ\10774A_06_PRJ.ssmssln, and click Open.2. Open the 41 - -Demonstration D.sql script file.3. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-29Lab: Sorting and Filtering DataLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the ‘‘Press CTRL+ALT+DELETE to log on’’message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the ‘‘Press CTRL+ALT+DELETE to log on’’message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


6-30 Sorting and Filtering Data7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You have been provided with a set of business requirements for data and youwill write T-<strong>SQL</strong> queries to retrieve the specified data from the databases. You will need to retrieve onlysome of the available data, and return it to your reports in a specified order.Important When comparing your results with the provided sample outputs, the columnordering and total number of affected rows should always match. However, remember thatthe order of the rows in the output of a query without an ORDER BY clause is notguaranteed. Therefore, the order of the rows in the sample outputs may be different thanyours. Also, the answer outputs include abbreviated results.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-31Exercise 1: Writing Queries That Filter Data Using a WHERE ClauseScenarioThe marketing department is working on several campaigns for existing customers. The marketing staffneeds to get different lists of customers, depending on several business rules. Based on these rules, youwill write the SELECT statements to retrieve the needed rows from the Sales.Customers table.The main tasks for this exercise are as follows:1. Write several SELECT statements that use different predicates in the WHERE clause.2. Correct the query supplied by the IT department.3. Answer questions. Task 1: Write a SELECT statement that uses a WHERE clause• Open the project file F:\10774A_Labs\10774A_06_PRJ\10774A_06_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement that will return the custid, companyname, contactname, address, city,country, and phone columns from the Sales.Customers table. Filter the results to include only thecustomers from the country Brazil.• Execute the written statement and compare the results that you got with the desired results shown inthe file 52 - Lab Exercise 1 - Task 1 Result.txt. Task 2: Write a SELECT statement that uses an IN predicate in the WHERE clause• Write a SELECT statement that will return the custid, companyname, contactname, address, city,country, and phone columns from the Sales.Customers table. Filter the results to include onlycustomers from the countries Brazil, UK, and USA.• Execute the written statement and compare the results that you got with the desired results shown inthe file 53 - Lab Exercise 1 - Task 2 Result.txt. Task 3: Write a SELECT statement that uses a LIKE predicate in the WHERE clause• Write a SELECT statement that will return the custid, companyname, contactname, address, city,country, and phone columns from the Sales.Customers table. Filter the results to include only thecustomers with a contact name starting with the letter A.• Execute the written statement and compare the results that you got with the desired results shown inthe file 54 - Lab Exercise 1 - Task 3 Result.txt.


6-32 Sorting and Filtering Data Task 4: Observe the T-<strong>SQL</strong> statement provided by the IT department• The IT department has written a T-<strong>SQL</strong> statement that retrieves the custid and companynamecolumns from the Sales.Customers table and the orderid column from the Sales.Orders table:SELECTc.custid, c.companyname, o.orderidFROM Sales.Customers AS cLEFT OUTER JOIN Sales.Orders AS o ON c.custid = o.custid AND c.city = 'Paris';• Execute the query. Notice two things. First, the query retrieves all the rows from the Sales.Customerstable. Second, there is a comparison operator in the ON clause specifying that the city column shouldbe equal to the value ‘‘Paris’’.• Copy the provided T-<strong>SQL</strong> statement and modify it to have a comparison operator for the city columnin the WHERE clause. Execute the query.• Compare the results that you got with the desired results shown in the file55 - Lab Exercise 1 - Task 4 Result.txt.• Is the result the same as in the first T-<strong>SQL</strong> statement? Why? What is the difference between specifyingthe predicate in the ON clause and in the WHERE clause? Task 5: Write a SELECT statement to retrieve those customers without orders• Write a T-<strong>SQL</strong> statement to retrieve customers from the Sales.Customers table that do nothave matching orders in the Sales.Orders table. Matching customers with orders is based on acomparison between the customer’s custid value and the order’s custid value. Retrieve the custid andcompanyname columns from the Sales.Customers table. (Hint: Use a T-<strong>SQL</strong> statement that is similar tothe one in the previous task.)• Execute the written statement and compare the results that you got with the desired results shown inthe file 56 - Lab Exercise 1 - Task 5 Result.txt.Results: After this exercise, you should be able to filter rows of data from one or more tables by usingWHERE predicates with logical operators.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-33Exercise 2: Writing Queries That Sort Data Using an ORDER BY ClauseScenarioThe sales department would like to have a report showing all the orders with some customer information.An additional request is that the result be sorted by the order dates and the customer IDs. Rememberfrom the previous modules that the order of the rows in the output of a query without an ORDER BYclause is not guaranteed. Because of this, you will have to write a SELECT statement that uses an ORDERBY clause.The main tasks for this exercise are as follows:1. Write a SELECT statement that uses an ORDER BY clause.2. Analyze and correct a query. Task 1: Write a SELECT statement that uses an ORDER BY clause• Open the project file F:\10774A_Labs\10774A_06_PRJ\10774A_06_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the custid and contactname columns from the Sales.Customerstable and the orderid and orderdate columns from the Sales.Orders table. Filter the results to includeonly orders placed on or after April 1, 2008 (filter the orderdate column). Then sort the result byorderdate in descending order and custid in ascending order.• Execute the written statement and compare the results that you got with the desired results shown inthe file 62 - Lab Exercise 2 - Task 1 Result.txt. Task 2: Apply the needed changes and execute the T-<strong>SQL</strong> statement• Someone took your T-<strong>SQL</strong> statement from lab 4 and added the following WHERE clause:SELECTe.empid, e.lastname, e.firstname, e.title, e.mgrid,m.lastname AS mgrlastname, m.firstname AS mgrfirstnameFROM HR.Employees AS eINNER JOIN HR.Employees AS m ON e.mgrid = m.empidWHERE mgrlastname = 'Buck';• Execute the query exactly as written inside a query window and observe the result.• You get an error. What is the error message? Why do you think you got this error? (Tip: Rememberthe logical processing order of the query.)• Apply the needed changes to the SELECT statement so that it will run without an error. Test thechanges by executing the T-<strong>SQL</strong> statement.• Observe and compare the results that you got with the recommended results shown in the file63 - Lab Exercise 2 - Task 2 Result.txt.


6-34 Sorting and Filtering Data Task 3: Order the result by the firstname column• Copy the existing T-<strong>SQL</strong> statement from task 2 and modify it so that the result will return allemployees and be ordered by the manager’s first name. Try first to use the source column name, andthen try to use the alias column name.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 64 - Lab Exercise 2 - Task 3 Result.txt.• Why were you able to use a source column name or an alias column name?Results: After this exercise, you should know how to use an ORDER BY clause.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-35Exercise 3: Writing Queries That Filter Data Using the TOP OptionScenarioThe Sales department would like to have some additional reports that show the last invoiced orders andthe top 10 percent of the most expensive products being sold.The main tasks for this exercise are as follows:1. Write a SELECT statement that will return the last 20 orders based on order date.2. Write a SELECT statement that will return the top 10 percent of products based on unit price. Task 1: Write a SELECT statement to retrieve the last 20 orders• Open the project file F:\10774A_Labs\10774A_06_PRJ\10774A_06_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement against the Sales.Orders table and retrieve the orderid and orderdatecolumns. Retrieve the last 20 orders, based on orderdate ordering.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 72 - Lab Exercise 3 - Task 1 Result.txt. Task 2: Use the OFFSET-FETCH clause to implement the same task• Write a SELECT statement to retrieve the same result as in task 1, but use the OFFSET-FETCH clause.• Execute the written statement and compare the results that you got with the results from task 1. Task 3: Write a SELECT statement to retrieve the most expensive products• Write a SELECT statement to retrieve the productname and unitprice columns from theProduction.Products table.• Execute the T-<strong>SQL</strong> statement and notice the number of the rows returned.• Modify the SELECT statement to include only the top 10 percent of products based on unitpriceordering.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 73 - Lab Exercise 3 - Task 2 Result.txt. Notice the number of rows returned.• Is it possible to implement this task with the OFFSET-FETCH clause?Results: After this exercise, you should have an understanding of how to apply the TOP option in theSELECT clause of a T-<strong>SQL</strong> statement.


6-36 Sorting and Filtering DataExercise 4: Writing Queries That Filter Data Using the OFFSET-FETCHClauseScenarioIn this exercise, you will implement a paging solution for displaying rows from the Sales.Orders tablebecause the total number of rows is high. In each page of a report, the user should only see 20 rows.The main task for this exercise is as follows:• Write a SELECT statement using the OFFSET-FETCH clause. Task 1: Use the OFFSET-FETCH clause to fetch the first 20 rows• Open the project file F:\10774A_Labs\10774A_06_PRJ\10774A_06_PRJ.ssmssln and the T-<strong>SQL</strong> script81 - Lab Exercise 4.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the custid, orderid, and orderdate columns from theSales.Orders table. Order the rows by orderdate and orderid. Retrieve the first 20 rows.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 82 - Lab Exercise 4 - Task 1 Result.txt. Task 2: Use the OFFSET-FETCH clause to skip the first 20 rows• Copy the SELECT statement in task 1 and modify the OFFSET-FETCH clause to skip the first 20 rowsand fetch the next 20 rows.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 83 - Lab Exercise 4 - Task 2 Result.txt. Task 3: Write a generic form of the OFFSET-FETCH clause for paging• You are given the parameters @pagenum for the requested page number and @pagesize for therequested page size. Can you figure out how to write a generic form of the OFFSET-FETCH clauseusing those parameters? (Do not worry about not being familiar with those parameters yet.)Results: After this exercise, you should have a basic understanding of how to use the OFFSET-FETCHclause.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 6-37Module ReviewReview Questions1. Is the use of ordinal column positions in an ORDER BY clause recommended? Why or why not?2. Can column aliases defined in a SELECT clause be used in an ORDER BY clause? Why or why not?3. What is the relationship between the ORDER BY clause and an OFFSET-FETCH clause?


6-38 Sorting and Filtering Data


7-1Module 7Working with <strong>SQL</strong> Server <strong>2012</strong> Data TypesContents:Lesson 1: Introducing <strong>SQL</strong> Server <strong>2012</strong> Data Types 7-3Lesson 2: Working with Character Data 7-15Lesson 3: Working with Date and Time Data 7-27Lab: Working with <strong>SQL</strong> Server <strong>2012</strong> Data Types 7-36


7-2 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesModule OverviewIn order to write effective queries in T-<strong>SQL</strong>, you will need to understand how Microsoft® <strong>SQL</strong> Server®stores different types of data. This will be especially important if your queries not only retrieve data fromtables but also perform comparisons, manipulate data, and implement other operations.In this module, you will learn about the data types <strong>SQL</strong> Server uses to store data. In the first lesson, youwill be introduced to many types of numeric and special-use data types. You will learn about conversionsbetween data types and the importance of data type precedence. You will learn how to work withcharacter-based data types, including functions that can be used to manipulate the data. You will alsolearn how to work with temporal data, or date and time data, including functions to retrieve andmanipulate all or portions of a stored date.ObjectivesAfter completing this module, you will be able to:• Describe numeric data types, type precedence, and type conversions.• Write queries using character data types.• Write queries using date and time data types.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-3Lesson 1Introducing <strong>SQL</strong> Server <strong>2012</strong> Data TypesIn this lesson, you will explore many of the data types <strong>SQL</strong> Server uses to store data and how data typesare converted between types.Note Character, date, and time data types are excluded from this lesson and will becovered later in this module.If your focus in taking this course is to write queries for reports, you may wish to take note of which datatypes are used in your environment and plan your reports and client applications with enough capacity todisplay the range of values the <strong>SQL</strong> Server data types hold. You may also need to plan for conversions inyour queries in order to display <strong>SQL</strong> Server data in other environments.If your focus in taking this course is to continue into database development and administration, you maywish to take note of the similarities and differences within categories of data types, and plan your storageaccordingly as you create types and design parameters for stored procedures.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe how <strong>SQL</strong> Server uses data types.• Describe the attributes of numeric data types, as well as binary strings and other specialized datatypes.• Describe data type precedence and its use in converting data between different data types.• Describe the difference between implicit and explicit data type conversion.


7-4 Working With <strong>SQL</strong> Server <strong>2012</strong> Data Types<strong>SQL</strong> Server Data Types<strong>SQL</strong> Server <strong>2012</strong> defines a set of system data types for storing data in columns, for holding valuestemporarily in variables, for operating on data in expressions, and for passing as parameters in storedprocedures. Data types specify the type, length, precision, and scale of data. Understanding the basictypes of data in <strong>SQL</strong> Server is fundamental to writing queries in T-<strong>SQL</strong>, as well as designing tables andcreating other objects in <strong>SQL</strong> Server.<strong>SQL</strong> Server supplies built-in data types of various categories. Developers may also extend the supplied setby creating aliases to built-in types and even by creating new user-defined types using the Microsoft .NETFramework. This lesson will focus on the built-in system data types.Other than character, date, and time types, which will be covered later in this module, <strong>SQL</strong> Server datatypes can be grouped into the following categories:• Exact numeric. These data types store data with precision, either as:• Integers with varying degrees of capacity• Decimals that allow you to specify how many total digits should be stored and how many ofthose digits should be to the right of the decimal placeAs you learn about these types, take note of the relationship between capacity and storagerequirements.• Approximate numeric. These data types allow inexact values to be stored, typically for use inscientific calculations.• Binary strings. These data types allow binary data to be stored, such as bytestreams or hashes, tosupport custom applications.• Other data types. This catch-all category includes special types such as uniqueidentifier and XML,which are sometimes used as column data types (and therefore accessible to queries). It also includesdata types that are not used for storage, but rather for special operations such as cursormanipulations or creating output tables for further processing. If you are a report writer, it is likelyyou may only encounter the uniqueidentifier and XML data types.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-5Numeric Data TypesWhen working with exact numeric data, you will see that there are three basic subcategories of data typesin <strong>SQL</strong> Server: exact numeric, decimal numeric, and approximate numeric. Each <strong>SQL</strong> Server data type fallsinto one of these categories.Exact numeric types include:• Integers, where the distinction between types relates to capacity and storage requirements. Notethat the tinyint data type, for example, can only hold values between 0 to 255, for the storage cost of1 byte. At the other end of the spectrum, the bigint data type can hold plus or minus 9 quintillion (avery large value) at the cost of 8 bytes. You will need to decide which integer data type offers the bestfit for capacity versus storage. Often you will see that the int data type has been selected for usebecause it provides the best tradeoff: a capacity of plus or minus 2 billion at the cost of 4 bytes.• Decimal and numeric, which allow you to specify the total number of digits to be stored (precision)and the number of digits to the right of the decimal (scale). As with integers, the greater the range,the higher the storage cost. Note that while decimal is ISO standards-compliant, decimal and numericare equivalent to one another. Numeric is kept for compatibility with earlier versions of <strong>SQL</strong> Server.• Money and smallmoney, which are designed to hold monetary values with a maximum of fourplaces. You may find that your organization uses the decimal type instead of money for its greaterflexibility and precision.• Bit, which is a single-bit value used to store Boolean values or flags. Storage for a bit column isdependent on how many other bit columns there may be in a table, due to <strong>SQL</strong> Server optimizingtheir storage.For More Information See the following topics in Books Online: "decimal and numeric(Transact <strong>SQL</strong>)" at http://go.microsoft.com/fwlink/?LinkId=242850, "Precision, Scale, andLength (Transact-<strong>SQL</strong>)" at http://go.microsoft.com/fwlink/?LinkId=242851, and "Data Types(Transact-<strong>SQL</strong>)" at http://go.microsoft.com/fwlink/?LinkId=233831.


7-6 Working With <strong>SQL</strong> Server <strong>2012</strong> Data Types<strong>SQL</strong> Server also supplies data types for approximate numeric values. The approximate numeric data typesare less accurate but have more capacity than the exact numeric data types. The approximate numericdata types store values in scientific notation, which loses accuracy because of a lack of precision.• Float takes an optional parameter of the number of digits to be stored after the decimal. Thisparameter is called the mantissa, and the value of the mantissa determines the storage size of thefloat. If the mantissa is in the range 1 to 24, the float requires 4 bytes. If the mantissa is between 25and 53, it requires 8 bytes.• Real is an ISO synonym for float(24).For More Information See the topic "float and real (Transact-<strong>SQL</strong>)" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242852.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-7Binary String Data TypesBinary string data types allow a developer to store binary information, such as serialized files, images,bytestreams, and other specialized data. If you are considering using the binary data type, note thedifferences in range and storage compared with integers and character string data. You can choosebetween fixed-width and varying-width binary strings. The difference between these will be explained inthe character data type lesson later in the module.The following example shows a number converted to a binary data type. (You will learn about the CASTfunction in the next module.) This query:SELECT CAST(12345 AS BINARY(4)) AS Result;Returns the following:Result----------0x00003039For More Information See the topic "binary and varbinary (Transact-<strong>SQL</strong>)" in BooksOnline at http://go.microsoft.com/fwlink/?LinkId=242853.


7-8 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesOther Data TypesIn addition to numeric and binary types, <strong>SQL</strong> Server also supplies some other data types, allowing you tostore and process XML, generate globally unique identifiers (GUIDs), represent hierarchies, and more.Some of these have limited use, others are more generally useful:• Rowversion is a binary value, auto-incrementing when a row in a table is inserted or updated. Itdoes not actually store time data in a form that will be useful to you. Rowversion has other limitationsas well.• Uniqueidentifier provides a mechanism for an automatically generated value that is unique acrossmultiple systems. It is stored as a 16 byte value. Uniqueidentifier must be generated either byconverting from a string (reducing the guarantee of uniqueness) or by using the NEWID() systemfunction. For example, this query:SELECT NEWID() AS [GUID];Returns:GUID------------------------------------1C0E3B5C-EA7A-41DC-8E1C-D0A302B5E58B• XML allows the storage and manipulation of eXtensible Markup Language data. This data type storesup to 2 GB of data per instance of the type.For More Information See course 10776A: Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong>Databases for additional information on the XML data type.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-9• Cursors are listed here for completeness. A <strong>SQL</strong> Server cursor is not a data type for storing data, butrather for use in variables or stored procedures that reference a cursor object. Discussions of cursorsare beyond the scope of this module.• Hierarchyid is a data type used to store hierarchical position data, such as levels of an organizationalchart or bill of materials. <strong>SQL</strong> Server stores hierarchy data as binary data and exposes it through builtinfunctions.For More Information See course 10776: Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong>Databases for additional information about the hierarchyid data type.• <strong>SQL</strong>_variant is a column data type that can store other common data types. Its use is not a bestpractice for typical data storage and may indicate design problems. It is listed here for completeness.• Table data types can be used to store the results of T-<strong>SQL</strong> statements for further processing later,such as in a subsequent statement in a query. You will learn more about table types later in thiscourse. Note that table types cannot be used as a data type for a column (such as to store nestedtables).For More Information Information on all of <strong>SQL</strong> Server's data types can be found inBooks Online starting at http://go.microsoft.com/fwlink/?LinkId=233831.


7-10 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesData Type PrecedenceWhen combining or comparing different data types in your queries, such as in a WHERE clause,<strong>SQL</strong> Server will need to convert one value from its data type to the data type of the other value.Which data type is converted depends on data type precedence between the two types.<strong>SQL</strong> Server defines a ranking of all its data types by precedence: between any two data types, one willhave a lower precedence and one will have a higher precedence. When converting, <strong>SQL</strong> Server willconvert the lower data type to the higher. This typically will happen implicitly, without the need for specialcode. However, it is important for you to have a basic understanding of this precedence arrangement soyou will know when you need to manually, or explicitly, convert data types for the purposes of combiningor converting them.For example, here is a partial list of data types, ranked according to their precedence:1. XML2. Datetime23. Date4. Time5. Decimal6. Int7. Tinyint8. Nvarchar9. Char


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-11When combining or comparing two expressions with different data types, the expression lower on this listwill be converted to the type higher on the list. In this example, the variable of type tinyint will beimplicitly converted to int before being added to the int variable @myInt:DECLARE @myTinyInt AS TINYINT = 25;DECLARE @myInt as INT = 9999;SELECT @myTinyInt + @myInt;Note Implicit conversions are transparent to the user. If an implicit conversion fails (suchas when your operation requires converting from a higher precedence to a lowerprecedence), you will need to explicitly convert the data type. You will learn how to use theCAST function for this purpose in the next module.For More Information For more information and a complete list of types and theirprecedence, see Books Online at http://go.microsoft.com/fwlink/?LinkId=233806.


7-12 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesWhen Are Data Types Converted?There are a number of scenarios in which data types may be converted when querying <strong>SQL</strong> Server:• When data is moved, compared, or combined with other data• During variable assignment• When using any operator that involves two operands of different types• When T-<strong>SQL</strong> code explicitly converts one type to another, using a CAST or CONVERT functionIn the previous topic's example, you saw that the tinyint data type was implicitly converted to int in thequery:DECLARE @myTinyInt AS TINYINT = 25;DECLARE @myInt as INT = 9999;SELECT @myTinyInt + @myInt;You might also anticipate that an implicit conversion will take place in the following example:DECLARE @somechar CHAR(5) = '6';DECLARE @someint INT = 1SELECT @somechar + @someint;Question: Which data type will be converted? To which type?As you have learned, <strong>SQL</strong> Server will automatically attempt to perform an implicit conversion from alower-precedence data type to a higher-precedence. This is transparent to the user, unless it fails, as in thefollowing example:DECLARE @somechar CHAR(3) = 'six';DECLARE @someint INT = 1SELECT @somechar + @someint;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-13Returns:Msg 245, Level 16, State 1, Line 3Conversion failed when converting the varchar value 'six' to data type int.Question: Why does <strong>SQL</strong> Server attempt to convert the character variable to an integer andnot the other way around?In order to force <strong>SQL</strong> Server to convert the int data type to a character for the purposes of the query, youwill need to explicitly convert it. You will learn how to do this in the next module.For More Information To learn more about data type conversions, see Books Online athttp://go.microsoft.com/fwlink/?LinkId=242854.


7-14 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesDemonstration: <strong>SQL</strong> Server Data TypesDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_07_PRJ\10774A_07_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-15Lesson 2Working with Character DataIt is likely that much of the data you will work with in your T-<strong>SQL</strong> queries will involve character data. Asyou will learn in this lesson, character data involves not only choices of capacity and storage, but also textspecificissues such as language, sort order, and collation. In this lesson, you will learn about the <strong>SQL</strong>Server character-based data types, how character comparisons work, and some common functions youmay find useful in your queries.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the character data types supplied by <strong>SQL</strong> Server.• Describe the impact of collation on character data.• Concatenate strings.• Extract and manipulate character data using built-in functions.• Write queries using the LIKE predicate for matching patterns in text.


7-16 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesCharacter Data TypesEven though there are many numeric data types in <strong>SQL</strong> Server, working with numbers is relativelystraightforward because there are only so many numbers to work with. By comparison, character data in<strong>SQL</strong> Server is far more wide open, due to issues such as language, character sets, accented characters, sortrules, case-sensitivity, as well as capacity and storage. Each of these issues will have an impact on whichcharacter data type you will encounter when writing queries.Note Character data is delimited with single quotes.• One initial choice is character types based on a simple ASCII set versus Unicode, the double-bytecharacter set. Regular, or non-Unicode, characters are limited to a 256 character set and occupy 1byte per character. These include the CHAR (fixed width) and VARCHAR (varying width) data types.Characters using these data types are delimited with single quotes, such as '<strong>SQL</strong>'.• Unicode data types include NCHAR (fixed width) and NVARCHAR (varying width). These mayrepresent approximately 65,000 different characters, including special characters from manylanguages, and consume 2 bytes per character. Character strings using this type have an N prefix (forNational), such as N'<strong>SQL</strong>'.• Character data types also provide for larger storage, in the form of regular and Unicode varying widthtypes declared with the MAX option: VARCHAR(MAX) and NVARCHAR(MAX). These can store up to 2GB (with each Unicode character using 2 bytes) per instance, and replace the deprecated TEXT andNTEXT data types, respectively.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-17Character data type ranges and storage requirements are listed in the following table:Data Type Range StorageCHAR(n),NCHAR(n)VARCHAR(n),NVARCHAR(n)VARCHAR(max),NVARCHAR(max)1-8000 characters n bytes, padded2*n bytes, padded1-8000 characters n+2 bytes(2*n) + 2 bytes1-2^31-1 characters Actual length + 2


7-18 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesCollationIn addition to size and character set, <strong>SQL</strong> Server character data types are assigned a collation. Thisassignment may be at one of several levels: the server instance, the database (default), or a collationassigned to a column in a table or in an expression. Collations are collections of properties that governseveral aspects of character data:• Supported languages• Sort order• Case sensitivity• Accent sensitivityNote A default collation is established during the installation of <strong>SQL</strong> Server but can beoverridden on a per-database or per-column basis. As you will see, you may also overridethe current collation for some character data by explicitly setting a different collation inyour query.When querying, it will be important to be aware of what the collation settings are for your character data.For example, is it case-sensitive? The following query will execute differently based on whether thecolumn being compared is case-sensitive or not. If the column is case-sensitive and the desired value isFunk, then this will succeed:SELECT empid, lastnameFROM HR.employeesWHERE lastname = N'Funk';


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-19For the same data, this query would return invalid results if the column were case-sensitive:SELECT empid, lastnameFROM HR.employeesWHERE lastname = N'funk';To control how your query is treating collation settings, you can add the optional COLLATE clause to theWHERE clause. This example will force a case-sensitive and accent-sensitive comparison using theLatin1_General character set:SELECT empid, lastnameFROM HR.employeesWHERE lastname COLLATE Latin1_General_CS_AS = N'Funk';


7-20 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesString ConcatenationTo concatenate, or join together, two strings, <strong>SQL</strong> Server uses the + (plus) operator. The followingexample concatenates a given name, a space, and a family name into a single string:SELECTempid, lastname, firstname, firstname + N' ' + lastname AS fullnameFROM HR.Employees;Note Since the plus sign is also used for arithmetic addition, be aware of whether any ofyour data is numeric when concatenating. Characters have a lower precedence thannumbers, and <strong>SQL</strong> Server will attempt to convert and add mixed data types rather thanconcatenating them.<strong>SQL</strong> Server <strong>2012</strong> introduces a new CONCAT() function, which returns a string that is the result ofconcatenating one or more string values. Unlike the + operator, CONCAT() will convert any NULLs toempty strings before concatenation. The syntax is as follows:CONCAT(string_value1, string_value2, string_valueN)An example of CONCAT() is:SELECT custid, city, region, country,CONCAT(city, ', ' + region, ', ' + country) AS locationFROM Sales.Customers;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-21This query returns the following partial results:custid city region country location------ ----------- ------ -------- -------------------1 Berlin NULL Germany Berlin, Germany2 México D.F. NULL Mexico México D.F., Mexico3 México D.F. NULL Mexico México D.F., Mexico4 London NULL UK London, UK5 Luleå NULL Sweden Luleå, SwedenFor More Information See the topic "CONCAT (Transact-<strong>SQL</strong>)" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=221358.


7-22 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesCharacter String FunctionsIn addition to retrieving character data as-is from <strong>SQL</strong> Server, you may also need to extract portions oftext or determine the location of characters within a larger string. <strong>SQL</strong> Server provides a number of builtinfunctions to accomplish these tasks. Some of these functions include:• FORMAT() - new to <strong>SQL</strong> Server <strong>2012</strong> - allows you to format an input value to a character string basedon a .NET format string, with an optional culture parameter:SELECT top (3) orderid, FORMAT(orderdate,'d','en-us') AS us,FORMAT(orderdate,'d','de-DE') AS deFROM Sales.Orders;Returns:Ordered us de------- -------- ----------10248 7/4/2006 04.07.200610249 7/5/2006 05.07.200610250 7/8/2006 08.07.2006• SUBSTRING() for returning part of a character string given a starting point and a number ofcharacters to return:SELECT SUBSTRING('Microsoft <strong>SQL</strong> Server',11,3) AS Result;Returns:Result------<strong>SQL</strong>


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-23• LEFT() and RIGHT() for returning the leftmost or rightmost characters, respectively, up to a providedpoint in a string:SELECT LEFT('Microsoft <strong>SQL</strong> Server',9) AS Result;Returns:Result---------Microsoft• LEN() and DATALENGTH() for providing metadata about the number of characters or number ofbytes stored in a string. Given a string padded with spaces:SELECT LEN('Microsoft <strong>SQL</strong> Server ') AS [LEN];SELECT DATALENGTH('Microsoft <strong>SQL</strong> Server ') AS [DATALEN];Returns:LEN-----------20DATALEN-----------25• CHARINDEX() for returning a number representing the position of a string within another string:SELECT CHARINDEX('<strong>SQL</strong>','Microsoft <strong>SQL</strong> Server') AS Result;Returns:Result-----------11• REPLACE() for substituting one set of characters with another set within a string:SELECT REPLACE('Microsoft <strong>SQL</strong> Server Denali','Denali','<strong>2012</strong>') AS Result;Returns:Result------Microsoft <strong>SQL</strong> Server <strong>2012</strong>


7-24 Working With <strong>SQL</strong> Server <strong>2012</strong> Data Types• UPPER() and LOWER() for performing case conversions:SELECT UPPER('Microsoft <strong>SQL</strong> Server') AS [UP],LOWER('Microsoft <strong>SQL</strong> Server') AS [LOW];Returns:UPLOW-------------------- --------------------MICROSOFT <strong>SQL</strong> SERVER microsoft sql serverFor More Information For references on these and other string functions, see BooksOnline at http://go.microsoft.com/fwlink/?LinkId=242855.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-25The LIKE PredicateCharacter-based data in <strong>SQL</strong> Server provides for more than exact matches in your queries. Through theuse of the LIKE predicate, you can also perform pattern matching in your WHERE clause.The LIKE predicate allows you to check a character string against a pattern. Patterns are expressed withsymbols, which can be used alone or in combinations to search within your strings:• % (Percent) represents a string of any length. For example, LIKE N'Sand%' will match 'Sand','Sandwich', 'Sandwiches', etc.• _ (Underscore) represents a single character. For example, LIKE N'_a' will match any string whosesecond character is an 'a'.• [] represents a single character within the supplied list. For example, LIKEN'[DEF]%' will find any string that starts with a 'D', an 'E', or an 'F'.• [ - ] represents a single character within the specified range. For example,LIKE N'[N-Z]%' will match any string that starts with any letter of the alphabet between N and Z,inclusive.• [^] represents a single character not in the specified list or range. Forexample, LIKE N'^[A]% will match a string beginning with anything other than an 'A'.• ESCAPE Character allows you to search for a character that is also a wildcard character. For example,LIKE N'10% off%' ESCAPE '%' will find any string that starts with 10%, including the literal character'%'.


7-26 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesDemonstration: Working with Character DataDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_07_PRJ\10774A_07_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-27Lesson 3Working with Date and Time DataDate and time data is very common in working with <strong>SQL</strong> Server data types. In this lesson, you will learnwhich data types are used to store temporal data, how to enter dates and times so they will be properlyparsed by <strong>SQL</strong> Server, and how to manipulate dates and times with built-in functions.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the data types used to store date and time information.• Enter dates and times as literal values for <strong>SQL</strong> Server to convert to date and time types.• Write queries comparing dates and times.• Write queries using built-in functions to manipulate dates and extract date parts.


7-28 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesDate and Time Data TypesThere has been a progression in <strong>SQL</strong> Server's handling of temporal data as newer versions of <strong>SQL</strong> Serverare released. Since you may need to work with data created for older versions of <strong>SQL</strong> Server even thoughyou're writing queries for <strong>SQL</strong> Server <strong>2012</strong>, it will be useful to review past support for date and time data:• Prior to <strong>SQL</strong> Server 2008, there were only two data types for date and time data: DATETIME andSMALLDATETIME. Each of these stored both date and time in a single value. For example, aDATETIME could store '<strong>2012</strong>0212 08:30:00' to represent February 12 <strong>2012</strong> at 8:30 AM.• In <strong>SQL</strong> Server 2008, Microsoft introduced four new data types: DATETIME2, DATE, TIME, andDATETIMEOFFSET. These addressed issues of precision, capacity, time zone tracking, and separatingdates from times.• In <strong>SQL</strong> Server <strong>2012</strong>, Microsoft introduced new functions for working with partial data from date andtime data types (such as DATEFROMPARTS) and for performing calculations on dates (such asEOMONTH).


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-29Date and Time Data Types: LiteralsIn order to use date and time data in your queries, you will need to be able to represent temporal data inT-<strong>SQL</strong>. <strong>SQL</strong> Server doesn't offer a specific option for entering dates and times, so you will use characterstrings called literals, which are delimited with single quotes. <strong>SQL</strong> Server will implicitly convert the literalsto date and time values. (You may also explicitly convert literals with the T-<strong>SQL</strong> CAST function, which youwill learn about in the next module.)<strong>SQL</strong> Server can interpret a wide variety of literal formats as dates, but for consistency and to avoid issueswith language or nationality interpretation, it is recommended that you use a neutral format such as'YYYYMMDD'. To represent February 12, <strong>2012</strong>, you would use the literal '<strong>2012</strong>0212'. To use literals in aquery, see the following example:SELECT orderid, custid, empid, orderdateFROM Sales.OrdersWHERE orderdate = '20070825';


7-30 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesBesides 'YYYYMMDD', other language-neutral formats are available to you:Data Type Language-Neutral Formats ExamplesDATETIMESMALLDATETIMEDATETIME2DATE'YYYYMMDD hh:mm:ss.nnn''YYYY-MM-DDThh:mm:ss.nnn''YYYYMMDD''YYYYMMDD hh:mm''YYYY-MM-DDThh:mm''YYYYMMDD''YYYY-MM-DD''YYYYMMDD hh:mm:ss.nnnnnnn''YYYY-MM-DD hh:mm:ss.nnnnnnn''YYYY-MM-DDThh:mm:ss.nnnnnnn''YYYYMMDD''YYYY-MM-DD''YYYYMMDD''YYYY-MM-DD''<strong>2012</strong>0212 12:30:15.123''<strong>2012</strong>-02-12T12:30:15.123''<strong>2012</strong>0212''<strong>2012</strong>0212 12:30''<strong>2012</strong>-02-12T12:30''<strong>2012</strong>0212''<strong>2012</strong>-02-12''<strong>2012</strong>0212 12:30:15.1234567''<strong>2012</strong>-02-12 12:30:15.1234567''<strong>2012</strong>-02-12T12:30:15.1234567''<strong>2012</strong>0212''<strong>2012</strong>-02-12''<strong>2012</strong>0212''<strong>2012</strong>-02-12'TIME 'hh:mm:ss.nnnnnnn' '12:30:15.1234567'DATETIMEOFFSET'YYYYMMDD hh:mm:ss.nnnnnnn [+|-]hh:mm''YYYY-MM-DD hh:mm:ss.nnnnnnn [+|-]hh:mm''YYYYMMDD''YYYY-MM-DD''<strong>2012</strong>0212 12:30:15.1234567+02:00''<strong>2012</strong>-02-12 12:30:15.1234567+02:00''<strong>2012</strong>0212''<strong>2012</strong>-02-12'


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-31Working with Date and Time SeparatelyAs you have learned, some <strong>SQL</strong> Server temporal data types store both date and time together in onevalue. DATETIME and DATETIME2 combine year, month, day, hour, minute, seconds, and more.DATETIMEOFFSET adds time zone information to the date and time as well. The time and datecomponents are optional in combination data types such as DATETIME2. So, when using these data types,you need to be aware of how they behave when provided with only partial data:• If only the date is provided, the time portion of the data type is filled with zeros and the time isconsidered to be at midnight. For example, the query:DECLARE @DateOnly AS DATETIME = '<strong>2012</strong>0212';SELECT @DateOnly AS RESULT;Returns:RESULT-----------------------<strong>2012</strong>-02-12 00:00:00.000• If no date data is available and you need to store time data in a combination data type, you can entera "base" date of January 1, 1900. Alternatively, you can use the CAST() function to convert the timedata to a combination data type while entering just the time value. <strong>SQL</strong> Server will assume the basedate. Explicit zeros for the date portion are not permitted.


7-32 Working With <strong>SQL</strong> Server <strong>2012</strong> Data Types<strong>Querying</strong> Date and Time ValuesWhen querying date and time data types, it is important to know whether your source data includes timevalues other than zeros. If all your time values are midnight, then queries such as the following will workas expected:SELECT orderid, custid, empid, orderdateFROM Sales.OrdersWHERE orderdate= '20070825'This query returns:orderid custid empid orderdate----------- ----------- ----------- -----------------------10643 1 6 2007-08-25 00:00:00.00010644 88 3 2007-08-25 00:00:00.000Note that the orderdate time values are all set to zero. This matches the query predicate, which also omitstime, implicitly asking only for rows at midnight.If your data includes time values, you will need to modify your logic to catch time values after midnight.For example, if the following rows existed in an orders2 table:orderid custid empid orderdate----------- ----------- ----------- -----------------------10643 1 6 2007-08-29 08:30:00.00010644 88 3 2007-08-29 11:55:00.000Then the following query would fail to select them:SELECT orderid, empid, custid, orderdateFROM orders2WHERE orderdate = '20070829'


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-33But this query would successfully retrieve the rows:SELECT orderid, empid, custid, orderdateFROM orders2WHERE orderdate >= '20070829'Note The previous example is supplied for illustration only and cannot be run as written inthe sample databases supplied with this course.As a result, you will need to account for time past midnight for rows where there are values stored in thetime portion of combination data types. Consider the use of range operators instead:SELECT orderid, custid, empid, orderdateFROM Sales.OrdersWHERE orderdate >= '20070825'AND orderdate < '20070826';


7-34 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesDate and Time FunctionsOver the years, <strong>SQL</strong> Server has supplied a number of functions designed to manipulate date and timedata. <strong>SQL</strong> Server <strong>2012</strong> introduces new functions as well:• Functions that return current date and time, offering you choices between various return types, aswell as whether to include or exclude time zone information.• Functions that return parts of date and time values, enabling you to extract only the portion of a dateor time that your query requires. Note that DATENAME() and DATEPART() offer functionality similarto one another. The difference between them is the return type.• Functions that return date and time typed data from components such as separately supplied year,month, and day. Previous versions required parsing of strings to assemble a literal that looked like adate. These new functions allow you to pass in simple numeric inputs for the functions to convert tothe corresponding date and time value. Note that these functions require all their parameters.• Functions that modify date and time values, including functions to increment dates, to calculate thelast day of a month, and to alter time zone offset information.• Functions that examine date and time values, returning metadata or calculations about intervalsbetween input dates.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-35Demonstration: Working with Date and Time DataDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_07_PRJ\10774A_07_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 31 – Demonstration C.sql script file.4. Follow the instructions contained within the comments of the script file.


7-36 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesLab: Working with <strong>SQL</strong> Server <strong>2012</strong> Data TypesLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-377. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You have been provided with a set of business requirements for data and youwill write T-<strong>SQL</strong> queries to retrieve the specified data from the databases. You will need to retrieve andconvert character and temporal data into various formats.Important When comparing your results with the provided sample outputs, the columnordering and total number of affected rows should always match. However, remember thatthe order of the rows in the output of a query without an ORDER BY clause is notguaranteed. Therefore, the order of the rows in the sample outputs may be different thanyours. Also, the answer outputs include abbreviated results.


7-38 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesExercise 1: Writing Queries That Return Date and Time DataScenarioBefore you start using different date and time functions in business scenarios, you have to practice onsample data.The main tasks for this exercise are as follows:1. Write a couple of SELECT statements using the date and time functions.2. Answer questions. Task 1: Write a SELECT statement to retrieve the current date and time• Open the project file F:\10774A_Labs\10774A_07_PRJ\10774A_07_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to return columns that contain:• The current date and time. Use the alias currentdatetime.• Just the current date. Use the alias currentdate.• Just the current time. Use the alias currenttime.• Just the current year. Use the alias currentyear.• Just the current month number. Use the alias currentmonth.• Just the current day of month number. Use the alias currentday.• Just the current week number in the year. Use the alias currentweeknumber.• The name of the current month based on the currentdatetime column. Use the aliascurrentmonthname.• Execute the written statement and compare the results that you got with the desired results shown inthe file 52 - Lab Exercise 1 - Task 1 Result.txt. Your results will be different because of the current dateand time value.• Can you use the alias currentdatetime as the source in the second column calculation (currentdate)?Please explain. Task 2: Write a SELECT statement to return the data type date• Write December 11, 2011, as a column with a data type of date. Use the different possibilities insidethe T-<strong>SQL</strong> language (cast, convert, specific function, etc.) and use the alias somedate.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-39 Task 3: Write a SELECT statement that uses different date and time functions• Write a SELECT statement to return columns that contain:• A date and time value that is three months from the current date and time. Use the aliasthreemonths.• Number of days between the current date and the first column (threemonths). Use the aliasdiffdays.• Number of weeks between April 4, 1992, and September 16, 2011. Use the alias diffweeks.• First day in the current month based on the current date and time. Use the alias firstday.• Execute the written statement and compare the results that you got with the desired results shown inthe file 53 - Lab Exercise 1 - Task 3 Result.txt. Some results will be different because of the currentdate and time value. Task 4: Observe the table provided by the IT department• The IT department has written a T-<strong>SQL</strong> statement that creates and populates a table namedSales.Somedates.• Execute the provided T-<strong>SQL</strong> statement.• Write a SELECT statement against the Sales.Somedates table and retrieve the isitdate column. Add anew column named converteddate with a new date data type value based on the column isitdate. Ifthe isitdate column cannot be converted to a date data type for a specific row, then return a NULL.• Execute the written statement and compare the results that you got with the desired results shown inthe file 54 - Lab Exercise 1 - Task 4 Result.txt.• What is the difference between the SYSDATETIME and CURRENT_TIMESTAMP functions?• What is a language-neutral format for the DATE type?Results: After this exercise, you should be able to retrieve date and time data using T-<strong>SQL</strong>.


7-40 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesExercise 2: Writing Queries That Use Date and Time FunctionsScenarioThe sales department would like to have different reports that focus on data during specific time frames.The sales staff would like to analyze distinct customers, distinct products, and orders placed near the endof the month. You will have to write the SELECT statements using the different date and time functions.The main tasks for this exercise are as follows:1. Write a SELECT statement to retrieve all distinct customers that placed an order in February 2008.2. Write a SELECT statement to retrieve all orders placed in last five days of the month.3. Write a SELECT statement to show all distinct products being sold in the first 10 weeks of theyear 2007.4. Analyze and correct the query. Task 1: Write a SELECT statement to retrieve all distinct customers• Open the project file F:\10774A_Labs\10774A_07_PRJ\10774A_07_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve distinct values for the custid column from the Sales.Orders table.Filter the results to include only orders placed in February 2008.• Execute the written statement and compare the results that you got with the desired results shown inthe file 62 - Lab Exercise 2 - Task 1 Result.txt. Task 2: Write a SELECT statement to calculate the first and last day of the month• Write a SELECT statement with these columns:• Current date and time• First date of the current month• Last date of the current month• Execute the written statement and compare the results that you got with the recommended resultshown in the file 63 - Lab Exercise 2 - Task 2 Result.txt. Task 3: Write a SELECT statement to retrieve the orders placed in the last five days ofthe ordered month• Write a SELECT statement against the Sales.Orders table and retrieve the orderid, custid, andorderdate columns. Filter the results to include only orders placed in the last five days of theorder month.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 64 - Lab Exercise 2 - Task 3 Result.txt.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-41 Task 4: Write a SELECT statement to retrieve all distinct products sold in the first 10weeks of the year 2007• Write a SELECT statement against the Sales.Orders and Sales.OrderDetails tables and retrieve all thedistinct values for the productid column. Filter the results to include only orders placed in the first 10weeks of the year 2007.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 65 - Lab Exercise 2 - Task 4 Result.txt.Results: After this exercise, you should know how to use the date and time functions.


7-42 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesExercise 3: Writing Queries That Return Character DataScenarioThe members of the marketing department would like to have a more condensed version of a report forwhen they talk with customers. They want the information that currently exists in two columns displayedin a single column.The main tasks for this exercise are as follows:1. Write a SELECT statement that concatenates values from different columns.2. Write a SELECT statement that returns all the customers, where the first character in the contact nameis ‘A’ through ‘G’. Task 1: Write a SELECT statement to concatenate two columns• Open the project file F:\10774A_Labs\10774A_07_PRJ\10774A_07_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement against the Sales.Customers table and retrieve the contactname and citycolumns. Concatenate both columns so that the new column looks like this:Allen, Michael (city: Berlin)• Execute the written statement and compare the results that you got with the recommended resultshown in the file 72 - Lab Exercise 3 - Task 1 Result.txt. Task 2: Add an additional column and treat NULL as an empty string• Copy the T-<strong>SQL</strong> statement in task 1 and modify it to extend the calculated column with newinformation from the region column. Treat a NULL in the region column as an empty string forconcatenation purposes. When the region is NULL, the modified column should look like this:Allen, Michael (city: Berlin, region: )When the region is not NULL, the modified column should look like this:Richardson, Shawn (city: Sao Paulo, region: SP)• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 73 - Lab Exercise 3 - Task 2 Result.txt. Task 3: Write a SELECT statement to retrieve all customers based on the firstcharacter in the contact name• Write a SELECT statement to retrieve the contactname and contacttitle columns from theSales.Customers table. Return only rows where the first character in the contact name is ‘A’through ‘G’.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 74 - Lab Exercise 3 - Task 3 Result.txt. Notice the number of rows returned.Results: After this exercise, you should have an understanding of how to concatenate character data.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 7-43Exercise 4: Writing Queries That Use Character FunctionsScenarioThe marketing department would like to address customers by their first and last names. In theSales.Customers table, there is only one column named contactname that has both elements separated bya comma. You will have to prepare a report to show the first and last names separately.1. Write a SELECT statement that uses the SUBSTRING function.2. Write a SELECT statement that uses the REPLICATE and REPLACE functions. Task 1: Write a SELECT statement that uses the SUBSTRING function• Open the project file F:\10774A_Labs\10774A_07_PRJ\10774A_07_PRJ.ssmssln and the T-<strong>SQL</strong> script81 - Lab Exercise 4.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the contactname column from the Sales.Customers table. Basedon this column, add a calculated column named lastname, which should consist of all the charactersbefore the comma.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 82 - Lab Exercise 4 - Task 1 Result.txt. Task 2: Extend the SUBSTRING function to retrieve the first name• Write a SELECT statement to retrieve the contactname column from the Sales.Customers table andreplace the comma in the contact name with an empty string. Based on this column, add a calculatedcolumn named firstname, which should consist of all the characters after the comma.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 83 - Lab Exercise 4 - Task 2 Result.txt. Task 3: Write a SELECT statement to change the customer IDs• Write a SELECT statement to retrieve the custid column from the Sales.Customers table. Add a newcalculated column to create a string representation of the custid as a fixed-width (6 characters)customer code prefixed with the letter C and leading zeros. For example, the custid value 1 shouldlook like C00001.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 84 - Lab Exercise 4 - Task 3 Result.txt. Task 4 (challenge): Write a SELECT statement to return the number of characteroccurrences• Write a SELECT statement to retrieve the contactname column from the Sales.Customers table. Add acalculated column, which should count the number of occurrences of the character ‘a’ inside thecontact name. (Hint: Use the string functions REPLACE and LEN.) Order the result from highest tolowest occurrence.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 85 - Lab Exercise 4 - Task 4 Result.txt.Results: After this exercise, you should have an understanding how to use the character functions.


7-44 Working With <strong>SQL</strong> Server <strong>2012</strong> Data TypesModule ReviewReview Questions1. Is <strong>SQL</strong> Server able to implicitly convert an int data type to a varchar?2. What data type is suitable for storing flag information, such as TRUE or FALSE?3. What logical operators are useful for retrieving ranges of date and time values?


8-1Module 8Using Built-In FunctionsContents:Lesson 1: Writing Queries with Built-In Functions 8-3Lesson 2: Using Conversion Functions 8-11Lesson 3: Using Logical Functions 8-21Lesson 4: Using Functions to Work with NULL 8-26Lab: Using Built-In Functions 8-31


8-2 Using Built-In FunctionsModule OverviewIn addition to retrieving data as it is stored in columns, you will often have to compare or furthermanipulate values in your T-<strong>SQL</strong> queries. In this module, you will learn about many functions that are builtinto Microsoft® <strong>SQL</strong> Server®, providing data type conversion, comparison, and NULL handling. You willlearn about the various types of functions in <strong>SQL</strong> Server and how they are categorized. You will work withscalar functions and see where they may be used in your queries. You will learn conversion functions forchanging data between different data types. You will learn how to write logical tests, including the use ofsome functions new in <strong>SQL</strong> Server <strong>2012</strong>. You will learn how to work with NULLs and use built-in functionsto select non-NULL values as well as replace certain values with NULL when applicable.ObjectivesAfter completing this module, you will be able to:• Write queries with built-in scalar functions.• Use conversion functions.• Use logical functions.• Use functions that work with NULL.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-3Lesson 1Writing Queries with Built-In Functions<strong>SQL</strong> Server <strong>2012</strong> provides many built-in functions, ranging from those that perform data type conversionto those that aggregate and analyze groups of rows. In this lesson, you will learn about the types offunctions provided by <strong>SQL</strong> Server, and then focus on working with scalar functions.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the types of built-in functions provided by <strong>SQL</strong> Server <strong>2012</strong>.• Write queries using scalar functions.• Describe aggregate, window, and rowset functions.


8-4 Using Built-In Functions<strong>SQL</strong> Server <strong>2012</strong> Built-In Function TypesFunctions built into <strong>SQL</strong> Server can be categorized as follows:Function CategoryScalarGrouped AggregateWindowRowsetDescriptionOperate on a single row, return a single valueTake one or more input values, return a single summarizing valueOperate on a window (set) of rowsReturn a virtual table that can be used subsequently in a T-<strong>SQL</strong> statementThis course will cover grouped aggregates and window functions in later modules, while rowset functionsare beyond the scope of the course. The rest of this module will cover various scalar functions.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-5Scalar FunctionsScalar functions are functions that return a single value. The number of inputs they take may range fromzero (such as GETDATE) to one (such as UPPER) to multiple (such as DATEADD). Since they always return asingle value, they may be used anywhere a single value (the result) could exist in its own right, fromSELECT clauses to WHERE clause predicates.Built-in scalar functions can be organized into many categories, such as string, conversion, logical,mathematical, and others. This lesson will look at a few common scalar functions.Some considerations when using scalar functions include:• Determinism: Will the function return the same value for the same input and same database stateeach time? Many built-in functions are non-deterministic, and as such their results cannot be indexed.This will have an impact on the query processor's ability to use an index when executing the query.• Collation: When using functions that manipulate character data, which collation will be used? Somefunctions use the collation of the input value, and others use the collation of the database if no inputcollation is supplied.At the time of this writing, Books Online listed over 200 scalar functions. While this course cannot begin tocover each function individually, here are some representative examples:• Date and time functions (covered previously in this course)• Mathematical functions• Conversion functions (covered in more detail later in this module)• System metadata functions


8-6 Using Built-In FunctionsThe following example of the YEAR function shows a typical use of a scalar function in a WHERE clause.The function is calculated once per row, using a column from the row as its input:SELECT orderid, orderdate, YEAR(orderdate) AS orderyearFROM Sales.Orders;The results:orderid orderdate orderyear----------- ----------------------- -----------10248 2006-07-04 00:00:00.000 200610249 2006-07-05 00:00:00.000 200610250 2006-07-08 00:00:00.000 2006The following example of the mathematical ABS function shows the function used to return an absolutevalue multiple times in the same SELECT clause, with differing inputs:SELECT ABS(-1.0), ABS(0.0), ABS(1.0);The results:--- --- ---1.0 0.0 1.0The following example uses the system metadata function DB_NAME() to return the name of the databasecurrently in use by the user's session:SELECT DB_NAME() AS current_database;The results:current_database----------------T<strong>SQL</strong><strong>2012</strong>For More Information Additional information about scalar functions and categories canbe found in Books Online at http://go.microsoft.com/fwlink/?LinkId=233912.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-7Aggregate FunctionsGrouped aggregate functions operate on sets of rows defined in a GROUP BY clause and return asummarized result. Examples include SUM, MIN, MAX COUNT, and AVG. In the absence of a GROUP BYclause, all rows are considered one set and the aggregation is performed on all rows.The following example uses a COUNT function and a SUM function to return aggregate values without aGROUP BY clause:SELECT COUNT(*) AS numorders, SUM(unitprice) AS totalsalesFROM Sales.OrderDetails;The results:numorders totalsales----------- ----------2155 56500.91Note Grouped aggregate functions and the GROUP BY clause will be covered in a latermodule.


8-8 Using Built-In FunctionsWindow FunctionsWindow functions allow you to perform calculations against a user-defined set, or window, of rows. Theyinclude ranking, offset, aggregate, and distribution functions. Windows are defined using the OVER clause,and then window functions are applied to the sets defined.This example uses the RANK function to calculate a ranking based on the unitprice, with the highest priceranked at 1, the next highest ranked 2, etc.:SELECT TOP(5) productid, productname, unitprice,RANK() OVER(ORDER BY unitprice DESC) AS rankbypriceFROM Production.ProductsORDER BY rankbyprice;The results:productid productname unitprice rankbyprice----------- ------------- --------- -----------38 Product QDOMO 263.50 129 Product VJXYN 123.79 29 Product AOZBW 97.00 320 Product QHFFP 81.00 418 Product CKEDC 62.50 5Note Window functions will be covered later in this course. This example is provided forillustration only.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-9Rowset FunctionsRowset functions return a virtual table that can be used elsewhere in the query and take parametersspecific to the rowset function itself. They include OPENDATASOURCE, OPENQUERY, OPENROWSET,and OPENXML.For example, the OPENQUERY function allows you to pass a query to a linked server. It takes the systemname of the linked server and the query expression as parameters. The results of the query are returnedas a rowset, or virtual table, to the query containing the OPENQUERY function.Note Further discussion of rowset functions is beyond the scope of this course. For moreinformation, see Books Online at http://go.microsoft.com/fwlink/?LinkId=242913.


8-10 Using Built-In FunctionsDemonstration: Writing Queries Using Built-In FunctionsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the ServerName text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_08_PRJ\10774A_08_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11- Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-11Lesson 2Using Conversion FunctionsWhen writing T-<strong>SQL</strong> queries, it's very common to need to convert data between data types. Sometimesthe conversion happens automatically, and sometimes you need to control the conversion. In this lesson,you will learn how to explicitly convert data between types using several <strong>SQL</strong> Server functions. You willalso learn to work with some new functions in <strong>SQL</strong> Server <strong>2012</strong> that provide additional flexibility duringconversion.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the difference between implicit conversions and explicit conversions.• Describe when you will need to use explicit conversions.• Explicitly convert between data types using the CAST and CONVERT functions.• Convert strings to date and numbers with the PARSE, TRY_PARSE, and TRY_CONVERT functions.


8-12 Using Built-In FunctionsImplicit and Explicit Data Type ConversionsEarlier in this course, you learned that there are scenarios when data types may be converted during<strong>SQL</strong> Server operations. You learned that <strong>SQL</strong> Server may implicitly convert data types, following theprecedence rules for type conversion. However, you may need to override the type precedence, or forcea conversion where an implicit conversion might fail.To accomplish this, you can use the CAST and CONVERT functions, as well as the new TRY_CONVERTfunction.Some considerations when converting between data types include:• Collation. When CAST or CONVERT returns a character string from a character string input, theoutput uses the same collation as the input. When converting from a non-character type to acharacter, the return value uses the collation of the database. The COLLATE option may be used withCAST or CONVERT to override this behavior.• Truncation. When you convert data between character or binary types and different data types, datamay be truncated, data may appear cut off, or an error may be thrown because the result is too shortto display. Which of these results occurs depends on the data types involved. For example, conversionfrom an integer with a two-digit value to a char(1) will return an '*' which means the character typewas too small to display the results.For More Information Additional reading about truncation behavior can be found inBooks Online at http://go.microsoft.com/fwlink/?LinkId=233807. For more information ondata type conversions, see "Data Type Conversion (Database Engine)" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242854.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-13Converting with CASTTo convert a value from one data type to another, <strong>SQL</strong> Server provides the CAST function. CAST is anANSI-standard function and is therefore recommended over the <strong>SQL</strong> Server-specific CONVERT function,which you will learn about in the next topic.As CAST is a scalar function, you may use it in SELECT and WHERE clauses. The syntax is as follows:CAST( AS )The following example from the T<strong>SQL</strong><strong>2012</strong> sample database uses CAST to convert the orderdate fromdatetime to date:SELECT orderid, orderdate AS order_datetime, CAST(orderdate AS DATE) AS order_dateFROM Sales.Orders;The results:orderid order_datetime order_date----------- ----------------------- ----------10248 2006-07-04 00:00:00.000 2006-07-0410249 2006-07-05 00:00:00.000 2006-07-0510250 2006-07-08 00:00:00.000 2006-07-08If the data types are incompatible, such as attempting to convert a date to a numeric value, CAST willreturn an error:SELECT CAST(SYSDATETIME() AS int);


8-14 Using Built-In FunctionsThe results:Msg 529, Level 16, State 2, Line 1Explicit conversion from data type datetime2 to int is not allowed.For More Information For more information about CAST, see Books Online athttp://go.microsoft.com/fwlink/?LinkId=233807.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-15Converting with CONVERTIn addition to CAST, <strong>SQL</strong> Server provides the CONVERT function. Unlike the ANSI-standard CAST function,the CONVERT function is proprietary to <strong>SQL</strong> Server and is therefore not recommended. However, becauseof its additional capability to format the return value, you may still need to use CONVERT on occasion.As with CAST, CONVERT is a scalar function. You may use CONVERT in SELECT and WHERE clauses. Thesyntax is as follows:CONVERT(, , );The style number argument causes CONVERT to format the return data according to a specified set ofoptions. These options cover a wide range of date and time styles, as well as styles for numeric, XML andbinary data. Some date and time examples include:Style without Century Style with Century Standard Label Value1 101 U.S. mm/dd/yyyy2 102 ANSI yy.mm.dd - no changefor century12 112 ISO yymmdd or yyyymmddThe following example uses CONVERT to convert the current time from datetime to char(8):SELECT CONVERT(CHAR(8), CURRENT_TIMESTAMP, 12) AS ISO_short, CONVERT(CHAR(8),CURRENT_TIMESTAMP, 112) AS ISO_long;


8-16 Using Built-In FunctionsThe results:ISO_short ISO_long--------- --------120212 <strong>2012</strong>0212For More Information For more information about CONVERT and its style options, seeBooks Online at http://go.microsoft.com/fwlink/?LinkId=233807.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-17Converting Strings with PARSEA very common business problem is building a date, time, or numeric value from one or more strings,often concatenated. <strong>SQL</strong> Server <strong>2012</strong> makes this task easier with the new PARSE function. It takes a string,which must be in a form recognizable to <strong>SQL</strong> Server as a date, time, or numeric value, and returns a valueof the specified data type:SELECT PARSE('', [USING ]);The culture parameter must be in the form of a valid .NET Framework culture code, such as 'en-US' for USEnglish, 'es-ES' for Spanish, etc. If the culture parameter is omitted, the settings for the current usersession will be used.The following example converts the string '02/12/<strong>2012</strong>' into a datetime2 using the en-US and es-ESculture codes:SELECT PARSE('02/12/<strong>2012</strong>' AS datetime2 USING 'en-US') AS us_result;The results:us_result----------------------<strong>2012</strong>-02-12 00:00:00.00For More Information For more information about PARSE, including culture codes, seeBooks Online at http://go.microsoft.com/fwlink/?LinkId=233808.


8-18 Using Built-In FunctionsConverting with TRY_PARSE and TRY_CONVERTWhen using CONVERT or PARSE, an error may occur if the input value cannot be converted to thespecified output type. For example, if February 31, <strong>2012</strong> (an invalid date) is passed to CONVERT, a runtimeerror is raised:SELECT CONVERT(datetime2, '<strong>2012</strong>0231');The result:Msg 241, Level 16, State 1, Line 1Conversion failed when converting date and/or time from character string.<strong>SQL</strong> Server <strong>2012</strong> provides new conversion functions to address this. TRY_PARSE and TRY_CONVERT willattempt a conversion, just like PARSE and CONVERT, respectively. However instead of raising a runtimeerror, failed conversions return NULL.The following examples compare PARSE and TRY_PARSE behavior. First, PARSE attempts to convert aninvalid date:SELECT PARSE('<strong>2012</strong>0231' AS datetime2 USING 'en-US')Returns:--Msg 9819, Level 16, State 1, Line 1--Error converting string value 'sqlserver' into data type datetime2 using culture 'en-US'.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-19In contrast, TRY_PARSE handles the error more gracefully:SELECT TRY_PARSE('<strong>2012</strong>0231' AS datetime2 USING 'en-US')Returns:------------------------NULL


8-20 Using Built-In FunctionsDemonstration: Using Conversion FunctionsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_08_PRJ\10774A_08_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-21Lesson 3Using Logical FunctionsSo far in this module, you have learned how to use built-in scalar functions to perform data conversions.In this lesson, you will learn how to use logical functions that evaluate an expression and return a scalarresult.Lesson ObjectivesAfter completing this lesson, you will be able to:• Use T-<strong>SQL</strong> functions to perform logical functions.• Perform conditional tests with the IIF function.• Select items from a list with CHOOSE.


8-22 Using Built-In FunctionsWriting Logical Tests with FunctionsA useful function for validating the data type of an expression is ISNUMERIC. ISNUMERIC tests an inputexpression and returns a 1 if the expression is convertible to any numeric type, including integers,decimals, money, floating point, and real. If the value is not convertible to a numeric type, ISNUMERICreturns a 0.In the following example, which uses the T<strong>SQL</strong><strong>2012</strong> sample database, any employee with a numeric postalcode is returned:SELECT empid, lastname, postalcodeFROM HR.EmployeesWHERE ISNUMERIC(postalcode)=1;The results:empid lastname postalcode----------- -------------------- ----------1 Davis 100032 Funk 100013 Lew 100074 Peled 100095 Buck 100046 Suurs 100057 King 100028 Cameron 100069 Dolgopyatova 10008Question: How might you use ISNUMERIC when testing data quality?


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-23Performing Conditional Tests with IIFIIF is a new logical function in <strong>SQL</strong> Server <strong>2012</strong>. If you have used Visual Basic for Applications in MicrosoftExcel®, used Microsoft Access®, or created expressions in <strong>SQL</strong> Server Reporting Services, you may haveused IIF. As in those environments, IIF accepts three parameters: a logical test to perform, a value to returnif the test evaluates to true, and a value to return if the test evaluates to false or unknown:SELECT IIF(,, 50, 'high','low') AS pricepointFROM Production.Products;Returns:productid unitprice pricepoint----------- --------------------- ----------7 30.00 low8 40.00 low9 97.00 high17 39.00 low18 62.50 highFor More Information To learn more about this new logical function, see "IIF (Transact-<strong>SQL</strong>)" in Books Online at http://go.microsoft.com/fwlink/?LinkId=242914.


8-24 Using Built-In FunctionsSelecting Items from a List with CHOOSECHOOSE is another new logical function in <strong>SQL</strong> Server <strong>2012</strong>. It is similar to the function of the same namein Microsoft Access. CHOOSE returns an item from a list, selecting the item that matches an index value:SELECT CHOOSE(,, [,...]);The following example uses CHOOSE to return a category name based on an input value:SELECT CHOOSE (3, 'Beverages', 'Condiments', 'Confections') AS choose_result;Returns:choose_result-------------ConfectionsNote If the index value supplied to CHOOSE does not correspond to a value in the list,CHOOSE will return a NULL.For More Information For additional information about this new logical function,see "CHOOSE (Transact-<strong>SQL</strong>)" in Books Online at http://go.microsoft.com/fwlink/?LinkId=242915.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-25Demonstration: Using Logical FunctionsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_08_PRJ\10774A_08_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 31 – Demonstration C.sql script file.4. Follow the instructions contained within the comments of the script file.


8-26 Using Built-In FunctionsLesson 4Using Functions to Work with NULLOften you will have to take special steps to deal with NULL. Earlier in this module, you learned how to testfor NULL with ISNULL. In this module, you will learn additional functions for working with NULL.Lesson ObjectivesAfter completing this lesson, you will be able to:• Use ISNULL to replace NULLs.• Use the COALESCE function to return non-NULL values.• Use the NULLIF function to return NULL if values match.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-27Converting NULL with ISNULLIn addition to data type conversions, <strong>SQL</strong> Server provides functions for conversion or replacement ofNULL. Both COALESCE and ISNULL can replace NULL input with another value.To use ISNULL, supply an expression to check for NULL and a replacement value, as in the followingexample using the T<strong>SQL</strong><strong>2012</strong> sample database. For customers with a region evaluating to NULL, the literal"N/A" is returned by the ISNULL function:SELECT custid, city, ISNULL(region, 'N/A') AS region, countryFROM Sales.Customers;The result:custid city region country----------- --------------- --------------- ---------------40 Versailles N/A France41 Toulouse N/A France43 Walla Walla WA USA45 San Francisco CA USANote ISNULL is not standard. Use COALESCE instead. COALESCE will be covered later inthis module.For More Information To learn more about ISNULL, see "ISNULL (Transact-<strong>SQL</strong>)" inBooks Online at http://go.microsoft.com/fwlink/?LinkId=242916.


8-28 Using Built-In FunctionsUsing COALESCE to Return Non-NULL ValuesEarlier in this module, you learned how to use the ISNULL function to test for NULL. Since ISNULL is notANSI standard, you may wish to use the COALESCE function instead. COALESCE takes as its input one ormore expressions, and returns the first non-NULL argument it finds.With only two arguments, COALESCE behaves like ISNULL. However, with more than two arguments,COALESCE can be used as an alternative to a multi-part CASE expression using ISNULL.If all arguments are NULL, COALESCE returns NULL. The syntax is as follows:SELECT COALESCE([, ...];The following example returns customers with regions where available, and adds a new columncombining country, region and city, replacing NULL regions with a space:SELECT custid, country, region, city,country + ',' + COALESCE(region, ' ') + ', ' + city as locationFROM Sales.Customers;Returns:custid country region city location------ ------- ------ ----------- ----------------------17 Germany NULL Aachen Germany, , Aachen65 USA NM Albuquerque USA,NM, Albuquerque55 USA AK Anchorage USA,AK, Anchorage83 Denmark NULL Århus Denmark, , ÅrhusNote For more information on COALESCE and comparisons to ISNULL, see Books Onlineat http://go.microsoft.com/fwlink/?LinkId=242918.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-29Using NULLIF to Return NULL If Values MatchThe NULLIF function is the first function you will learn in this module that is designed to return NULL if itscondition is met. NULLIF returns NULL when two arguments match. This has useful applications in areassuch as data cleansing, when you wish to replace blank or placeholder characters with NULL.NULLIF takes two arguments and returns NULL if both arguments match. If they are not equal, NULLIFreturns the first argument.In this example, NULLIF replaces an empty string (if present) with a NULL, but returns the employeemiddle initial if it is present:SELECT empid, lastname, firstname, NULLIF(middleinitial,' ') AS middle_initialFROM HR.Employees;Returns:empid lastname firstname middle_initial----------- -------------------- ---------- --------------1 Davis Sara NULL2 Funk Don D3 Lew Judy NULL4 Peled Yael YNote This example is provided for illustration only and will not run against the sampledatabase supplied with this course.For More Information For more information, see "NULLIF (Transact-<strong>SQL</strong>)" in BooksOnline at http://go.microsoft.com/fwlink/?LinkId=242924.


8-30 Using Built-In FunctionsDemonstration: Using Functions to Work with NULLDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_08_PRJ\10774A_08_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 41 – Demonstration D.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-31Lab: Using Built-In FunctionsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


8-32 Using Built-In Functions7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You have been provided with a set of business requirements for data and youwill write T-<strong>SQL</strong> queries to retrieve the specified data from the databases. You will need to retrieve thedata, convert the data, and check for missing values.Important When comparing your results with the provided sample outputs, the columnordering and total number of affected rows should always match. However, remember thatthe order of the rows in the output of a query without an ORDER BY clause is notguaranteed. Therefore, the order of the rows in the sample outputs may be different thanyours. In addition, the answer outputs include abbreviated results.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-33Exercise 1: Writing Queries That Use Conversion FunctionsScenarioYou have to prepare a couple of reports for the business users and the IT department.The main tasks for this exercise are as follows:1. Write a SELECT statement using the CAST or CONVERT function.2. Write a SELECT statement to filter rows based on specific date information.3. Write a SELECT statement to convert the phone number information to an integer value. Task 1: Write a SELECT statement that uses the CAST or CONVERT function• Open the project file F:\10774A_Labs\10774A_08_PRJ\10774A_08_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement against the Production.Products table to retrieve a calculated columnnamed productdesc. The calculated column should be based on the columns productname andunitprice and look like this:Results: The unit price for the Product HHYDP is 18.00 $.• Execute the written statement and compare the results that you got with the desired results shown inthe file 52 - Lab Exercise 1 - Task 1 Result.txt.• Did you use the CAST or the CONVERT function? Which one do you think is more appropriate to use? Task 2: Write a SELECT statement to filter rows based on specific date information• The US marketing department has supplied you with a start date of 4/1/2007 (using US English form,read as April 1, 2007) and an end date of 11/30/2007 (using US English form, read as November 30,2007). Write a SELECT statement against the Sales.Orders table to retrieve the orderid, orderdate,shippeddate, and shipregion columns. Filter the result to include only rows with the order datebetween the specified start date and end date and have more than 30 days between the shipped dateand order date. Also check the shipregion column for missing values. If there is a missing value, thenreturn the value ‘No region’.• In this SELECT statement, you can use the CONVERT function with a style parameter or the newPARSE function.• Execute the written statement and compare the results that you got with the desired results shown inthe file 53 - Lab Exercise 1 - Task 2 Result.txt.


8-34 Using Built-In Functions Task 3: Write a SELECT statement to convert the phone number information to aninteger value• The IT department would like to convert all the information about phone numbers in theSales.Customers table to integer values. The IT staff indicated that all hyphens, parentheses, andspaces have to be removed before the conversion to an integer data type.• Write a SELECT statement to implement the requirement of the IT department. Replace all thespecified characters in the phone column of the Sales.Customers table and then convert the columnfrom the nvarchar datatype to the int datatype. The T-<strong>SQL</strong> statement must not fail if there is aconversion error, but rather it should return a NULL. (Hint: First try writing a T-<strong>SQL</strong> statement usingthe CONVERT function and then use the new functionality in <strong>SQL</strong> Server <strong>2012</strong>.) Use the aliasphoneasint for this calculated column.• Execute the written statement and compare the results that you got with the desired results shown inthe file 54 - Lab Exercise 3 - Task 3 Result.txt.Results: After this exercise, you should know how to use the conversion functions.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-35Exercise 2: Writing Queries That Use Logical FunctionsScenarioThe sales department would like to have different reports regarding the segmentation of customers andspecific order lines. You will add a new calculated column to show the target group for the segmentation.The main tasks for this exercise are as follows:1. Write a SELECT statement to mark specific customers based on one or more logical predicates insidethe logical function.2. Write a SELECT statement to segment the customers into four groups using the modulo operator. Task 1: Write a SELECT statement to mark specific customers based on their countryand contact title• Open the project file F:\10774A_Labs\10774A_08_PRJ\10774A_08_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement against the Sales.Customers table and retrieve the custid and contactnamecolumns. Add a calculated column named segmentgroup using a logical function IIF with the value“Target group” for customers that are from Mexico and have in the contact title the value “Owner”.Use the value “Other” for the rest of the customers.• Execute the written statement and compare the results that you got with the desired results shown inthe file 62 - Lab Exercise 2 - Task 1 Result.txt. Task 2: Modify the T-<strong>SQL</strong> statement to mark different customers• Modify the T-<strong>SQL</strong> statement from task 1 to change the calculated column to show the value “Targetgroup” for all customers without a missing value in the region attribute or with the value “Owner” inthe contact title attribute.• Execute the written statement and compare the results that you got with the recommended resultshown in the file 63 - Lab Exercise 2 - Task 2 Result.txt. Task 3: Create four groups of customers• Write a SELECT statement against the Sales.Customers table and retrieve the custid and contactnamecolumns. Add a calculated column named segmentgroup using the logical function CHOOSE withfour possible descriptions (“Group One”, “Group Two”, “Group Three”, “Group Four”). Use the modulooperator on the column custid. (Use the expression custid % 4 + 1 to determine the target group.)• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 64 - Lab Exercise 2 - Task 3 Result.txt.Results: After this exercise, you should know how to use the logical functions.


8-36 Using Built-In FunctionsExercise 3: Writing Queries That Test for NullabilityScenarioThe sales department would like to have additional segmentation of customers. Some columns that youshould retrieve contain missing values, and you will have to change the NULL to some more meaningfulinformation for the business users.The main tasks for this exercise are as follows:1. Write a SELECT statement that will retrieve the customer fax information.2. Write a SELECT statement that will return all the customers that do not have a two-characterabbreviation for the region. Task 1: Write a SELECT statement to retrieve the customer fax information• Open the project file F:\10774A_Labs\10774A_08_PRJ\10774A_08_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the contactname and fax columns from the Sales.Customerstable. If there is a missing value in the fax column, return the value ‘No information’.• Write two solutions, one using the COALESCE function and the other using the ISNULL function.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 72 - Lab Exercise 3 - Task 1 Result.txt.• What is the difference between the ISNULL and COALESCE functions? Task 2: Write a filter for a variable that could be a NULL• Update the provided T-<strong>SQL</strong> statement with a WHERE clause to filter the region column using theprovided variable @region, which can have a value or a NULL. Test the solution using both providedvariable declaration cases.DECLARE @region AS NVARCHAR(30) = NULL;SELECTcustid, regionFROM Sales.Customers;GODECLARE @region AS NVARCHAR(30) = N'WA';SELECTcustid, regionFROM Sales.Customers;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 8-37 Task 3: Write a SELECT statement to return all the customers that do not have atwo-character abbreviation for the region• Write a SELECT statement to retrieve the contactname, city, and region columns from theSales.Customers table. Return only rows that do not have two characters in the region column,including those with an inapplicable region (where the region is NULL).• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 73 - Lab Exercise 3 - Task 3 Result.txt. Notice the number of rows returned.Results: After this exercise, you should have an understanding of how to test for nullability.


8-38 Using Built-In FunctionsModule ReviewReview Questions1. Which function should you use to convert from an int to a nchar(8)?2. Which function will return a NULL rather than an error message if it cannot convert a string to a date?3. What is the name for a function that returns a single value?


9-1Module 9Grouping and Aggregating DataContents:Lesson 1: Using Aggregate Functions 9-3Lesson 2: Using the GROUP BY Clause 9-13Lesson 3: Filtering Groups with HAVING 9-21Lab: Grouping and Aggregating Data 9-26


9-2 Grouping and Aggregating DataModule OverviewIn addition to row-at-a-time queries, you may need to summarize data in order to analyze it. Microsoft®<strong>SQL</strong> Server® provides a number of built-in functions that can aggregate, or summarize, informationacross multiple rows. In this module, you will learn how to use aggregate functions. You will also learnhow to use the GROUP BY and HAVING clauses to break up the data into groups for summarizing and tofilter the resulting groups.ObjectivesAfter completing this module, you will be able to:• Write queries that summarize data using built-in aggregate functions.• Use the GROUP BY clause to arrange rows into groups.• Use the HAVING clause to filter out groups based on a search condition.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-3Lesson 1Using Aggregate FunctionsIn this lesson, you will learn how to use built-in functions to aggregate, or summarize, data in multiplerows. <strong>SQL</strong> Server provides functions such as SUM, MAX, and AVG to perform calculations that takemultiple values and return a single result.Lesson ObjectivesAfter completing this lesson, you will be able to:• List the built-in aggregate functions provided by <strong>SQL</strong> Server.• Write queries that use aggregate functions in a SELECT list to summarize all the rows in an input set.• Describe the use of the DISTINCT option in aggregate functions.• Write queries using aggregate functions that handle the presence of NULLs in source data.


9-4 Grouping and Aggregating DataWorking with Aggregate FunctionsSo far in this course, you have learned how to operate on a row at a time, using a WHERE clause to filterrows, adding computed columns to a SELECT list, and processing across columns but within each row.You may also have a need to perform analysis across rows, such as counting rows that meet your criteriaor summarizing total sales for all orders. In order to accomplish this, you will use aggregate functionscapable of operating on multiple rows at once.There are many aggregate functions provided in <strong>SQL</strong> Server <strong>2012</strong>. In this course, you will learn aboutcommon functions such as SUM, MIN, MAX, AVG, and COUNT.When working with aggregate functions, there are some considerations to keep in mind:• Aggregate functions return a single (scalar) value and can be used in SELECT statements where asingle expression is used, such as SELECT, HAVING, and ORDER BY clauses.• Aggregate functions ignore NULLs, except when using COUNT(*). You will learn more about this laterin this lesson.• Aggregate functions in a SELECT list do not generate a column alias. You may wish to use the ASclause to provide one.• Aggregate functions in a SELECT clause operate on all rows passed to the SELECT phase. If there is noGROUP BY clause, all rows will be summarized, as in the slide above. You will learn more aboutGROUP BY in the next lesson.• To extend beyond the built-in functions, <strong>SQL</strong> Server provides a mechanism for user-definedaggregate functions via the .NET Common Language Runtime (CLR). See Microsoft course 10776:Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases for more information on .NET CLR functionality.For More Information For more information on other built-in aggregate functions, seeBooks Online at http://go.microsoft.com/fwlink/?LinkId=242925.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-5Built-In Aggregate Functions<strong>SQL</strong> Server provides many built-in aggregate functions. Commonly used functions include:Function Name Syntax DescriptionSUM SUM() Totals all the non-NULL numeric values in a column.AVG AVG() Averages all the non-NULL numeric values in a column(sum/count).MIN MIN() Returns the smallest number, earliest date/time, or firstoccurringstring (according to sort rules in collation).MAX MAX() Returns the largest number, latest date/time, or lastoccurringstring (according to sort rules in collation).COUNT orCOUNT_BIGCOUNT(*) orCOUNT()With (*), counts all rows, including those with NULL.When a column is specified as , returnscount of non-NULL rows for the column. COUNT returnsan int; COUNT_BIG returns a big_int.Note This lesson will only cover common aggregate functions. For more information onother built-in aggregate functions, see Books Online athttp://go.microsoft.com/fwlink/?LinkId=242925.


9-6 Grouping and Aggregating DataTo use a built-in aggregate in a SELECT clause, consider the following example in the T<strong>SQL</strong><strong>2012</strong> sampledatabase:SELECT AVG(unitprice) AS avg_price,MIN(qty)AS min_qty,MAX(discount) AS max_discountFROM Sales.OrderDetails;Note that the above example does not use a GROUP BY clause. Therefore, all rows from theSales.OrderDetails table will be summarized by the aggregate formulas in the SELECT clause.The results:avg_price min_qty max_discount--------- ------- ------------26.2185 1 0.250When using aggregates in a SELECT clause, all columns referenced in the SELECT list must be used asinputs for an aggregate function, or be referenced in a GROUP BY clause. The following example willreturn an error:SELECT orderid, AVG(unitprice) AS avg_price, MIN(qty)AS min_qty, MAX(discount) ASmax_discountFROM Sales.OrderDetails;This returns:Msg 8120, Level 16, State 1, Line 1Column 'Sales.OrderDetails.orderid' is invalid in the select list because it is notcontained in either an aggregate function or the GROUP BY clause.Since our example is not using a GROUP BY clause, the query treats all rows as a single group. Allcolumns, therefore, must be used as inputs to aggregate functions. Removing orderid from the previousexample will prevent the error.In addition to numeric data such as the price and quantities in the previous example, aggregateexpressions can also summarize date, time, and character data. The following examples show the use ofaggregates with dates and characters. This query returns first and last company by name, using MIN andMAX:SELECT MIN(companyname) AS first_customer, MAX(companyname) AS last_customerFROM Sales.Customers;Returns:first_customer last_customer-------------- --------------Customer AHPOP Customer ZRNDEThis query returns the earliest and latest orders by order date, using MIN and MAX:SELECT MIN(orderdate)AS earliest,MAX(orderdate) AS latestFROM Sales.Orders;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-7Returns:earliestlatest----------------------- -----------------------2006-07-04 00:00:00.000 2008-05-06 00:00:00.000Other functions may coexist with aggregate functions. For example, the YEAR scalar function is used in thefollowing example to return only the year portion of the order date, before MIN and MAX are evaluated:SELECT MIN(YEAR(orderdate))AS earliest, MAX(YEAR(orderdate)) AS latestFROM Sales.Orders;Returns:earliest latest-------- -------2006 2008


9-8 Grouping and Aggregating DataUsing DISTINCT with Aggregate FunctionsEarlier in this course, you learned about the use of DISTINCT in a SELECT clause to remove duplicate rows.When used with an aggregate function, DISTINCT removes duplicate values from the input columnbefore computing the summary value. This is useful when you wish to summarize unique occurrences ofvalues, such as customers in the T<strong>SQL</strong><strong>2012</strong> orders table.The following example returns customers that have placed orders, grouped by employee id and year:SELECT empid, YEAR(orderdate) AS orderyear,COUNT(custid) AS all_custs,COUNT(DISTINCT custid) AS unique_custsFROM Sales.OrdersGROUP BY empid, YEAR(orderdate);Note that the above example uses a GROUP BY clause. GROUP BY will be covered in the next lesson. It isused here in order to provide a useful example for comparing DISTINCT and non-DISTINCT aggregatefunctions.This returns, in part:empid orderyear all_custs unique_custs--------------- --------- ------------1 2006 26 221 2007 55 401 2008 42 322 2006 16 152 2007 41 352 2008 39 343 2006 18 163 2007 71 463 2008 38 30


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-9Note the difference in each row between the COUNT of custid (in column 3) and the DISTINCT COUNT incolumn 4. Column 3 simply returns all rows except those containing NULL. Column 4 excludes duplicatecustids (repeat customers) and returns a count of unique customers, answering the question: “How manycustomers per employee?”Question: Could you accomplish the same output with the use of SELECT DISTINCT?


9-10 Grouping and Aggregating DataUsing Aggregate Functions with NULLAs you have learned in this course, it is important to be aware of the possible presence of NULLs in yourdata, and of how NULL interacts with T-<strong>SQL</strong> query components. This is also true with aggregateexpressions. There are a few considerations to be aware of:• With the exception of COUNT used with the (*) option, T-<strong>SQL</strong> aggregate functions ignore NULLs. Thismeans, for example, that a SUM function will add only non-NULL values. NULLS do not evaluate tozero.• The presence of NULLs in a column may lead to inaccurate computations for AVG, which will sumonly populated rows and divide that sum by the number of non-NULL rows. There may be adifference in results between AVG() and (SUM()/COUNT(*)).For example, given the following table named t1:C1C21 NULL2 103 204 305 406 50


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-11The following query illustrates the difference between how AVG handles NULL and how you mightcalculate an average yourself with a SUM/COUNT(*) computed column:SELECT SUM(c2) AS sum_nonnulls,COUNT(*)AS count_all_rows,COUNT(c2)AS count_nonnulls,AVG(c2) AS [avg],(SUM(c2)/COUNT(*))AS arith_avgFROM t1;The result:sum_nonnulls count_all_rows count_nonnulls avg arith_avg------------ -------------- -------------- --- ---------150 6 5 30 25If you need to summarize all rows, whether NULL or not, consider replacing the NULLs with another valuethat can be used by your aggregate function.The following example replaces NULLs with 0 before calculating an average. The table named t2 containsthe following rows:c1c2----------- -----------1 12 103 14 NULL5 16 107 18 NULL9 110 1011 112 10Compare the effect on the arithmetic mean with NULLs ignored verses replaced with 0:SELECT AVG(c2) AS AvgWithNULLs, AVG(COALESCE(c2,0)) AS AvgWithNULLReplaceFROM dbo.t2;This returns the following results, with a warning message:AvgWithNULLs AvgWithNULLReplace------------ ------------------4 3Warning: Null value is eliminated by an aggregate or other SET operation.Note This example cannot be executed against the sample database used in this course. Ascript to create the table is included in the upcoming demonstration.


9-12 Grouping and Aggregating DataDemonstration: Using Aggregate FunctionsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_09_PRJ\10774A_09_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-13Lesson 2Using the GROUP BY ClauseWhile aggregate functions are useful for analysis, you may wish to arrange your data into subsets beforesummarizing it. In this lesson, you will learn how to accomplish this using the GROUP BY clause.Lesson ObjectivesAfter completing this lesson, you will be able to:• Write queries that separate rows into groups using the GROUP BY clause.• Describe the role of the GROUP BY clause in the logical order of operations for processing a SELECTstatement.• Write SELECT clauses that reflect the output of a GROUP BY clause.• Use GROUP BY with aggregate functions.


9-14 Grouping and Aggregating DataUsing the GROUP BY ClauseAs you have learned, when your SELECT statement is processed, after the FROM clause and WHERE clause(if present) have been evaluated, a virtual table has been created. The contents of the virtual table arenow available for further processing. The GROUP BY clause allows you to subdivide the results of thepreceding query phases into groups of rows. To group rows, specify one or more elements in the GROUPBY clause:GROUP BY [, , ...]GROUP BY creates groups and places rows into each group as determined by unique combinations of theelements specified in the clause. For example, the following snippet of a query will result in a set ofgrouped rows, one per empid, in the Sales.Orders table:FROM Sales.OrdersGROUP BY empid;Once the GROUP BY clause has been processed and rows have been associated with a group, subsequentphases of the query must aggregate any elements of the source rows that do not appear in the GROUP BYlist. This will have an impact on how you write your SELECT and HAVING clauses.In order to see into the results of the GROUP BY clause, you will need to add a SELECT clause. This showsthe original 830 source rows being grouped into 9 groups based on the unique employee ID:SELECT empid, COUNT(*) AS cntFROM Sales.OrdersGROUP BY empid;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-15The result:empid cnt----- -----1 1232 963 1274 1565 426 677 728 1049 43(9 row(s) affected)For More Information To learn more about GROUP BY, see “GROUP BY (Transact <strong>SQL</strong>)”in Books Online at http://go.microsoft.com/fwlink/?LinkId=242926.


9-16 Grouping and Aggregating DataGROUP BY and the Logical Order of OperationsA common obstacle to becoming comfortable with using GROUP BY in SELECT statements isunderstanding why the following type of error message occurs:Msg 8120, Level 16, State 1, Line 2Column is invalid in the select list because it is not contained in eitheran aggregate function or the GROUP BY clause.A review of the logical order of operations during query processing will help clarify this issue.If you recall from earlier in the course, the SELECT clause is not processed until after the FROM, WHERE,GROUP BY, and HAVING clauses are processed if present. When discussing the use of GROUP BY, it isimportant to remember that not only does GROUP BY precede SELECT, but GROUP BY also replaces theresults of the FROM and WHERE clauses with its own results. The final outcome of the query will onlyreturn one row per qualifying group (if a HAVING clause is present). Therefore, any operations performedafter GROUP BY, including SELECT, HAVING, and ORDER BY, are performed on the groups, not theoriginal detail rows. Columns in the SELECT list, for example, must return a scalar value per group. Thismay include the column(s) being grouped on or aggregate functions being performed on each group.The following query is permitted because each column in the SELECT list is either a column in the GROUPBY clause or is an aggregate function operating on each group:SELECT empid, COUNT(*) AS cntFROM Sales.OrdersGROUP BY empid;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-17This returns:empid count----- -----1 1232 963 1274 1565 426 677 728 1049 43The following query will return an error since orderdate is not an input to GROUP BY, and its data hasbeen "lost" following the FROM clause:SELECT empid, orderdate, COUNT(*) AS cntFROM Sales.OrdersGROUP BY empid;This returns:Msg 8120, Level 16, State 1, Line 1Column 'Sales.Orders.orderdate' is invalid in the select list because it is notcontained in either an aggregate function or the GROUP BY clause.If you did want to see orders per employee ID and per order date, add it to the GROUP BY clause, asfollows:SELECT empid, YEAR(orderdate) AS orderyear, COUNT(*) AS cntFROM Sales.OrdersGROUP BY empid, YEAR(orderdate)ORDER BY empid, YEAR(orderdate);This returns (in part):empid orderyear count----- --------- -----1 2006 261 2007 551 2008 422 2006 162 2007 41The net effect of this behavior is that you will not be able to combine a view of summary data with thedetailed source date with the T-<strong>SQL</strong> tools you have learned so far. You will learn some approaches tosolving this problem later in this course.For More Information For additional information about troubleshooting GROUP BYerrors, go to http://go.microsoft.com/fwlink/?LinkId=242927.


9-18 Grouping and Aggregating DataGROUP BY WorkflowThe source queries to build the demonstration on the slide follow and are included with thedemonstration file for this lesson:SELECT orderid, empid, custidFROM Sales.Orders;SELECT orderid, empid, custidFROM Sales.OrdersWHERE CUSTID 3;SELECT empid, COUNT(*)FROM Sales.OrdersWHERE CUSTID 3GROUP BY empid;.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-19Using GROUP BY with Aggregate FunctionsAs you have heard, if you use a GROUP BY clause in a T-<strong>SQL</strong> query, all columns listed in the SELECT clausemust either be used in the GROUP BY clause itself or be inputs to aggregate functions operating on eachgroup.You have seen the use of the COUNT function in conjunction with GROUP BY queries. Other aggregatefunctions may be used as well, as in the following example, which uses MAX to return the largest quantityordered per product:SELECT productid, MAX(qty) AS largest_orderFROM Sales.OrderDetailsGROUP BY productid;This returns (in part):productid largest_order----------- -------------23 7046 6069 6529 8075 120Note The qty column, used as an input to the MAX function, is not used in the GROUP BYclause. This illustrates that even though the detail rows returned by the FROM...WHEREphase are lost to the GROUP BY phase, the source columns are still available foraggregation.


9-20 Grouping and Aggregating DataDemonstration: Using GROUP BYDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_09_PRJ\10774A_09_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer..3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-21Lesson 3Filtering Groups with HAVINGOnce you have created groups with a GROUP BY clause, you may wish to further filter the results. TheHAVING clause acts as a filter on groups, much like the WHERE clause acts as a filter on rows returned bythe FROM clause. In this lesson, you will learn how to write a HAVING clause and understand thedifferences between HAVING and WHERE.Lesson ObjectivesAfter completing this lesson, you will be able to:• Write queries that use the HAVING clause to filter groups.• Compare HAVING to WHERE.• Choose the appropriate filter for a scenario: WHERE or HAVING.


9-22 Grouping and Aggregating DataFiltering Grouped Data Using the HAVING ClauseIf a WHERE clause and a GROUP BY clause are present in a T-<strong>SQL</strong> SELECT statement, the HAVING clause isthe fourth phase of logical query processing:Logical Order Phase Comments5 SELECT1 FROM2 WHERE Operates on rows3 GROUP BY Creates groups4 HAVING Operates on groups6 ORDER BYA HAVING clause allows you to create a search condition, conceptually similar to the predicate of aWHERE clause, which will then test each group returned by the GROUP BY clause.The following example from the T<strong>SQL</strong><strong>2012</strong> database groups all orders by customer, then returns onlythose customers that have placed orders. No HAVING clause has been added; therefore, no filter isapplied to the groups:SELECT custid, COUNT(*) AS count_ordersFROM Sales.OrdersGROUP BY custid;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-23Returns the groups, with the following message:(89 row(s) affected)The following example adds a HAVING clause to the previous query. It groups all orders by customer,then returns only those customers that have placed 10 or more orders. Groups containing customers thatplaced fewer than 10 rows are discarded:SELECT custid, COUNT(*) AS count_ordersFROM Sales.OrdersGROUP BY custidHAVING COUNT(*) >= 10;Returns the groups, with the following message:(28 row(s) affected)Note Remember that HAVING is processed before the SELECT clause, so any columnaliases created in a SELECT clause are not available to the HAVING clause.For More Information See “HAVING (Transact-<strong>SQL</strong>)” in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242933.


9-24 Grouping and Aggregating DataCompare HAVING to WHEREWhile both HAVING and WHERE clauses filter data, it is important to remember that WHERE operates onrows returned by the FROM clause. If a GROUP BY...HAVING section exists in your query following aWHERE clause, the WHERE clause will filter rows before GROUP BY is processed, potentially limiting thegroups that can be created.A HAVING clause is processed after GROUP BY and only operates on groups, not detail rows. Tosummarize:• A WHERE clause controls which rows are available to the next phase of the query.• A HAVING clause controls which groups are available to the next phase of the query.Note WHERE and HAVING clauses are not mutually exclusive!You will see a comparison of using WHERE and HAVING in the next demonstration.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-25Demonstration: Filtering Groups with HAVINGDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_09_PRJ\10774A_09_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 31 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


9-26 Grouping and Aggregating DataLab: Grouping and Aggregating DataLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. In the Virtual Machines list, if the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-277. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type depending on the type of Microsoft <strong>SQL</strong> version (ask your instructorfor a current list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You have been provided with a set of business requirements for data and youwill write T-<strong>SQL</strong> queries to retrieve the specified data from the databases. You will need to performcalculations upon groups of data and filter according to the results.Important When comparing your results with the provided sample outputs, the columnordering and total number of affected rows should always match. However, remember thatthe order of the rows in the output of a query without an ORDER BY clause is notguaranteed. Therefore, the order of the rows in the sample outputs may be different thanyours. Also, the answer outputs include abbreviated results.


9-28 Grouping and Aggregating DataExercise 1: Writing Queries That Use the GROUP BY ClauseScenarioThe sales department would like to create additional up-sell opportunities from existing customers. Thestaff needs to analyze different groups of customers and product categories, depending on severalbusiness rules. Based on these rules, you will write the SELECT statements to retrieve the needed rowsfrom the Sales.Customers table.The main tasks for this exercise are as follows:1. Write a SELECT statement to retrieve different groups of customers for the specific sales employee.2. Write a SELECT statement to retrieve groups of customers for the specific order year.3. Write a SELECT statement to retrieve the sales category groups for the specific year. Task 1: Write a SELECT statement to retrieve different groups of customers• Open the project file F:\10774A_Labs\10774A_09_PRJ\10774A_09_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement that will return groups of customers that made a purchase. The SELECTclause should include the custid column from the Sales.Orders table and the contactname columnfrom the Sales.Customers table. Group by both columns and filter only the orders from the salesemployee whose empid equals five.• Execute the written statement and compare the results that you got with the desired results shown inthe file 52 - Lab Exercise 1 - Task 1 Result.txt. Task 2: Add an additional column from the Sales.Customers table• Copy the T-<strong>SQL</strong> statement in task 1 and modify it to include the city column from theSales.Customers table in the SELECT clause.• Execute the query.• You will get an error. What is the error message? Why?• Correct the query so that it will execute properly.• Execute the query and compare the results that you got with the desired results shown in the file53 - Lab Exercise 1 - Task 2 Result.txt. Task 3: Write a SELECT statement to retrieve the customers with orders for each year• Write a SELECT statement that will return groups of rows based on the custid column and a calculatedcolumn orderyear representing the order year based on the orderdate column from the Sales.Orderstable. Filter the results to include only the orders from the sales employee whose empid equals five.• Execute the written statement and compare the results that you got with the desired results shown inthe file 54 - Lab Exercise 1 - Task 3 Result.txt.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-29 Task 4: Write a SELECT statement to retrieve groups of product categories sold in aspecific year• Write a SELECT statement to retrieve groups of rows based on the categoryname column in theProduction.Categories table. Filter the results to include only the product categories that wereordered in the year 2008.• Execute the written statement and compare the results that you got with the desired results shown inthe file 55 - Lab Exercise 1 - Task 4 Result.txt.Results: After this exercise, you should be able to use the GROUP BY clause in the T-<strong>SQL</strong> statement.


9-30 Grouping and Aggregating DataExercise 2: Writing Queries That Use Aggregate FunctionsScenarioThe marketing department would like to launch a new campaign, so the staff needs to gain a betterinsight into the existing customers’ buying behavior. You will have to create different sales reports basedon the total and average sales amount per year and per customer.The main tasks for this exercise are as follows:1. Write a SELECT statement to retrieve the total sales amount per order.2. Write a SELECT statement to retrieve additional information about the order lines.3. Write a SELECT statement to analyze all customers’ buying behavior. Task 1: Write a SELECT statement to retrieve the total sales amount per order• Open the project file F:\10774A_Labs\10774A_09_PRJ\10774A_09_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the orderid column from the Sales.Orders table and the totalsales amount per orderid. (Hint: Multiply the qty and unitprice columns from the Sales.OrderDetailstable.) Use the alias salesamount for the calculated column. Sort the result by the total sales amountin descending order.• Execute the written statement and compare the results that you got with the desired results shown inthe file 62 - Lab Exercise 2 - Task 1 Result.txt. Task 2: Add additional columns• Copy the T-<strong>SQL</strong> statement in task 1 and modify it to include the total number of order lines for eachorder and the average order line sales amount value within the order. Use the aliases nooforderlinesand avgsalesamountperorderline, respectively.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 63 - Lab Exercise 2 - Task 2 Result.txt. Task 3: Write a SELECT statement to retrieve the sales amount value per month• Write a select statement to retrieve the total sales amount for each month. The SELECT clause shouldinclude a calculated column named yearmonthno (YYYYMM notation) based on the orderdatecolumn in the Sales.Orders table and a total sales amount (multiply the qty and unitprice columnsfrom the Sales.OrderDetails table). Order the result by the yearmonthno calculated column.• Execute the written statement and compare the results that you got with the recommended resultshown in the file 64 - Lab Exercise 2 - Task 3 Result.txt.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-31 Task 4: Write a SELECT statement to list all customers with the total sales amountand number of order lines added• Write a select statement to retrieve all the customers (including those that did not place any orders)and their total sales amount, maximum sales amount per order line, and number of order lines.• The SELECT clause should include the custid and contactname columns from the Sales.Customerstable and four calculated columns based on appropriate aggregate functions:• totalsalesamount, representing the total sales amount per order• maxsalesamountperorderline, representing the maximum sales amount per order line• numberofrows, representing the number of rows (use * in the COUNT function)• numberoforderlines, representing the number of order lines (use the orderid column in theCOUNT function)• Order the result by the totalsalesamount column.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 65 - Lab Exercise 2 - Task 4 Result.txt.• Notice that the custid 22 and 57 rows have a NULL in the columns with the SUM and MAX aggregatefunctions. What are their values in the COUNT columns? Why are they different?Results: After this exercise, you should know how to use aggregate functions.


9-32 Grouping and Aggregating DataExercise 3: Writing Queries That Use Distinct Aggregate FunctionsScenarioThe marketing department would like to have some additional reports that display the number ofcustomers that made any order in the specific period of time and the number of customers based on thefirst letter in the contact name.The main tasks for this exercise are as follows:1. Modify a SELECT statement to display the number of distinct customers for each order year.2. Write a SELECT statement to retrieve the number of customers based on first letter of the contactname.3. Write a SELECT statement to retrieve additional sales statistics. Task 1: Modify a SELECT statement to retrieve the number of customers• Open the project file F:\10774A_Labs\10774A_09_PRJ\10774A_09_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• A junior analyst prepared a T-<strong>SQL</strong> statement to retrieve the number of orders and the number ofcustomers for each order year. Observe the provided T-<strong>SQL</strong> statement and execute it:SELECTYEAR(orderdate) AS orderyear,COUNT(orderid) AS nooforders,COUNT(custid) AS noofcustomersFROM Sales.OrdersGROUP BY YEAR(orderdate);• Observe the results. Notice that the number of orders is the same as the number of customers. Why?• Correct the T-<strong>SQL</strong> statement to show the correct number of customers that placed an order for eachyear.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 72 - Lab Exercise 3 - Task 1 Result.txt. Task 2: Write a SELECT statement to analyze segments of customers• Write a SELECT statement to retrieve the number of customers based on the first letter of the valuesin the contactname column from the Sales.Customers table. Add an additional column to show thetotal number of orders placed by each group of customers. Use the aliases firstletter, noofcustomersand nooforders. Order the result by the firstletter column.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 73 - Lab Exercise 3 - Task 2 Result.txt.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-33 Task 3: Write a SELECT statement to retrieve additional sales statistics• Copy the T-<strong>SQL</strong> statement in exercise 1, task 4, and modify to include the following informationabout for each product category: total sales amount, number of orders, and average sales amount perorder. Use the aliases totalsalesamount, nooforders, and avgsalesamountperorder, respectively.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 74 - Lab Exercise 3 - Task 3 Result.txt.Results: After this exercise, you should have an understanding of how to apply a DISTINCT aggregatefunction.


9-34 Grouping and Aggregating DataExercise 4: Writing Queries That Filter Groups with the HAVING ClauseScenarioThe sales and marketing departments were satisfied with the reports you provided to analyze customers’behavior. Now they would like to have the results filtered based on the total sales amount and number oforders. So, in the last exercise, you will learn how to filter the result based on aggregated functions andlearn when to use the WHERE and HAVING clauses.The main tasks for this exercise are as follows:1. Write a SELECT statement to retrieve the top 10 customers that spent more than$10,000.2. Write a SELECT statement to retrieve specific orders based on different predicate logic.3. Write a SELECT statement to retrieve all customers that placed a specific number of orders and thelast order date. Task 1: Write a SELECT statement to retrieve the top 10 customers• Open the project file F:\10774A_Labs\10774A_09_PRJ\10774A_09_PRJ.ssmssln and the T-<strong>SQL</strong> script81 - Lab Exercise 4.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the top 10 customers by total sales amount that spent morethan $10,000 in terms of sales amount. Display the custid column from the Orders table and acalculated column that contains the total sales amount based on the qty and unitprice columnsfrom the Sales.OrderDetails table. Use the alias totalsalesamount for the calculated column.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 82 - Lab Exercise 4 - Task 1 Result.txt. Task 2: Write a SELECT statement to retrieve specific orders• Write a SELECT statement against the Sales.Orders and Sales.OrderDetails tables and display theempid column and a calculated column representing the total sales amount. Filter the results togroup only the rows with an order year 2008.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 83 - Lab Exercise 4 - Task 2 Result.txt. Task 3: Apply additional filtering• Copy the T-<strong>SQL</strong> statement in task 2 and modify it to apply an additional filter to retrieve only therows that have a sales amount higher than $10,000.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 84 - Lab Exercise 4 - Task 3_1 Result.txt.• Apply an additional filter to show only employees with empid equal number 3.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 85 - Lab Exercise 4 - Task 3_2 Result.txt.• Did you apply the predicate logic in the WHERE clause or the HAVING clause? Which do you think isbetter? Why?


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 9-35 Task 4: Retrieve the customers with more than 25 orders• Write a SELECT statement to retrieve all customers who placed more than 25 orders and addinformation about the date of the last order and the total sales amount. Display the custid columnfrom the Sales.Orders table and two calculated columns: lastorderdate based on the orderdatecolumn and totalsalesamount based on the qty and unitprice columns in the Sales.OrderDetails table.• Execute the written statement and compare the results that you got with the recommended resultshown in the file 86 - Lab Exercise 4 - Task 4 Result.txt.Results: After this exercise, you should have an understanding of how to use the HAVING clause.


9-36 Grouping and Aggregating DataModule ReviewReview Questions1. What is the difference between the COUNT function and the COUNT_BIG function?2. Can a GROUP BY clause include more than one column?3. Can a WHERE clause and a HAVING clause in a query filter on the same column?


10-1Module 10Using SubqueriesContents:Lesson 1: Writing Self-Contained Subqueries 10-3Lesson 2: Writing Correlated Subqueries 10-10Lesson 3: Using the EXISTS Predicate with Subqueries 10-15Lab: Using Subqueries 10-20


10-2 Using SubqueriesModule OverviewAt this point in this course, you have learned many aspects of the T-<strong>SQL</strong> SELECT statement, but eachquery that you have written has been a single self-contained statement. <strong>SQL</strong> Server also provides theability to nest one query within another—in other words, to form subqueries. In a subquery, the results ofthe inner query (subquery) are returned to the outer query. This can provide a great deal of flexibility foryour query logic. In this module, you will learn to write several types of subqueries.ObjectivesAfter completing this module, you will be able to:• Describe the uses for queries that are nested within other queries.• Write self-contained subqueries that return scalar or multi-valued results.• Write correlated subqueries that return scalar or multi-valued results.• Use the EXISTS predicate to efficiently check for the existence of rows in a subquery.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-3Lesson 1Writing Self-Contained SubqueriesA subquery is a SELECT statement nested within another query. Being able to nest one query withinanother will enhance your ability to create effective queries in T-<strong>SQL</strong>. In this lesson, you will learn how towrite self-contained queries, which are evaluated once and provide their results to the outer query. Youwill learn how to write scalar subqueries, which return a single value, and multi-valued subqueries, whichas their name implies can return a list of values to the outer query.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe where subqueries may be used in a SELECT statement.• Write queries that use scalar subqueries in the WHERE clause of a SELECT statement.• Write queries that use multi-valued subqueries in the WHERE clause of a SELECT statement.


10-4 Using SubqueriesWorking with SubqueriesA subquery is a SELECT statement nested, or embedded, within another query. The nested query, which isthe subquery, is the inner query. The query that contains the nested query is the outer query.The purpose of a subquery is to return results to the outer query. The form of the results will determinewhether the subquery is a scalar subquery or a multi-valued subquery:• Scalar subqueries, like scalar functions, return a single value. Outer queries need to be written toprocess a single result.• Multi-valued subqueries return a result much like a single-column table. Outer queries need to bewritten to handle multiple possible results.In addition to the choice between scalar and multi-valued subqueries, you may choose to writesubqueries that are self-contained or subqueries that are correlated with the outer query:• Self-contained subqueries can be written as standalone queries, with no dependencies on the outerquery. A self-contained subquery is processed once when the outer query runs and passes its resultsto the outer query.• Correlated subqueries reference one or more columns from the outer query and therefore depend onthe outer query. Correlated subqueries cannot be run separately from the outer query.Note You will learn about correlated subqueries in a later lesson in this module.For More Information Additional reading about subqueries can be found in BooksOnline at http://go.microsoft.com/fwlink/?LinkId=242934.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-5Writing Scalar SubqueriesA scalar subquery is an inner SELECT statement within an outer query, written to return a single value.Scalar subqueries may be used anywhere in an outer T-<strong>SQL</strong> statement where a single-valued expression ispermitted, such as in a SELECT clause, a WHERE clause, a HAVING clause, or even a FROM clause.To write a scalar subquery, consider the following guidelines:• To denote a query as a subquery, enclose it in parentheses.• Multiple levels of subqueries are supported in <strong>SQL</strong> Server. In this lesson, we will only consider twolevelqueries (one inner query within one outer query), but up to 32 levels are supported.• If the subquery returns an empty set, the result of the subquery is converted and returned as a NULL.Ensure your outer query can gracefully handle a NULL in addition to other expected results.To build the example query provided on the slide above, you may wish to start by writing and testing theinner query alone:USE T<strong>SQL</strong><strong>2012</strong>;GOSELECT MAX(orderid) AS lastorderFROM Sales.Orders;This returns:lastorder---------11077


10-6 Using SubqueriesThen you will write the outer query, using the value returned by the inner query. In this example, you willreturn details about the most recent order:SELECT orderid, productid, unitprice, qtyFROM Sales.OrderDetailsWHERE orderid =(SELECT MAX(orderid) AS lastorderFROM Sales.Orders);This returns (partial result):orderid productid unitprice qty----------- ----------- --------------------- ------11077 2 19.00 2411077 3 10.00 411077 4 22.00 111077 6 25.00 1Test the logic of your subquery to ensure it will only return a single value. In the query above, since theouter query used an = operator in the predicate of the WHERE clause, an error would have been returnedif the inner query returned more than one result. If the outer query is written to expect a single value,such as through the use of simple equality operators (=, , , etc.), an error will be returned:Msg 512, Level 16, State 1, Line 1Subquery returned more than 1 value. This is not permitted when the subquery follows =,!=, = or when the subquery is used as an expression.In the case of the Sales.Orders table, orderid is known to be a unique column, enforced in the structure ofthe table by a PRIMARY KEY constraint.For More Information See "PRIMARY KEY Constraints" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=209411.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-7Writing Multi-Valued SubqueriesAs its name suggests, a multi-valued subquery may return more than one result, in the form of asingle-column set. A multi-valued subquery is well-suited to return results to the IN predicate, as in thefollowing example:SELECT custid, orderidFROM Sales.ordersWHERE custid IN (SELECT custidFROM Sales.CustomersWHERE country =N'Mexico');In this example, if you were to execute only the inner query, you would return the following list of custidsfor customers in the country of Mexico:custid------23135880<strong>SQL</strong> Server will pass those results to the outer query, logically rewritten as follows:SELECT custid, orderidFROM Sales.ordersWHERE custid IN (2,3,13,58,80);


10-8 Using SubqueriesThe outer query will continue to process the SELECT statement, with the following partial results:custid orderid------ -----------2 103082 106253 103653 105073 1085613 1025958 1032258 10354As you continue to learn about writing T-<strong>SQL</strong> queries, you may find scenarios in which multi-valuedsubqueries are written as SELECT statements using JOINs. For example, the previous subquery might berewritten as follows, with the same results and comparable performance:SELECT c.custid, o.orderidFROM Sales.Customers AS c JOIN Sales.Orders AS oON c.custid = o.custidWHERE c.country = N'Mexico‘;Note In some cases, the database engine will interpret a subquery as a JOIN and executeit accordingly. As you learn more about <strong>SQL</strong> Server internals, such as execution plans, youmay be able to see your queries interpreted this way. See Microsoft Course 10776:Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases for more information about executionplans and query performance.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-9Demonstration: Writing Self-Contained SubqueriesDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_10_PRJ\10774A_10_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10-10 Using SubqueriesLesson 2Writing Correlated SubqueriesEarlier in this module, you learned how to write self-contained subqueries, in which the inner query isindependent of the outer query, executes once, and returns its results to the outer query. Microsoft®<strong>SQL</strong> Server® also supports correlated subqueries, in which the inner query receives input from the outerquery and conceptually executes once per row in the outer query. In this lesson, you will learn how towrite correlated subqueries, as well as rewrite some types of correlated subqueries as JOINs forperformance or logical efficiency.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe how correlated subqueries are processed.• Write queries that use correlated subqueries in a SELECT statement.• Rewrite some correlated subqueries as JOINs.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-11Working with Correlated SubqueriesLike self-contained subqueries, correlated subqueries are SELECT statements nested within an outer query.They may also be written as scalar or as multi-valued subqueries. They are typically used to pass a valuefrom the outer query to the inner query, to be used as a parameter there.However, unlike self-contained subqueries, correlated subqueries depend on the outer query to passvalues into the subquery as a parameter. This leads to some special considerations when planningtheir use:• Correlated subqueries cannot be executed separately from the outer query. This complicates testingand debugging.• Unlike self-contained subqueries which are processed once, correlated subqueries will run multipletimes. Logically, the outer query runs first, and for each row returned by the outer query, the innerquery is processed.The following example uses a correlated subquery to return the orders with the latest order date for eachemployee. The subquery accepts an input value from the outer query, uses the input in its WHERE clause,and returns a scalar result to the outer query. (Line numbers have been added for use in the subsequentexplanation. They do not indicate the order in which the steps are logically processed.)1. SELECT orderid, empid, orderdate2. FROM Sales.Orders AS O13. WHERE orderdate =4. (SELECT MAX(orderdate)5. FROM Sales.Orders AS O26. WHERE O2.empid = O1.empid)7. ORDER BY empid, orderdate;


10-12 Using SubqueriesLet's examine this query and trace the role of each clause:Line No. Statement Description1 SELECT orderid, empid, orderdate Columns returned by the outer query.2 FROM Sales.Orders AS O1 Source table for the outer query. Note the alias.3 WHERE orderdate = Predicate used to evaluate the outer rows against theresult of the inner query.4 (SELECT MAX(orderdate) Column returned by the inner query. Aggregatefunction returns a scalar value.5 FROM Sales.Orders AS O2 Source table for the inner query. Note the alias.6 WHERE O2.empid = O1.empid) Correlation of empid from the outer query to empidfrom the inner query. This value will be supplied foreach row in the outer query.7 ORDER BY empid, orderdate; Sorts the results of the outer query.The query returns the following results. Note that some employees appear more than once, since they areassociated with multiple orders on the latest orderdate.orderid empid orderdate----- ----- -----------------------11077 1 2008-05-06 00:00:00.00011073 2 2008-05-05 00:00:00.00011070 2 2008-05-05 00:00:00.00011063 3 2008-04-30 00:00:00.00011076 4 2008-05-06 00:00:00.00011043 5 2008-04-22 00:00:00.00011045 6 2008-04-23 00:00:00.00011074 7 2008-05-06 00:00:00.00011075 8 2008-05-06 00:00:00.00011058 9 2008-04-29 00:00:00.000Question: Why can't a correlated subquery be executed separately from the outer query?


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-13Writing Correlated SubqueriesTo write correlated subquery subqueries, consider the following guidelines:• Write the outer query to accept the appropriate return result from the inner query. If the inner querywill be scalar, you can use equality and comparison operators, such as =, , and in the WHEREclause. If the inner query may return multiple values, use an IN predicate. Plan to handle NULL results.• Identify the column from the outer query that will be passed to the correlated subquery. Declare analias for the table that is the source of the column in the outer query.• Identify the column from the inner table that will be compared to the column from the outer table.Create an alias for the source table, as you did for the outer query.• Write the inner query to retrieve values from its source based on the input value from the outerquery. For example, use the outer column in the WHERE clause of the inner query.The correlation between the inner and outer queries occurs when the outer value is passed to the innerquery for comparison. It’s this correlation that gives the subquery its name.For More Information Additional reading about correlated subqueries can be found inBooks Online at http://go.microsoft.com/fwlink/?LinkId=242935.


10-14 Using SubqueriesDemonstration: Writing Correlated SubqueriesDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_10_PRJ\10774A_10_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-15Lesson 3Using the EXISTS Predicate with SubqueriesIn addition to retrieving values from a subquery, <strong>SQL</strong> Server provides a mechanism for checking whetherany results would be returned from a query. The EXISTS predicate evaluates whether rows exist, but ratherthan return them, it returns TRUE or FALSE. This is a useful technique for validating data without incurringthe overhead of retrieving and counting the results.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe how the EXISTS predicate combines with a subquery to perform an existence test.• Write queries that use EXISTS predicates in a WHERE clause to test for the existence ofqualifying rows.


10-16 Using SubqueriesWorking with EXISTSWhen a subquery is invoked by an outer query using the EXISTS predicate, <strong>SQL</strong> Server handles the resultsof the subquery differently than what you have seen so far in this module. Rather than retrieve a scalarvalue or a multi-valued list from the subquery, EXISTS simply checks to see if there are any rows in theresults.Conceptually, an EXISTS predicate is equivalent to retrieving the results, counting the rows returned, andcomparing the count to zero. Compare the following queries, which will return details about employeeswho are associated with orders.The first query uses COUNT in a subquery:SELECT empid, lastnamexFROM HR.Employees AS eWHERE (SELECT COUNT(*)FROM Sales.Orders AS OWHERE O.empid = e.empid)>0;The second query, which returns the same results, uses EXISTS:SELECT empid, lastnameFROM HR.Employees AS eWHERE EXISTS( SELECT *FROM Sales.Orders AS OWHERE O.empid = e.empid);In the first example, the subquery must count each occurrence of each empid found in the Sales.Orderstable, and compare the count results to zero, simply to indicate that the employee has associated orders.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-17In the second query, EXISTS returns TRUE for an empid as soon as one has been found in the Sales.Orderstable—a complete accounting of each occurrence is unnecessary.Note From the perspective of logical processing, the two query forms are equivalent.From a performance perspective, the database engine may treat the queries differently as itoptimizes them for execution. Consider testing each one for your own usage.Another useful application of EXISTS is negating it with NOT, as in the following example, which willreturn any customer that has never placed an order:SELECT custid, companynameFROM Sales.Customers AS cWHERE NOT EXISTS (SELECT *FROM Sales.Orders AS oWHERE c.custid=o.custid);Once again, <strong>SQL</strong> Server will not have to return data about the related orders for customers that haveplaced orders. If a customer ID is found in the Sales.Orders table, NOT EXISTS evaluates to FALSE and theevaluation quickly completes.


10-18 Using SubqueriesWriting Queries Using EXISTS with SubqueriesTo write queries that use EXISTS with subqueries, consider the following guidelines:• The keyword EXISTS directly follows WHERE. No column name (or other expression) needs to precedeit, unless NOT is also used.• Within the subquery following EXISTS, the SELECT list only needs to contain (*). No rows are returnedby the subquery, so no columns need to be specified.For More Information See "Subqueries with EXISTS" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242937.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-19Demonstration: Writing Subqueries Using EXISTSDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_10_PRJ\10774A_10_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 31 – Demonstration C.sql script file.4. Follow the instructions contained within the comments of the script file.


10-20 Using SubqueriesLab: Using SubqueriesLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log” onmessage appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-217. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You have been provided with a set of business requirements for data and youwill write T-<strong>SQL</strong> queries to retrieve the specified data from the databases. Due to the complexity of someof the requests, you will need to embed subqueries into your queries in order to return results in a singlequery.Important When comparing your results with the provided sample outputs, the columnordering and total number of affected rows should always match. However, remember thatthe order of the rows in the output of a query without an ORDER BY clause is notguaranteed. Therefore, the order of the rows in the sample outputs may be different thanyours. Also, the answer outputs include abbreviated results.


10-22 Using SubqueriesExercise 1: Writing Queries That Use Self-Contained SubqueriesScenarioThe sales department needs some advanced reports to analyze sales orders. You will write differentSELECT statements that use self-contained subqueries.The main tasks for this exercise are as follows:1. Write a couple of SELECT statements using a self-contained subquery in the WHERE clause.2. Observe the SELECT statement provided by the IT department.3. Write a SELECT statement to analyze each sales order against the monthly sales value. Task 1: Write a SELECT statement to retrieve the last order date• Open the project file F:\10774A_Labs\10774A_10_PRJ\10774A_10_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to return the maximum order date from the table Sales.Orders.• Execute the written statement and compare the results that you got with the desired results shown inthe file 52 - Lab Exercise 1 - Task 1 Result.txt. Task 2: Write a SELECT statement to retrieve all orders on the last order date• Write a SELECT statement to return the orderid, orderdate, empid, and custid columns from theSales.Orders table. Filter the results to include only orders where the date order equals the last orderdate. (Hint: Use the query in task 1 as a self-contained subquery.)• Execute the written statement and compare the results that you got with the desired results shown inthe file 53 - Lab Exercise 1 - Task 2 Result.txt. Task 3: Observe the T-<strong>SQL</strong> statement provided by the IT department• The IT department has written a T-<strong>SQL</strong> statement that retrieves the orders for all customers whosecontact name starts with a letter I:SELECTorderid, orderdate, empid, custidFROM Sales.OrdersWHEREcustid =(SELECT custidFROM Sales.CustomersWHERE contactname LIKE N'I%');• Execute the query and observe the result.• Modify the query to filter customers whose contact name starts with a letter B.• Execute the query. What happened? What is the error message? Why did the query fail?• Apply the needed changes to the T-<strong>SQL</strong> statement so that it will run without an error.• Execute the written statement and compare the results that you got with the desired results shown inthe file 54 - Lab Exercise 1 - Task 3 Result.txt.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-23 Task 4: Write a SELECT statement to analyze each order’s sales as a percentage of thetotal sales amount• Write a SELECT statement to retrieve the orderid column from the Sales.Orders table and thefollowing calculated columns:• totalsalesamount (based on the qty and unitprice columns in the Sales.OrderDetails table)• salespctoftotal (percentage of the total sales amount for each order divided by the total salesamount for all orders in a specific period)• Filter the results to include only orders placed in May 2008.• Execute the written statement and compare the results that you got with the desired results shown inthe file 55 - Lab Exercise 1 - Task 4 Result.txt.Results: After this exercise, you should be able to use self-contained subqueries in T-<strong>SQL</strong> statements.


10-24 Using SubqueriesExercise 2: Writing Queries That Use Scalar and Multi-Result SubqueriesScenarioThe marketing department would like to prepare materials for different groups of products and customersbased on historic sales information. You have to prepare different SELECT statements that use a subqueryin the WHERE clause.The main tasks for this exercise are as follows:1. Write a SELECT statement to retrieve specific products.2. Write a query and understand a three-valued predicate logic. Task 1: Write a SELECT statement to retrieve specific products• Open the project file F:\10774A_Labs\10774A_10_PRJ\10774A_10_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the productid and productname columns from theProduction.Products table. Filter the results to include only products that were sold in high quantities(more than 100 products) for a specific order line.• Execute the written statement and compare the results that you got with the desired results shown inthe file 62 - Lab Exercise 2 - Task 1 Result.txt. Task 2: Write a SELECT statement to retrieve those customers without orders• Write a SELECT statement to retrieve the custid and contactname columns from the Sales.Customerstable. Filter the results to include only those customers that do not have any placed orders.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 63 - Lab Exercise 2 - Task 2 Result.txt. Remember the number of rows in the results. Task 3: Add a row and rerun the query that retrieves those customers without orders• The IT department has written a T-<strong>SQL</strong> statement that inserts an additional row in the Sales.Orderstable. This row has a NULL in the custid column.INSERT INTO Sales.Orders (custid, empid, orderdate, requireddate, shippeddate, shipperid, freight,shipname, shipaddress, shipcity, shipregion, shippostalcode, shipcountry)VALUES(NULL, 1, '20111231', '20111231', '20111231', 1, 0,'ShipOne', 'ShipAddress', 'ShipCity', 'RA', '1000', 'USA')• Execute this query exactly as written inside a query window.• Copy the T-<strong>SQL</strong> statement you wrote in task 2 and execute it.• Observe the result. How many rows are in the result? Why?• Modify the T-<strong>SQL</strong> statement to retrieve the same number of rows as in task 2. (Hint: You have toremove the rows with an unknown value in the custid column.)• Execute the modified statement and compare the results that you got with the recommended resultsshown in the file 64 - Lab Exercise 2 - Task 3 Result.txt.Results: After this exercise, you should know how to use multi-result subqueries in T-<strong>SQL</strong> statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-25Exercise 3: Writing Queries That Use Correlated Subqueries and an EXISTSPredicateScenarioThe sales department would like to have some additional reports to display different analyses of existingcustomers. Because the requests are complex, you will need to use correlated subqueries.The main tasks for this exercise are as follows:1. Write a SELECT statement to return the last order date for each customer.2. Write a SELECT statement to display customers without an order using a correlated subquery.3. Write an advanced T-<strong>SQL</strong> statement to retrieve running aggregates. Task 1: Write a SELECT statement to retrieve the last order date for each customer• Open the project file F:\10774A_Labs\10774A_10_PRJ\10774A_10_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the custid and contactname columns from the Sales.Customerstable. Add a calculated column named lastorderdate that contains the last order date from theSales.Orders table for each customer. (Hint: You have to use a correlated subquery.)• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 72 - Lab Exercise 3 - Task 1 Result.txt. Task 2: Write a SELECT statement that uses the EXISTS predicate to retrieve thosecustomers without orders• Write a SELECT statement to retrieve all customers that do not have any orders in the Sales.Orderstable, similar to the request in exercise 2, task 3. However, this time use the EXISTS predicate to filterthe results to include only those customers without an order. Also, you do not need to explicitly checkthat the custid column in the Sales.Orders table is not NULL.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 73 - Lab Exercise 3 - Task 2 Result.txt.• Why didn’t you need to check for a NULL? Task 3: Write a SELECT statement to retrieve customers that bought expensiveproducts• Write a SELECT statement to retrieve the custid and contactname columns from the Sales.Customerstable. Filter the results to include only customers that placed an order on or after April 1, 2008, andordered a product with a price higher than $100.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 74 - Lab Exercise 3 - Task 3 Result.txt.


10-26 Using Subqueries Task 4 (challenge): Write a SELECT statement to display the total sales amount andthe running total sales amount for each order year• Running aggregates are aggregates that accumulate values over time. Write a SELECT statement toretrieve the following information for each year:• The order year• The total sales amount• The running total sales amount over the years. That is, for each year, return the sum of salesamount up to that year. So, for example, for the earliest year (2006) return the total sales amount,for the next year (2007), return the sum of the total sales amount for the previous year and theyear 2007.• The SELECT statement should have three calculated columns:• orderyear, representing the order year. This column should be based on the orderyear columnfrom the Sales.Orders table.• totalsales, representing the total sales amount for each year. This column should be based on theqty and unitprice columns from the Sales.OrderDetails table.• runsales, representing the running sales amount. This column should use a correlated subquery.• Execute the T-<strong>SQL</strong> code and compare the results that you got with the recommended results shownin the file 75 - Lab Exercise 3 - Task 4 Result.txt. Task 5: Clean the Sales.Customers table• Delete the row added in exercise 2 using the provided <strong>SQL</strong> statement:DELETE Sales.OrdersWHERE custid IS NULL;• Execute this query exactly as written inside a query window.Results: After this exercise, you should have an understanding of how to use a correlated subquery in T-<strong>SQL</strong> statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 10-27Module ReviewReview Questions1. Can a correlated subquery return a multi-valued set?2. What type of subquery may be rewritten as a JOIN?3. What columns should appear in the SELECT list of a subquery following the EXISTS predicate?


10-28 Using Subqueries


11-1Module 11Using Table ExpressionsContents:Lesson 1: Using Views 11-3Lesson 2: Using Inline Table-Valued Functions 11-9Lesson 3: Using Derived Tables 11-14Lesson 4: Using Common Table Expressions 11-25Lab: Using Table Expressions 11-29


11-2 Using Table ExpressionsModule OverviewPreviously in this course, you learned about using subqueries as an expression that returned results to anouter calling query. Like subqueries, table expressions are query expressions, but table expressions extendthis idea by allowing you to name them and to work with their results as you would work with data in anyvalid relational table. Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> supports four types of table expressions: derivedtables, common table expression (CTEs), views, and inline table-valued functions (TVFs). In this module,you will learn to work with these forms of table expressions and learn how to use them to help create amodular approach to writing queries.ObjectivesAfter completing this module, you will be able to:• Create simple views and write queries against them.• Create simple inline TVFs and write queries against them.• Write queries that use derived tables.• Write queries that use CTEs.Note Some of the examples used in this module have been adapted from samplespublished in Microsoft <strong>SQL</strong> Server 2008 T-<strong>SQL</strong> Fundamentals, Microsoft Press 2009.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-3Lesson 1Using ViewsSo far in this module, you have learned about table expressions whose lifespan is limited to the query inwhich they are defined and invoked. Views and TVFs, however, can be persistently stored in a databaseand reused. A view is a table expression whose definition is stored in a <strong>SQL</strong> Server database. Like derivedtables and CTEs, views are defined with SELECT statements. This provides not only the benefits ofmodularity and encapsulation possible with derived table and CTEs, but also adds reusability as well asadditional security beyond what is provided with query-scoped table expressions.Lesson ObjectivesAfter completing this lesson, you will be able to:• Write queries that return results from views.• Create simple views.


11-4 Using Table ExpressionsWriting Queries That Return Results from ViewsA view is a named table expression whose definition is stored as metadata in a <strong>SQL</strong> Server database. Viewscan be used as a source for queries in much the same way as tables themselves. However, views do notpersistently store data; the definition of the view is unpacked at runtime and the source objects arequeried.Note There is one form of view, an indexed view, in which data is materialized in the view.Indexed views are beyond the scope of this course.To write a query that uses a view as its data source, use the two-part view name wherever the table sourcewould be used, such as in a FROM or a JOIN clause:SELECT FROM ORDER BY ;Note that an ORDER BY clause is used in this sample syntax to emphasize the point that as a tableexpression, there is no sort order included in the definition of a view. This will be discussed later in thislesson.The following example uses a sample view whose definition is stored in the T<strong>SQL</strong><strong>2012</strong> database. Note thatthere is no way to determine that the FROM clause references a view and not a table:SELECT custid, ordermonth, qtyFROM Sales.CustOrders;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-5The partial results are indistinguishable from any other table-based query:custid ordermonth qty----------- ----------------------- -----------7 2006-07-01 00:00:00.000 5013 2006-07-01 00:00:00.000 1114 2006-07-01 00:00:00.000 57The apparent similarity between a table and a view provides an important benefit: an application can bewritten to use views instead of the underlying tables, shielding the application from changes to the tables.As long as the view continues to present the same structure to the calling application, the application willreceive consistent results. Views can be considered an application programming interface (API) to adatabase for purposes of retrieving data.Administrators can also use views as a security layer, granting users permissions to select from a viewwithout providing permissions on the underlying source tables.For More Information For more information on database security, see Microsoft Course10775: Administering Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases.


11-6 Using Table ExpressionsCreating Simple ViewsIn order to use views in your queries, the view must be created by a database developer or administratorwith appropriate permission in the database. While coverage of database security is beyond the scope ofthis course, you will have permission to create views in the lab database.To store a view definition, use the CREATE VIEW T-<strong>SQL</strong> statement to name and store a single SELECTstatement. Note that the ORDER BY clause is not permitted in a view definition unless the view uses aTOP, OFFSET/FETCH, or FOR XML element:CREATE VIEW [][WITH ]AS select_statement;Note This lesson covers the basics of creating views for the purposes of discussion aboutquerying them only. For more information on views and view options, see Microsoft Course10776: Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases.The following example creates the view named Sales.CustOrders that exists in the T<strong>SQL</strong><strong>2012</strong> sampledatabase. Most of the code within the example makes up the definition of the SELECT statement itself:CREATE VIEW Sales.CustOrdersASSELECTO.custid,DATEADD(month, DATEDIFF(month, 0, O.orderdate), 0) AS ordermonth,SUM(OD.qty) AS qtyFROM Sales.Orders AS OJOIN Sales.OrderDetails AS ODON OD.orderid = O.orderidGROUP BY custid, DATEADD(month, DATEDIFF(month, 0, O.orderdate), 0);


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-7You can query system metadata by querying system catalog views such as sys.views, which you will learnabout in a later module. To query a view, refer to it in the FROM clause of a SELECT statement, like youwould refer to a table:SELECT custid, ordermonth, qtyFROM Sales.CustOrders;


11-8 Using Table ExpressionsDemonstration: Using ViewsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_11_PRJ\10774A_11_PRJ.ssmssln and click Open.1. On the View menu, click Solution Explorer.2. Open the 11 – Demonstration A.sql script file.3. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-9Lesson 2Using Inline Table-Valued FunctionsAn inline table-valued function (TVF) is a form of table expression that has several properties in commonwith views. Like a view, the definition of a TVF is stored as a persistent object in a database. Also like aview, an inline TVF encapsulates a single SELECT statement, returning a virtual table to the calling query.A primary distinction between a view and an inline TVF is that an inline TVF can accept input parametersand refer to them in the embedded SELECT statement.In this lesson, you will learn how to create basic inline TVFs and write queries that return results fromthem.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the structure and usage of inline TVFs.• Use the CREATE FUNCTION statement to create simple inline TVFs.• Write queries that return results from inline TVFs.


11-10 Using Table ExpressionsWriting Queries That Use Inline Table-Valued FunctionsInline TVFs are named table expressions whose definitions are stored persistently in a database that canbe queried in much the same way as a view. This enables reuse and centralized management of code in away that is not possible for derived tables and CTEs as query-scoped table expressions.Note <strong>SQL</strong> Server supports several types of user-defined functions. In addition to inlineTVFs, users can create scalar functions, multi-statement TVFs, and functions written in the.NET Common Language Runtime (CLR). For more information on these functions, seeMicrosoft course 10776: Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases.One of the key distinctions between views and inline TVFs is that inline TVFs can accept input parameters.Therefore, you may think of inline TVFs conceptually as parameterized views and choose to use inlineTVFs in place of views for occasions when flexibility of input is preferred.For More Information Additional reading can be found in Books Online athttp://go.microsoft.com/fwlink/?LinkId=220033.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-11Creating Simple Inline Table-Valued FunctionsIn order to use inline table-valued functions in your queries, the TVF must be created by a databasedeveloper or administrator with appropriate permission in the database. While coverage of databasesecurity is beyond the scope of this course, you will have permission to create TVFs in the lab database.To store an inline TVF view definition:• Use the CREATE FUNCTION T-<strong>SQL</strong> statement to name and store a single SELECT statement withoptional parameters.• Use RETURNS TABLE to identify this function as a TVF.• Enclose the SELECT statement inside parentheses following the RETURN keyword to make this aninline function:CREATE FUNCTION (@ AS , ...)RETURNS TABLEASRETURN ();The following example creates an inline TVF, which takes an input parameter to control how manyrows are returned by the TOP operator:CREATE FUNCTION Production.TopNProducts(@t AS INT)RETURNS TABLEASRETURN(SELECT TOP (@t) productid, productname, unitpriceFROM Production.ProductsORDER BY unitprice DESC);


11-12 Using Table ExpressionsRetrieving from Inline Table-Valued FunctionsAfter creating an inline TVF, you can invoke it by selecting from it, as you would a view. If there is anargument, you need to enclose it in parentheses. Multiple arguments need to be separated by commas.Here is an example of how to query an inline TVF:SELECT * FROM Production.TopNProducts(3)The results:productid productname unitprice--------- ------------- ---------38 Product QDOMO 263.5029 Product VJXYN 123.799 Product AOZBW 97.00(3 row(s) affected)Note Use of a two-part name is required when calling a user-defined function.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-13Demonstration: Inline Table-Valued FunctionsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_11_PRJ\10774A_11_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


11-14 Using Table ExpressionsLesson 3Using Derived TablesIn this lesson, you will learn how to write queries that create derived tables in the FROM clause of an outerquery. You will also learn how to return results from the table expression defined in the derived table.Lesson ObjectivesAfter completing this lesson, you will be able to:• Write queries that create and retrieve results from derived tables.• Describe how to provide aliases for column names in derived tables.• Pass arguments to derived tables.• Describe nesting and reuse behavior in derived tables.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-15Writing Queries with Derived TablesEarlier in this course, you learned about subqueries, which are queries nested within other SELECTstatements. Like subqueries, you create derived tables in the FROM clause of an outer SELECT statement.Unlike subqueries, you write derived tables using a named expression that is logically equivalent to a tableand may be referenced as a table elsewhere in the outer query. Derived tables allow you to write T-<strong>SQL</strong>statements that are more modular, helping you break down complex queries into more manageableparts. Using derived tables in your queries can also provide workarounds for some of the restrictionsimposed by the logical order of query processing, such as the use of column aliases.To create a derived table, write the inner query between parentheses, followed by an AS clause and aname for the derived table:SELECT FROM (SELECT FROM ) AS The following example uses a derived table to retrieve information about orders placed by distinctcustomers per year. The inner query builds a set of orders and places it into the derived tablederived_year. The outer query operates on the derived table and summarizes the results:SELECT orderyear, COUNT(DISTINCT custid) AS cust_countFROM (SELECT YEAR(orderdate) AS orderyear, custidFROM Sales.Orders) AS derived_yearGROUP BY orderyear;


11-16 Using Table ExpressionsThe results:orderyear cust_count--------- ----------2006 672007 862008 81(3 row(s) affected)When writing queries that use derived tables, consider the following:• Derived tables are not stored in the database. Therefore, no special security privileges are required towrite queries using derived tables, other than the rights to select from the source objects.• A derived table is created at the time of execution of the outer query and goes out of scope when theouter query ends.• Derived tables do not necessarily have an impact on performance, compared to the same queryexpressed differently. When the query is processed, the statement is unpacked and evaluated againstthe underlying database objects.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-17Guidelines for Derived TablesWhen writing queries that use derived tables, keep the following guidelines in mind:• The nested SELECT statement that defines the derived table must have an alias assigned to it. Theouter query will use the alias in its SELECT statement in much the same way you refer to aliased tablesjoined in a FROM clause.• All columns referenced in the derived table's SELECT clause should be assigned aliases, a best practicethat is not always required in T-<strong>SQL</strong>. Each alias must be unique within the expression. The columnaliases may be declared inline with the columns or externally to the clause. You will see examples ofthis in the next topic.• The SELECT statement that defines the derived table expression may not use an ORDER BY clause,unless it also includes a TOP operator, an OFFSET/FETCH clause, or a FOR XML clause. As a result,there is no sort order provided by the derived table. You sort the results in the outer query.• The SELECT statement that defines the derived table may be written to accept arguments in the formof local variables. If the SELECT statement is embedded in a stored procedure, the arguments may bewritten as parameters for the procedure. You will see examples of this later in the module.• Derived table expressions that are nested within an outer query can contain other derived tableexpressions. Nesting is permitted, but it is not recommended due to increased complexity andreduced readability.• A derived table may not be referred to multiple times within an outer query. If you need tomanipulate the same results, you will need to define the derived table expression each time, such ason each side of a JOIN operator.Note You will see examples of multiple usage of the same derived table expression in aquery in the demonstration for this lesson.


11-18 Using Table ExpressionsUsing Aliases for Column Names in Derived TablesTo create aliases, you can use one of two methods: inline or external.To define aliases inline or with the column specification, use the following syntax. Note that aliases are notrequired by T-<strong>SQL</strong>, but are a best practice:SELECT FROM (SELECT AS , AS ...FROM );The following example declares aliases inline for the results of the YEAR function and the custid column:SELECT orderyear, COUNT(DISTINCT custid) AS cust_countFROM (SELECT YEAR(orderdate) AS orderyear, custidFROM Sales.Orders) AS derived_yearGROUP BY orderyear;A partial result for the inner query displays the following:orderyear custid----------- ------2006 852006 792006 34


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-19The inner results are passed to the outer query, which operates on the derived table's orderyear andcustid columns:orderyear cust_count----------- -----------2006 672007 862008 81To use externally declared aliases with derived tables, use the following syntax:SELECT FROM ( SELECT , ..FROM ) AS (, );The following example uses external alias definitions for orderyear and custid:SELECT orderyear, COUNT(DISTINCT custid) AS cust_countFROM (SELECT YEAR(orderdate), custidFROM Sales.Orders) AS derived_year(orderyear, custid)GROUP BY orderyear;Note When using external aliases, if the inner query is executed separately, the aliases willnot be returned to the outer query. For ease of testing and readability, it is recommendedthat you use inline aliases rather than external aliases.


11-20 Using Table ExpressionsPassing Arguments to Derived TablesDerived tables in <strong>SQL</strong> Server <strong>2012</strong> can accept arguments passed in from a calling routine, such as a T-<strong>SQL</strong>batch, function, or a stored procedure. Derived tables can be written with local variables serving asplaceholders in their code. At runtime, the placeholders can be replaced with values supplied in the batchor with values passed as parameters to the stored procedure that invoked the query. This will allow yourcode to be reused more flexibly than rewriting the same query with different values each time.Note The use of parameters in functions and stored procedures will be covered later inthis course. This lesson focuses on writing table expressions that can accept arguments.For example, the following batch declares a local variable (marked with the @ symbol) for the employeeID, and then uses the ability of <strong>SQL</strong> Server 2008 and later to assign a value to the variable in the samestatement. The query accepts the @emp_id variable and uses it in the derived table expression:DECLARE @emp_id INT = 9; --declare and assign the variableSELECT orderyear, COUNT(DISTINCT custid) AS cust_countFROM (SELECT YEAR(orderdate) AS orderyear, custidFROM Sales.OrdersWHERE empid=@emp_id --use the variable to pass a value to the derived table query) AS derived_yearGROUP BY orderyear;GO


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-21The results:orderyear cust_count----------- -----------2006 52007 162008 16(3 row(s) affected)Note You will learn more about declaring variables, executing T-<strong>SQL</strong> code in batches, andworking with stored procedures later in this class.


11-22 Using Table ExpressionsNesting and Reusing Derived TablesSince a derived table is itself a complete query expression, it is possible for that query to refer to a derivedtable expression. This creates a nesting scenario, which while possible, is not recommended for reasons ofcode maintenance and readability. For example, the following query nests one derived table withinanother:SELECT orderyear, cust_countFROM (SELECT orderyear, COUNT(DISTINCT custid) AS cust_countFROM (SELECT YEAR(orderdate) AS orderyear ,custidFROM Sales.Orders) AS derived_table_1GROUP BY orderyear) AS derived_table_2WHERE cust_count > 80;Logically, the innermost query is processed first, returning these partial results as derived_table_1:orderyear custid----------- -----------2006 852006 792006 34Next, the middle query runs, grouping and aggregating the results into derived_table_2:orderyear cust_count----------- -----------2006 672007 862008 81


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-23Finally, the outer query runs, filtering the output:orderyear cust_count----------- -----------2007 862008 81As you can see, while is possible to nest derived tables, it does add complexity.While nesting derived tables is possible, references to the same derived table from multiple clauses of anouter query can be challenging. Since the table expression is defined in the FROM clause, subsequentphases of the query can see it, but it cannot be referenced elsewhere in the same FROM clause.For example, a derived table defined in a FROM clause may be referenced in a WHERE clause, but not in aJOIN in the same FROM clause that defines it. The derived table must be defined separately, and multiplecopies of the code must be maintained. For an alternative approach that allows reuse without maintainingseparate copies of the derived table definition, see common table expression discussion later in thismodule.Question: How could you rewrite the previous example to eliminate one level of nesting?


11-24 Using Table ExpressionsDemonstration: Using Derived TablesDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_11_PRJ\10774A_11_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 31 – Demonstration C.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-25Lesson 4Using Common Table ExpressionsAnother form of table expression provided by <strong>SQL</strong> Server <strong>2012</strong> is the common table expression, or CTE.Similar in some ways to derived tables, CTEs provide a mechanism for defining a subquery that may thenbe used elsewhere in a query. Unlike a derived table, a CTE is defined at the beginning of a query andmay be referenced multiple times in the outer query.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the use of CTEs.• Write queries that create CTEs and return results from the table expression.• Describe how a CTE can be reused multiple times by the same outer query.


11-26 Using Table ExpressionsWriting Queries with Common Table ExpressionsCTEs are named expressions defined in a query. Like subqueries and derived tables, CTEs provide a meansto break down query problems into smaller, more modular units.When writing queries with CTEs, consider the following guidelines:• Like derived tables, CTEs are limited in scope to the execution of the outer query. When the outerquery ends, the CTE's lifetime ends.• CTEs require a name for the table expression, as well as unique names for each of the columnsreferenced in the CTE's SELECT clause.• CTEs may use inline or external aliases for columns.• Unlike a derived table, a CTE may be referenced multiple times in the same query with one definition.Multiple CTEs may also be defined in the same WITH clause.• CTEs support recursion, in which the expression is defined with a reference to itself. Recursive CTEsare beyond the scope of this course.For More Information Additional reading on recursive CTEs may be found in BooksOnline at http://go.microsoft.com/fwlink/?LinkId=242962.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-27Creating Queries with Common Table ExpressionsTo create a common table expression, define the CTE in a WITH clause, as in the following syntax:WITH AS ( )For example, the same query used to illustrate derived tables, when written to use a CTE, looks like this:WITH CTE_year --name the CTEAS -- define the subquery(SELECT YEAR(orderdate) AS orderyear, custidFROM Sales.Orders)SELECT orderyear, COUNT(DISTINCT custid) AS cust_countFROM CTE_year --reference the CTE in the outer queryGROUP BY orderyear;The results:orderyear cust_count----------- -----------2006 672007 862008 81(3 row(s) affected)


11-28 Using Table ExpressionsDemonstration: Using CTEsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_11_PRJ\10774A_11_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 41 – Demonstration D.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-29Lab: Using Table ExpressionsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


11-30 Using Table Expressions7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft <strong>SQL</strong> Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You have been provided with a set of business requirements for data and youwill write T-<strong>SQL</strong> queries to retrieve the specified data from the databases. Because of advanced businessrequests, you will have to learn how to create and query different query expressions that represent a validrelational table.Important When comparing your results with the provided sample outputs, the column orderingand total number of affected rows should always match. However, remember that the order of therows in the output of a query without an ORDER BY clause is not guaranteed. Therefore, the order ofthe rows in the sample outputs may be different than yours. Also, the answer outputs includeabbreviated results.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-31Exercise 1: Writing Queries That Use ViewsScenarioIn the last 10 modules, you had to prepare a lot of different T-<strong>SQL</strong> statements to support differentbusiness requirements. Because some of them used a similar table and column structure, you would liketo have them reusable. You will learn how to use one of two persistent table expressions: a view.The main tasks for this exercise are as follows:1. Write a SELECT statement and use the supplied T-<strong>SQL</strong> code to create a view.2. Write a SELECT statement against the view.3. Modify the view and learn about some of the needed prerequisites for creating a view. Task 1: Write a SELECT statement to retrieve all products for a specific category• Open the project file F:\10774A_Labs\10774A_11_PRJ\10774A_11_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to return the productid, productname, supplierid, unitprice, anddiscontinued columns from the Production.Products table. Filter the results to include only productsthat belong to the category Beverages (categoryid equals 1).• Observe and compare the results that you got with the desired results shown in the file52 - Lab Exercise 1 - Task 1 Result.txt.• Modify the T-<strong>SQL</strong> code to include the following supplied T-<strong>SQL</strong> statement. Put this statement beforethe SELECT clause:CREATE VIEW Production.ProductsBeverages AS• Execute the complete T-<strong>SQL</strong> statement. This will create an object view named ProductsBeveragesunder the Production schema. Task 2: Write a SELECT statement against the created view• Write a SELECT statement to return the productid and productname columns from theProduction.ProductsBeverages view. Filter the results to include only products where supplieridequals 1.• Execute the written statement and compare the results that you got with the desired results shown inthe file 53 - Lab Exercise 1 - Task 2 Result.txt. Task 3: Try to use an ORDER BY clause in the created view• The IT department has written a T-<strong>SQL</strong> statement that adds an ORDER BY clause to the view createdin task 1:ALTER VIEW Production.ProductsBeverages ASSELECTproductid, productname, supplierid, unitprice, discontinuedFROM Production.ProductsWHERE categoryid = 1ORDER BY productname;• Execute the provided code. What happened? What is the error message? Why did the query fail?


11-32 Using Table Expressions• Modify the supplied T-<strong>SQL</strong> statement by including the TOP (100) PERCENT option. The query shouldlook like this:ALTER VIEW Production.ProductsBeverages ASSELECT TOP(100) PERCENTproductid, productname, supplierid, unitprice, discontinuedFROM Production.ProductsWHERE categoryid = 1ORDER BY productname;• Execute the modified T-<strong>SQL</strong> statement. By applying the needed changes, you have altered theexisting view. Notice that you are still using the ORDER BY clause.• If you write a query against the modified Production.ProductsBeverages view, will it be guaranteedthat the retrieved rows will be sorted by productname? Please explain. Task 4: Add a calculated column to the view• The IT department has written a T-<strong>SQL</strong> statement that adds an additional calculated column to theview created in task 1:ALTER VIEW Production.ProductsBeverages ASSELECTproductid, productname, supplierid, unitprice, discontinued,CASE WHEN unitprice > 100. THEN N'high' ELSE N'normal' ENDFROM Production.ProductsWHERE categoryid = 1;• Execute the provided query. What happened? What is the error message? Why did the query fail?• Apply the changes needed to get the T-<strong>SQL</strong> statement to execute properly. Task 5: Remove the Production.ProductsBeverages view• Remove the created view by executing the provided T-<strong>SQL</strong> statement:IF OBJECT_ID(N'Production.ProductsBeverages', N'V') IS NOT NULLDROP VIEW Production.ProductsBeverages;• Execute this code exactly as written inside a query window.Results: After this exercise, you should know how to use a view in T-<strong>SQL</strong> statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-33Exercise 2: Writing Queries That Use Derived TablesScenarioThe sales department would like to compare the sales amounts between the ordered year and theprevious year to calculate the growth percentage. To prepare such a report, you will learn how to usederived tables inside T-<strong>SQL</strong> statements.The main tasks for this exercise are as follows:1. Write a SELECT statement against a derived table.2. Write a SELECT statement to calculate the total sales amount and the average sales amount foreach customer.3. Write a SELECT statement to retrieve the sales growth percentage. Task 1: Write a SELECT statement against a derived table• Open the project file F:\10774A_Labs\10774A_11_PRJ\10774A_11_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement against a derived table and retrieve the productid and productnamecolumns. Filter the results to include only the rows in which the pricetype column value is equal tohigh. Use the SELECT statement from exercise 1, task 4, as the inner query that defines the derivedtable. Do not forget to use an alias for the derived table. (You can use the alias p.)• Execute the written statement and compare the results that you got with the desired results shown inthe file 62 - Lab Exercise 2 - Task 1 Result.txt. Task 2: Write a SELECT statement to calculate the total and average sales amount• Write a SELECT statement to retrieve the custid column and two calculated columns:totalsalesamount, which returns the total sales amount per customer, and avgsalesamount, whichreturns the average sales amount of orders per customer. To correctly calculate the average salesamount of orders per customer, you will first have to calculate the total sales amount per order.You can do so by defining a derived table based on a query that joins the Sales.Orders andSales.OrderDetails tables. You can use the custid and orderid columns from the Sales.Orders tableand the qty and unitprice columns from the Sales.OrderDetails table.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 63 - Lab Exercise 2 - Task 2 Result.txt.


11-34 Using Table Expressions Task 3 (challenge): Write a SELECT statement to retrieve the sales growth percentage• Write a SELECT statement to retrieve the following columns:• orderyear, representing the year of the order date• curtotalsales, representing the total sales amount for the current order year• prevtotalsales, representing the total sales amount for the previous order year• percentgrowth, representing the percentage of sales growth in the current order year comparedto the previous order year• You will have to write a T-<strong>SQL</strong> statement using two derived tables. To get the order year and totalsales columns for each SELECT statement, you can query an already existing view namedSales.OrderValues. The val column represents the sales amount.• Do not forget that the order year 2006 does not have a previous order year in the database, but itshould still be retrieved by the query.• Execute the T-<strong>SQL</strong> code and compare the results that you got with the recommended results shownin the file 64 - Lab Exercise 2 - Task 3 Result.txt.Results: After this exercise, you should be able to use derived tables in T-<strong>SQL</strong> statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-35Exercise 3: Writing Queries That Use Common Table Expressions (CTEs)ScenarioThe sales department needs an additional report showing the sales growth over the years for eachcustomer. You could use your existing knowledge of derived tables and views, but instead you willpractice how to use a common table expression (CTE).The main tasks for this exercise are as follows:1. Write the same SELECT statement as in exercise 2 but using a CTE.2. Write a SELECT statement to retrieve the sales amount for each customer.3. Write an advanced T-<strong>SQL</strong> statement to retrieve the yearly sales growth for the year 2008 foreach customer. Task 1: Write a SELECT statement that uses a CTE• Open the project file F:\10774A_Labs\10774A_11_PRJ\10774A_11_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement like that in exercise 2, task 1, but use a CTE instead of a derived table. Useinline column aliasing in the CTE query and name the CTE ProductBeverages.• Execute the T-<strong>SQL</strong> code and compare the results that you got with the recommended results shownin the file 72 - Lab Exercise 3 - Task 1 Result.txt. Task 2: Write a SELECT statement to retrieve the total sales amount for eachcustomer• Write a SELECT statement against Sales.OrderValues to retrieve each customer’s ID and total salesamount for the year 2008. Define a CTE named c2008 based on this query using the external aliasingform to name the CTE columns custid and salesamt2008. Join the Sales.Customers table and thec2008 CTE, returning the custid and contactname columns from the Sales.Customers table and thesalesamt2008 column from the c2008 CTE.• Execute the T-<strong>SQL</strong> code and compare the results that you got with the recommended results shownin the file 73 - Lab Exercise 3 - Task 2 Result.txt.


11-36 Using Table Expressions Task 3 (challenge): Write a SELECT statement to compare the total sales amount foreach customer over the previous year• Write a SELECT statement to retrieve the custid and contactname columns from the Sales.Customerstable. Also retrieve the following calculated columns:• salesamt2008, representing the total sales amount for the year 2008• salesamt2007, representing the total sales amount for the year 2007• percentgrowth, representing the percentage of sales growth between the year 2007 and 2008• If percentgrowth is NULL, then display the value 0.• You can use the CTE from the previous task and add another CTE for the year 2007. Then join both ofthem with the Sales.Customers table. Order the result by the percentgrowth column.• Execute the T-<strong>SQL</strong> code and compare the results that you got with the recommended results shownin the file 74 - Lab Exercise 3 - Task 3 Result.txt.Results: After this exercise, you should have an understanding of how to use a CTE in a T-<strong>SQL</strong> statement.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-37Exercise 4: Writing Queries That Use Inline Table-Valued FunctionsScenarioYou learned how to write a SELECT statement against a view. But since a view does not supportparameters, you will now use an inline table-valued function to retrieve data as a relational table based onan input parameter.The main tasks for this exercise are as follows:1. Write a SELECT statement that uses a parameter for the order year and retrieves all customers and thetotal sales value for the specified year.2. Write a SELECT statement against the created inline table-valued function.3. Write a SELECT statement to retrieve the top three products by sales amount for a specific customerand create an inline table-valued function. Task 1: Write a SELECT statement to retrieve the total sales amount for eachcustomer• Open the project file F:\10774A_Labs\10774A_11_PRJ\10774A_11_PRJ.ssmssln and the T-<strong>SQL</strong> script81 - Lab Exercise 4.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement against the Sales.OrderValues view and retrieve the custid andtotalsalesamount columns as a total of the val column. Filter the results to include orders only forthe year 2007.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 82 - Lab Exercise 4 - Task 1 Result.txt.• Define an inline table-valued function using the following function header and add your previousquery after the RETURN clause:CREATE FUNCTION dbo.fnGetSalesByCustomer(@orderyear AS INT) RETURNS TABLEASRETURN• Modify the query by replacing the constant year value 2007 in the WHERE clause with the parameter@orderyear.• Highlight the complete code and execute it. This will create an inline table-valued function nameddbo.fnGetSalesByCustomer. Task 2: Write a SELECT statement against the inline table-valued function• Write a SELECT statement to retrieve the custid and totalsalesamount columns from thedbo.fnGetSalesByCustomer inline table-valued function. Use the value 2007 for the neededparameter.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 83 - Lab Exercise 4 - Task 2 Result.txt.


11-38 Using Table Expressions Task 3: Write a SELECT statement to retrieve the top three products based on thetotal sales value for a specific customer• In this task, you will query the Production.Products and Sales.OrderDetails tables. Write a SELECTstatement that retrieves the top three sold products based on the total sales value for the customerwith ID 1. Return the productid and productname columns from the Production.Products table. Usethe qty and unitprice columns from the Sales.OrderDetails table to compute each order line’s value,and return the sum of all values per product, naming the resulting column totalsalesamount. Filter theresults to include only the rows where the custid value is equal to 1.• Execute the T-<strong>SQL</strong> code and compare the results that you got with the recommended results shownin the file 84 - Lab Exercise 4 - Task 3_1 Result.txt.• Create an inline table-valued function based on the following function header, using the previousSELECT statement. Replace the constant custid value 1 in the query with the function’s inputparameter @custid:CREATE FUNCTION dbo.fnGetTop3ProductsForCustomer(@custid AS INT) RETURNS TABLEASRETURN• Highlight the complete code and execute it. This will create an inline table-valued function nameddbo.fnGetTop3ProductsForCustomer that accepts a parameter for the customer ID.• Test the created inline table-valued function by writing a SELECT statement against it and use thevalue 1 for the customer ID parameter. Retrieve the productid, productname, and totalsalesamountcolumns, and use the alias p for the inline table-valued function.• Execute the T-<strong>SQL</strong> code and compare the results that you got with the recommended results shownin the file 85 - Lab Exercise 4 - Task 3_2 Result.txt. Task 4 (challenge): Write a SELECT statement to compare the total sales amount foreach customer over the previous year using inline table-valued functions• Write a SELECT statement to retrieve the same result as in exercise 3, task 3, but use the created inlinetable-valued function in task 2 (dbo.fnGetSalesByCustomer).• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 86 - Lab Exercise 4 - Task 4 Result.txt. Task 5: Remove the created inline table-valued functions• Remove the created inline table-valued functions by executing the provided T-<strong>SQL</strong> statement:IF OBJECT_ID('dbo.fnGetSalesByCustomer') IS NOT NULLDROP FUNCTION dbo.fnGetSalesByCustomer;IF OBJECT_ID('dbo.fnGetTop3ProductsForCustomer') IS NOT NULLDROP FUNCTION dbo.fnGetTop3ProductsForCustomer;• Execute this code exactly as written inside a query window.Results: After this exercise, you should know how to use inline table-valued functions in T-<strong>SQL</strong>statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 11-39Module ReviewReview Questions1. When would you use a common table expression rather than a derived table for a query?2. Which table expressions allow variables to be passed in as parameters to the expression?


11-40 Using Table Expressions


12-1Module 12Using Set OperatorsContents:Lesson 1: Writing Queries with the UNION Operator 12-3Lesson 2: Using EXCEPT and INTERSECT 12-9Lesson 3: Using APPLY 12-15Lab: Using Set Operators 12-23


12-2 Using Set OperatorsModule OverviewMicrosoft® <strong>SQL</strong> Server® provides methods for performing operations using the sets that result from twoor more different queries. In this module, you will learn how to use the set operators UNION, INTERSECT,and EXCEPT to compare rows between two input sets. You will also learn how to use forms of the APPLYoperator to manipulate the rows in one table based on the output of a second table, which may be aderived table or a table-valued function.ObjectivesAfter completing this module, you will be able to:• Write queries that combine data using the UNION operator.• Write queries that compare sets using the INTERSECT and EXCEPT operators.• Write queries that manipulate rows in a table by using APPLY with the results of a derived table orfunction.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-3Lesson 1Writing Queries with the UNION OperatorIn this lesson, you will learn how to use the UNION operator to combine multiple input sets into a singleresult. UNION and UNION ALL provide a mechanism to add, in mathematical terms, one set to another,allowing you to stack result sets. UNION combines rows. In comparison, JOIN combines columns fromdifferent sources.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the conditions necessary to interact between input sets.• Write queries that use UNION to combine input sets.• Write queries that use UNION ALL to combine input sets.


12-4 Using Set OperatorsInteractions Between Sets<strong>SQL</strong> Server provides a number of set manipulation techniques using a variety of set operators. In order tosuccessfully work with these operators, it is important to understand some considerations for the inputsets themselves:• Each input set is the result of a query, which may include any SELECT statement components youhave already learned about, with the exception of an ORDER BY clause.• The input sets must have the same number of columns and the columns must have compatible datatypes. The column data types, if not initially compatible, must be made compatible through implicitconversion.• A NULL in one set is treated as equal to a NULL in another set, despite what you have learned aboutcomparing NULLs earlier in this course.• Each operator can be thought as having two forms: DISTINCT and ALL. For example UNION DISTINCTeliminates duplicate rows while combining two sets, and UNION ALL combines all rows, includingduplicates. Not all set operators support both forms in <strong>SQL</strong> Server <strong>2012</strong>.Note When working with set operators, it may be useful to remember that in set theory, aset does not provide a sort order, and it includes only distinct rows. If you need the resultssorted, you will need to add an ORDER BY to the final results since you may not use it insidethe input queries.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-5Using the UNION OperatorThe UNION operator allows you to combine rows from one input set with rows from another input setinto a resulting set. If a row appears in either of the input sets, it will be returned in the output:UNION;For example, in the T<strong>SQL</strong><strong>2012</strong> sample database, there are 29 rows in the Production.Suppliers table and91 rows in the Sales.Customers table. Simply combining all rows from each set should yield 29 + 91, or120 rows. Yet because of duplicates, UNION returns 93 rows:SELECT country, cityFROM Production.SuppliersUNIONSELECT country, cityFROM Sales.Customers;A partial result:country city--------- ---------------Argentina Buenos AiresAustralia Melbourne...USA Walla WallaVenezuela BarquisimetoVenezuela CaracasVenezuela I. de MargaritaVenezuela San Cristóbal(93 row(s) affected)


12-6 Using Set OperatorsNote Remember that there is no sort order guaranteed by set operators. Although theresults might appear to be sorted, this is a by-product of the filtering performed and is notassured. Add an ORDER BY clause at the end of the second query if you require sortedoutput.As previously mentioned, set operators can conceptually be thought of in two forms: DISTINCT and ALL.<strong>SQL</strong> Server <strong>2012</strong> does not implement an explicit UNION DISTINCT, though it does implement UNION ALL.ANSI <strong>SQL</strong> standards do specify both as explicit forms (UNION DISTINCT and UNION ALL). In T-<strong>SQL</strong>, theuse of DISTINCT is not supported. However, it is the implicit default. UNION combines all rows from eachinput set, and then filters out duplicate rows.From a performance standpoint, the use of UNION will include a filter operation, whether or not there areduplicate rows. If you need to combine sets and already know that there are no duplicates, consider usingUNION ALL to save the overhead of the distinct filter.Note You will learn about UNION ALL in the next lesson.For More Information See "UNION (Transact-<strong>SQL</strong>)" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242963.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-7Using the UNION ALL OperatorIf you wish to return all rows from both input sets, or know there will be no duplicates to filter out, youcan use the UNION ALL operator. The following example continues from the previous topic, andcombines all supplier locations with all customer locations to yield all rows from each input set:SELECT country, cityFROM Production.SuppliersUNION ALLSELECT Country, CityFROM Sales.Customers;This time, the result does include all 91 + 29 rows, partially displayed below:country city------- ---------------UK LondonUSA New Orleans...Finland HelsinkiPoland Warszawa(120 row(s) affected)Since UNION ALL does not perform any filtering of duplicates, it can be used in place of UNION in caseswhere you know there will be no duplicate input rows and wish to improve performance compared tousing UNION.


12-8 Using Set OperatorsDemonstration: Using UNION and UNION ALLDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_12_PRJ\10774A_12_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-9Lesson 2Using EXCEPT and INTERSECTWhile UNION and UNION ALL combine all rows from input sets, you may need to return either only thoserows in one set but not in the other, or only rows that are present in both sets. For these purposes theEXCEPT and INTERSECT operators may be useful to your queries. You will learn how to use EXCEPT andINTERSECT in this lesson.Lesson ObjectivesAfter completing this lesson, you will be able to:• Write queries that use the EXCEPT operator to return only rows in one set but not another.• Write queries that use the INTERSECT operator to return only rows that are present in both sets.


12-10 Using Set OperatorsUsing the INTERSECT OperatorThe T-<strong>SQL</strong> INTERSECT operator, added in <strong>SQL</strong> Server 2005, returns only distinct rows that appear in bothinput sets:INTERSECT;Note While UNION supports both conceptual forms DISTINCT and ALL, INTERSECTcurrently only provides an implicit DISTINCT option. No duplicate rows will be returned bythe operation.The following example uses INTERSECT to return geographical information in common betweencustomers and suppliers. (Remember that there are 91 rows in the Customers table and 29 rows in theSuppliers table.)SELECT country, cityFROM Production.SuppliersINTERSECTSELECT country, cityFROM Sales.Customers;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-11The results:country city-------- ---------Germany BerlinUK LondonCanada MontréalFrance ParisBrazil Sao Paulo(5 row(s) affected)For More Information See "EXCEPT and INTERSECT (Transact-<strong>SQL</strong>)" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242964.


12-12 Using Set OperatorsUsing the EXCEPT OperatorThe T-<strong>SQL</strong> EXCEPT operator, added in <strong>SQL</strong> Server 2005, returns only distinct rows that appear in one setand not the other. Specifically, EXCEPT returns rows from the input set listed first in the query. As withqueries that use a LEFT OUTER JOIN, the order in which the inputs are listed is important:EXCEPT;Note While UNION supports both conceptual forms DISTINCT and ALL, EXCEPT currentlyonly provides an implicit DISTINCT option. No duplicate rows will be returned by theoperation.The following example uses EXCEPT to return geographical information that is not common between thecustomers and suppliers. (Remember that there are 91 rows in the Customers table and 29 rows in theSuppliers table.) First the query is executed with the Suppliers table listed first:SELECT country, cityFROM Production.SuppliersEXCEPTSELECT country, cityFROM Sales.Customers;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-13This returns 24 rows, partially displayed here:country city---------- -------------Australia MelbourneAustralia SydneyCanada Ste-HyacintheDenmark LyngbyFinland LappeenrantaFrance AnnecyFrance Montceau(24 row(s) affected)The results are different when the order of the input sets is reversed:SELECT country, cityFROM Sales.CustomersEXCEPTSELECT country, cityFROM Production.Suppliers;This returns 64 rows. When using EXCEPT, plan the order of the input queries carefully.


12-14 Using Set OperatorsDemonstration: Using EXCEPT and INTERSECTDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_12_PRJ\10774A_12_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-15Lesson 3Using APPLYAs an alternative to combining or comparing rows from two sets, <strong>SQL</strong> Server provides a mechanism toapply a table expression from one set on each row in the other set. In this lesson, you will learn how to usethe APPLY operator to process rows in one set using rows in another.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the use of the APPLY operator to manipulate sets.• Write queries using the CROSS APPLY operator.• Write queries using the OUTER APPLY operator.


12-16 Using Set OperatorsUsing the APPLY Operator<strong>SQL</strong> Server provides the <strong>SQL</strong> Server-specific APPLY operator to enable queries that evaluate rows in oneinput set against the expression that defines the second input set. Strictly speaking, APPLY is a tableoperator, not a set operator. You will use APPLY in a FROM clause, like a JOIN, rather than as a setoperator that operates on two compatible result sets of queries.Conceptually, the APPLY operator is similar to a correlated subquery in that it applies a correlated tableexpression to each row from a table. However, APPLY differs from correlated subqueries by returning atable-valued result rather than a scalar or multi-valued result. For example, the table expression could bea table-valued function (TVF), and you can pass elements from the left row as input parameters to theTVF. The TVF will be logically processed once for each row in the left table. This will be demonstratedlater.Note When describing input tables used with APPLY, the terms "left" and "right" are usedin the same way as they are with the JOIN operator, based on the order they are listed inthe FROM clause.To use APPLY, you will supply two input sets within a single FROM clause. Unlike the set operators youhave learned about earlier in this lesson, with APPLY, the second, or right, input may be a TVF that will belogically processed once per row found in the other input. The TVF will typically take values found incolumns from the left input and use them as parameters within the function.Additionally, APPLY supports two different forms: CROSS APPLY and OUTER APPLY, which you will learnabout in this lesson.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-17The general syntax for APPLY lists the derived table or TVF second, or on the right, of the other inputtable:SELECT FROM AS [CROSS]|[OUTER] APPLY AS You will learn how CROSS APPLY and OUTER APPLY work in the next topics.For More Information See APPLY in the “Remarks” section of "FROM (Transact-<strong>SQL</strong>)" inBooks Online at http://go.microsoft.com/fwlink/?LinkId=242965. See alsohttp://go.microsoft.com/fwlink/?LinkId=242966.


12-18 Using Set OperatorsUsing the CROSS APPLY OperatorCROSS APPLY correlates the rows in the left table expression against the derived table or table-valuedexpression in the right input. This enables you to write queries that go beyond comparing and combiningdata. You can perform more flexible manipulations, such as TOP N per group, which will be demonstratedin the examples to follow.The usage of CROSS in CROSS APPLY may be suggestive of a CROSS JOIN, in which all rows in the lefttable are joined to all rows in the right table. However, if there is no result output from the rightexpression, the current row on the left will not be returned. In this regard, a CROSS APPLY may beconceptually closer to an INNER JOIN.To use a CROSS APPLY, list the TVF or derived table second in the query, supplying parameters if needed.The TVF or derived table will be logically processed once for each row in the left table.The following example uses the supplierid column from the left input table as an input parameter to aTVF named dbo.fn_TopProductsByShipper. If there are rows in the Suppliers table with no correspondingproducts, the rows will not be displayed:SELECT S.supplierid, s.companyname, P.productid, P.productname, P.unitpriceFROM Production.Suppliers AS SCROSS APPLY dbo.fn_TopProductsByShipper(S.supplierid) AS P;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-19Partial results appear as follows:supplierid companyname productid productname unitprice----------- -------------- ----------- ------------- ---------1 Supplier SWRXU 2 Product RECZE 19.001 Supplier SWRXU 1 Product HHYDP 18.001 Supplier SWRXU 3 Product IMEHJ 10.002 Supplier VHQZD 4 Product KSBRM 22.002 Supplier VHQZD 5 Product EPEIM 21.352 Supplier VHQZD 65 Product XYWBZ 21.053 Supplier STUAZ 8 Product WVJFP 40.003 Supplier STUAZ 7 Product HMLNI 30.003 Supplier STUAZ 6 Product VAIIV 25.00Note Code to create this example function, as well as to test it, is provided in thedemonstration script for this lesson.


12-20 Using Set OperatorsUsing the OUTER APPLY OperatorOUTER APPLY correlates the rows in the left table expression against the derived table or table-valuedexpression in the right input. Like CROSS APPLY, the table expression on the right will be processed oncefor each row in the left input table. However, where CROSS APPLY did not return rows where the rightexpression had an empty result, OUTER APPLY will add rows for the left table where NULL was returnedon the right. The usage of OUTER in OUTER APPLY is conceptually similar to a LEFT OUTER JOIN, in whichall rows in the left table are joined to matching rows in the right table and NULLs are added.The following example uses the custid column from the left input table as an input parameter to a derivedtable that accepts the custid and uses it to find corresponding orders. If there are rows in the Customerstable with no corresponding orders, the rows will be displayed with NULL for order attributes:SELECT C.custid, TopOrders.orderid, TopOrders.orderdateFROM Sales.Customers AS COUTER APPLY(SELECT TOP (3) orderid, orderdateFROM Sales.Orders AS OWHERE O.custid = C.custidORDER BY orderdate DESC, orderid DESC) AS TopOrders;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-21Partial results, including rows with NULLs, appear as follows:custid orderid orderdate----------- ----------- -----------1 11011 20081 10952 20081 10835 20082 10926 20082 10759 20072 10625 200722 NULL NULL57 NULL NULL58 11073 200858 10995 200858 10502 2007(265 row(s) affected)


12-22 Using Set OperatorsDemonstration: Using CROSS APPLY and OUTER APPLYDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. From the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_12_PRJ\10774A_12_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 31 – Demonstration C.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-23Lab: Using Set OperatorsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


12-24 Using Set Operators7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You have been provided with a set of business requirements for data and youwill write T-<strong>SQL</strong> queries to retrieve the specified data from the databases. Because of the complexbusiness requirements, you will need to prepare combined results from multiple queries using setoperators.Important When comparing your results with the provided sample outputs, the column orderingand total number of affected rows should always match. However, remember that the order of therows in the output of a query without an ORDER BY clause is not guaranteed. Therefore, the order ofthe rows in the sample outputs may be different than yours. Also, the answer outputs includeabbreviated results.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-25Exercise 1: Writing Queries That Use UNION Set Operators and UNION ALLMulti-Set OperatorsScenarioThe marketing department needs some additional information regarding segmentation of products andcustomers. It would like to have a report based on multiple queries but be presented as one result. Youwill write different SELECT statements and then merge them together into one result using the UNIONoperator.The main tasks for this exercise are as follows:1. Write a couple of SELECT statements to retrieve products based on different business requirements.2. Write a SELECT statement to retrieve and combine the results from the two T-<strong>SQL</strong> statements.3. Write a SELECT statement to retrieve different groups of customers. Task 1: Write a SELECT statement to retrieve specific products• Open the project file F:\10774A_Labs\10774A_12_PRJ\10774A_12_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to return the productid and productname columns from theProduction.Products table. Filter the results to include only products that have a categoryid value 4.• Execute the written statement and compare the results that you got with the desired results shown inthe file 52 - Lab Exercise 1 - Task 1 Result.txt. Remember the number of rows in the results. Task 2: Write a SELECT statement to retrieve all products with more than $50,000total sales amount• Write a SELECT statement to return the productid and productname columns from theProduction.Products table. Filter the results to include only products that have a total sales amount ofmore than $50,000. For the total sales amount, you will need to query the Sales.OrderDetails tableand aggregate all order line values (qty * unitprice) for each product.• Execute the written statement and compare the results that you got with the desired results shown inthe file 53 - Lab Exercise 1 - Task 2 Result.txt. Remember the number of rows in the results. Task 3: Merge the results from task 1 and task 2• Write a SELECT statement that uses the UNION operator to retrieve the productid and productnamecolumns from the T-<strong>SQL</strong> statements in task 1 and task 2.• Execute the written statement and compare the results that you got with the desired results shown inthe file 54 - Lab Exercise 1 - Task 3_1 Result.txt.• What is the total number of rows in the results? If you compare this number with an aggregate valueof the number of rows from task 1 and task 2, is there any difference?• Copy the T-<strong>SQL</strong> statement and modify it to use the UNION ALL operator.• Execute the written statement and compare the results that you got with the desired results shown inthe file 55 - Lab Exercise 1 - Task 3_2 Result.txt.• What is the total number of rows in the result? What is the difference between the UNION andUNION ALL operators?


12-26 Using Set Operators Task 4: Write a SELECT statement to retrieve the top 10 customers by sales amountfor January 2008 and February 2008• Write a SELECT statement to retrieve the custid and contactname columns from the Sales.Customerstable. Display the top 10 customers by sales amount for January 2008 and display the top 10customers by sales amount for February 2008 (Hint: Write two SELECT statements each joiningSales.Customers and Sales.OrderValues and use the appropriate set operator.)• Execute the T-<strong>SQL</strong> code and compare the results that you got with the desired results shown in thefile 56 - Lab Exercise 1 - Task 4 Result.txt.Results: After this exercise, you should know how to use the UNION and UNION ALL set operators in T-<strong>SQL</strong> statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-27Exercise 2: Writing Queries That Use the CROSS APPLY and OUTER APPLYOperatorsScenarioThe sales department needs a more advanced analysis of buying behavior. The sales staff wants to findout the top three products based on sales revenue for each customer. Therefore, you will need to use theAPPLY operator.The main tasks for this exercise are as follows:1. Write a SELECT statement to retrieve the last two orders for each product.2. Write a SELECT statement that uses the APPLY operator and an inline table-valued function.3. Demonstrate the difference between the CROSS APPLY and OUTER APPLY operators. Task 1: Write a SELECT statement that uses the CROSS APPLY operator to retrieve thelast two orders for each product• Open the project file F:\10774A_Labs\10774A_12_PRJ\10774A_12_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the productid and productname columns from theProduction.Products table. In addition, for each product, retrieve the last two rows from theSales.OrderDetails table based on orderid number.• Use the CROSS APPLY operator and a correlated subquery. Order the result by the column productid.• Execute the written statement and compare the results that you got with the desired results shown inthe file 62 - Lab Exercise 2 - Task 1 Result.txt. Task 2: Write a SELECT statement that uses the CROSS APPLY operator to retrieve thetop three products based on sales revenue for each customer• Execute the provided T-<strong>SQL</strong> code to create the inline table-valued functionfnGetTop3ProductsForCustomer, as you did in the previous module:IF OBJECT_ID('dbo.fnGetTop3ProductsForCustomer') IS NOT NULLDROP FUNCTION dbo.fnGetTop3ProductsForCustomer;GOCREATE FUNCTION dbo.fnGetTop3ProductsForCustomer(@custid AS INT) RETURNS TABLEASRETURNSELECT TOP(3)d.productid,p.productname,SUM(d.qty * d.unitprice) AS totalsalesamountFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidINNER JOIN Production.Products AS p ON p.productid = d.productidWHERE custid = @custidGROUP BY d.productid, p.productnameORDER BY totalsalesamount DESC;


12-28 Using Set Operators• Write a SELECT statement to retrieve the custid and contactname columns from the Sales.Customerstable. Use the CROSS APPLY operator with the dbo.fnGetTop3ProductsForCustomer function toretrieve productid, productname, and totalsalesamount columns for each customer.• Execute the written statement and compare the results that you got with the recommended resultshown in the file 63 - Lab Exercise 2 - Task 2 Result.txt. Remember the number of rows in the results. Task 3: Use the OUTER APPLY operator• Copy the T-<strong>SQL</strong> statement from the previous task and modify it by replacing the CROSS APPLYoperator with the OUTER APPLY operator.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 64 - Lab Exercise 2 - Task 3 Result.txt. Notice that you got more rows than in theprevious task. Task 4: Analyze the OUTER APPLY operator• Copy the T-<strong>SQL</strong> statement from the previous task and modify it by filtering the results to show onlycustomers without products. (Hint: In a WHERE clause, look for any column returned by the inlinetable-valued function that is NULL.)• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 65 - Lab Exercise 2 - Task 4 Result.txt.• What is the difference between the CROSS APPLY and OUTER APPLY operators? Task 5: Remove the created inline table-valued function• Remove the created inline table-valued function by executing the provided T-<strong>SQL</strong> code:IF OBJECT_ID('dbo.fnGetTop3ProductsForCustomer') IS NOT NULLDROP FUNCTION dbo.fnGetTop3ProductsForCustomer;• Execute this code exactly as written inside a query window.Results: After this exercise, you should be able to use the CROSS APPLY and OUTER APPLY operators inyour T-<strong>SQL</strong> statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-29Exercise 3: Writing Queries That Use the EXCEPT and INTERSECT OperatorsScenarioThe marketing department was satisfied with the results from exercise 1, but the staff now needs to seespecific rows from one result set that are not present in the other result set. You will have to writedifferent queries using the EXCEPT and INTERSECT operators.The main tasks for this exercise are as follows:1. Write a SELECT statement to return all customers that bought more than 20 distinct products.2. Write a SELECT statement to retrieve all customers from the USA that did not buy more than 20distinct products.3. Write different T-<strong>SQL</strong> statements to observe the precedence of EXCEPT and INTERSECT operators. Task 1: Write a SELECT statement to return all customers that bought more than 20distinct products• Open the project file F:\10774A_Labs\10774A_12_PRJ\10774A_12_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the custid column from the Sales.Orders table. Filter the resultsto include only customers that bought more than 20 different products (based on the productidcolumn from the Sales.OrderDetails table).• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 72 - Lab Exercise 3 - Task 1 Result.txt. Task 2: Write a SELECT statement to retrieve all customers from the USA, exceptthose that bought more than 20 distinct products• Write a SELECT statement to retrieve the custid column from the Sales.Orders table. Filter the resultsto include only customers from the country USA and exclude all customers from the previous (task 1)result. (Hint: Use the EXCEPT operator and the previous query.)• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 73 - Lab Exercise 3 - Task 2 Result.txt. Task 3: Write a SELECT statement to retrieve customers that spent more than$10,000• Write a SELECT statement to retrieve the custid column from the Sales.Orders table. Filter onlycustomers that have a total sales value greater than $10,000. Calculate the sales value using the qtyand unitprice columns from the Sales.OrderDetails table.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 73 - Lab Exercise 3 - Task 3 Result.txt. Task 4: Write a SELECT statement that uses the EXCEPT and INTERSECT operators• Copy the T-<strong>SQL</strong> statement from task 2. Add the INTERSECT operator at the end of the statement.After the INTERSECT operator, add the T-<strong>SQL</strong> statement from task 3.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the recommended resultsshown in the file 74 - Lab Exercise 3 - Task 4 Result.txt. Notice the total number of rows in the results.• Can you explain in business terms which customers are part of the result?


12-30 Using Set Operators Task 5: Change the operator precedence• Copy the T-<strong>SQL</strong> statement from the previous task and add parentheses around the first two SELECTstatements (from the beginning until the INTERSECT operator).• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the recommended resultshown in the file 75 - Lab Exercise 3 - Task 5 Result.txt. Notice the total number of rows in the results.• Are the results different than the results from task 4? Please explain why.• What is the precedence among the set operators?Results: After this exercise, you should have an understanding of how to use the EXCEPT and INTERSECToperators in T-<strong>SQL</strong> statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 12-31Module ReviewReview Questions1. Which set operator would you use to combine sets if you knew there were no duplicates and wantedbetter performance?2. Which APPLY form will not return rows from the left table if the result of the right table expressionwas empty?3. What is the difference between APPLY and JOIN?


12-32 Using Set Operators


13-1Module 13Using Window Ranking, Offset, and Aggregate FunctionsContents:Lesson 1: Creating Windows with OVER 13-3Lesson 2: Exploring Window Functions 13-15Lab: Using Window Ranking, Offset, and Aggregate Functions 13-26


13-2 Using Window Ranking, Offset, and Aggregate FunctionsModule OverviewMicrosoft® <strong>SQL</strong> Server® implements support for <strong>SQL</strong> windowing operations, which gives you the abilityto define a set of rows and apply several different functions against those rows. Once you have learnedhow to work with windows and window functions, you may find that some types of queries whichappeared to require complex manipulations of data (e.g., self-joins, temporary tables, and otherconstructs) aren't needed to write your reports.ObjectivesAfter completing this module, you will be able to:• Describe the benefits to using window functions.• Restrict window functions to rows defined in an OVER clause, including partitions and frames.• Write queries that use window functions to operate on a window of rows and return ranking,aggregation, and offset comparison results.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-3Lesson 1Creating Windows with OVER<strong>SQL</strong> Server provides a number of window functions, which perform calculations such as ranking,aggregations, and offset comparisons between rows. In order to use these functions, you will need towrite queries that define windows, or sets, of rows. You will use the OVER clause and its related elementsto define the sets for the window functions.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the T-<strong>SQL</strong> components used to define windows, and the relationships between them.• Write queries that use the OVER clause, with partitioning, ordering, and framing to define windows.


13-4 Using Window Ranking, Offset, and Aggregate Functions<strong>SQL</strong> Windowing<strong>SQL</strong> Server provides windows as a method for applying functions to sets of rows. There are manyapplications of this technique that solve common problems in writing T-<strong>SQL</strong> queries. For example, usingwindows allows the easy generation of row numbers in a result set and the calculation of running totals.Windows also provide an efficient way to compare values in one row with values in another without theneed to join a table to itself using an inequality operator.There are several core elements of writing queries that use windows:• Windows allow you to specify an order to rows that will be passed to a window function, withoutaffecting the final order of the query output.• Windows include a partitioning feature, which enables you to specify that you want to restrict afunction only to rows that have the same value as the current row.• Windows provide a framing option. It allows you to specify a further subset of rows within a windowpartition by setting upper and lower boundaries for the window frame, which presents rows to thewindow function.The following example uses an aggregate window function to calculate a running total. This illustrates theuse of these elements:SELECT Category, Qty, Orderyear,SUM(Qty) OVER (PARTITION BY Category ORDER BY OrderyearROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS RunningQtyFROM Sales.CategoryQtyYear;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-5The partial results:Category Qty Orderyear RunningQty--------------- ----- ---------- -----------Beverages 1842 2006 1842Beverages 3996 2007 5838Beverages 3694 2008 9532Condiments 962 2006 962Condiments 2895 2007 3857Condiments 1441 2008 5298Confections 1357 2006 1357Confections 4137 2007 5494Confections 2412 2008 7906Dairy Products 2086 2006 2086Dairy Products 4374 2007 6460Dairy Products 2689 2008 9149In the next few topics of this lesson, you will learn how to use these query elements.


13-6 Using Window Ranking, Offset, and Aggregate FunctionsWindowing ComponentsIn order to use windows and window functions in T-<strong>SQL</strong>, you will always use one of the subclauses thatcreate and manipulate windows: the OVER subclause. Additionally, you may need to create partitions withthe PARTITION BY option, and even further restrict which rows are applied to a function with framingoptions. Therefore, understanding the relationship between these components is vital.The general relationship can be expressed as a sequence, with one element further manipulating the rowsoutput by the previous element:1. The OVER clause determines the result set that will be used by the window function. An OVER clausewith no partition defined is unrestricted. It returns all rows to the function.2. A PARTITION BY clause, if present, restricts the results to those rows that have the same value in thepartitioned columns as the current row. For example, PARTITION BY custid restricts the window torows with the same custid as the current row. PARTITION BY builds on the OVER clause and cannotbe used without OVER. (An OVER clause without a window partition clause is considered onepartition.)3. A ROW or RANGE clause creates a window frame within the window partition, which allows you to seta starting and ending boundary around the rows being operated on. A frame requires an ORDER BYsubclause within the OVER clause.The following example, also seen in the previous topic, aggregates the Qty column against a window inthe OVER clause defined by partitioning on the category column, sorting on the orderyear and framed bya boundary at the first row and a boundary at the current row. This creates a "moving window," whereeach row is aggregated with other rows of the same category value, from the oldest row by orderyear, tothe current row:SELECT Category, Qty, Orderyear,SUM(Qty) OVER (PARTITION BY category ORDER BY OrderyearROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS RunningQtyFROM Sales.CategoryQtyYear;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-7The details of each component will be covered in upcoming topics.Note A single query can use multiple window functions, each with its own OVER clause.Each clause determines its own partitioning, ordering, and framing.


13-8 Using Window Ranking, Offset, and Aggregate FunctionsUsing OVERThe OVER clause defines the window, or set, of rows that will be operated on by a window function, whichwe will look at in the next lesson. The OVER clause includes partitioning, ordering, and framing, whereeach is applicable.Used alone, the OVER clause does not restrict the result set passed to the window function. Used with aPARTITION BY subclause, OVER restricts the set to those rows with the same values in the partitioningelements.For example, the following example shows the use of OVER without an explicit window partition to definean unrestricted window that will be used by the ROW_NUMBER function. All rows will be numbered, usingan ORDER BY clause, which is required by ROW_NUMBER. The row numbers will be displayed in a newcolumn named Running:SELECT Category, Qty, Orderyear,ROW_NUMBER() OVER (ORDER BY Qty DESC) AS RunningFROM Sales.CategoryQtyYearORDER BY Running;The partial result, further ordered by the Running column for display purposes:Category Qty Orderyear Running--------------- ----------- ----------- --Dairy Products 4374 2007 1Confections 4137 2007 2Beverages 3996 2007 3Beverages 3694 2008 4Seafood 3679 2007 5Condiments 2895 2007 6Seafood 2716 2008 7Dairy Products 2689 2008 8Grains/Cereals 2636 2007 9The next topics will build on this basic use of OVER to define a window of rows.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-9For More Information For further reading on the OVER clause, see Books Online athttp://go.microsoft.com/fwlink/?LinkId=242967.


13-10 Using Window Ranking, Offset, and Aggregate FunctionsPartitioning WindowsPartitioning a window limits a set to rows with the same value in the partitioning column. For example,the following code snippet shows the use of PARTITION BY to create a window partition by category. Inthis example, a partition contains only rows with a category of beverages, or a category of confections:() OVER(PARTITION BY Category)As you have learned, if there is no partition defined, then the OVER() clause returns all rows from theunderlying query's result set to the window function.The following example builds on the example you saw in the previous topic. It adds a PARTITION BYsubclause to the OVER clause, creating a window partition for rows with matching Category values. Thisallows the ROW_NUMBER function to number each set of years per category separately. Note that anORDER BY subclause has been added to the OVER clause to provide meaning to ROW_NUMBER:SELECT Category, Qty, Orderyear,ROW_NUMBER() OVER (PARTITION BY Category ORDER BY Qty DESC) AS RunningFROM Sales.CategoryQtyYearORDER BY Category;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-11The partial result:Category Qty Orderyear Running--------------- ----------- ----------- ---Beverages 3996 2007 1Beverages 3694 2008 2Beverages 1842 2006 3Condiments 2895 2007 1Condiments 1441 2008 2Condiments 962 2006 3Confections 4137 2007 1Confections 2412 2008 2Confections 1357 2006 3Note An ORDER BY subclause will also be needed in the OVER clause if you will be addingframing to the window partition, as discussed in the next topic.


13-12 Using Window Ranking, Offset, and Aggregate FunctionsOrdering and FramingAs you have learned, window partitions allow you to define a subset of rows within the outer windowdefined by OVER. In a similar approach, window framing allows you to further restrict the rows availableto the window function. You can think of a frame as a moving window over the data, starting and endingat positions you define.To define window frames, use the ROW or RANGE subclauses and provide a starting and an endingboundary. For example, to set a frame that extends from the first row in the partition to the current row(such as to create a moving window for a running total), follow these steps:1. Define an OVER clause with a PARTITION BY element.2. Define an ORDER BY subclause to the OVER clause. This will cause the concept of "first row" to bemeaningful.3. Add the ROWS BETWEEN subclause, setting the starting boundary using UNBOUNDED PRECEDING.UNBOUNDED means go all the way to the boundary in the direction specified as PRECEDING(before). Add the CURRENT ROW element to indicate the ending boundary is the row beingcalculated.Note Since OVER returns a set, and sets have no order, an ORDER BY subclause is requiredfor the framing operation to be useful. This can be (and typically is) different from ORDERBY, which determines the display order for the final result set.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-13The following example uses framing to create a moving window, where each row is the end of a framestarting with the first row in the window partitioned by category and ordered by year. The SUM functioncalculates an aggregate in each window partition's frame:SELECT Category, Qty, Orderyear,SUM(Qty) OVER (PARTITION BY Category ORDER BY OrderyearROWS BETWEEN UNBOUNDED PRECEDINGAND CURRENT ROW) AS RunningQtyFROM Sales.CategoryQtyYear;The partial results:Category Qty Orderyear RunningQty--------------- ----------- ----------- -----------Beverages 1842 2006 1842Beverages 3996 2007 5838Beverages 3694 2008 9532Condiments 962 2006 962Condiments 2895 2007 3857Condiments 1441 2008 5298Confections 1357 2006 1357Confections 4137 2007 5494Confections 2412 2008 7906Dairy Products 2086 2006 2086Dairy Products 4374 2007 6460Dairy Products 2689 2008 9149


13-14 Using Window Ranking, Offset, and Aggregate FunctionsDemonstration: Using OVER and PartitioningDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_13_PRJ\10774A_13_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-15Lesson 2Exploring Window Functions<strong>SQL</strong> Server <strong>2012</strong> provides window functions to operate on a window of rows. In addition to windowaggregate functions, which you will find to be conceptually similar to grouped aggregate functions, youcan use window ranking, distribution, and offset functions in your queries.Lesson ObjectivesAfter completing this lesson, you will be able to:• Write queries that use window aggregate functions.• Write queries that use window ranking functions.• Write queries that use window offset functions.


13-16 Using Window Ranking, Offset, and Aggregate FunctionsDefining Window FunctionsA window function is a function applied to a window, or set, of rows. Earlier in this course, you learnedabout group aggregate functions such as SUM, MIN, and MAX, which operated on a set of rows definedby a GROUP BY clause. In window operations, you can also use these functions, as well as others, tooperate on a set of rows defined in a window by an OVER clause and its elements.<strong>SQL</strong> Server window functions can be found in the following categories, which will be discussed in thenext topics:• Aggregate functions, such as SUM, which operate on a window and return a single row.• Ranking functions, such as RANK, which depend on a sort order and return a value representing therank of a row with respect to other rows in the window.• Distribution functions, such as CUME_DIST, which calculate the distribution of a value in a windowof rows.• Offset functions, such as LEAD, which return values from other rows relative to the position of thecurrent row.When used in windowing scenarios, these functions depend on the result set returned by the OVER clauseand any further restrictions you provide within OVER, such as partitioning and framing.The following example uses the RANK function to calculate a rank of each row by unitprice, high to lowvalue. Note that there is no explicit window partition clause defined:SELECT productid, productname, unitprice,RANK() OVER(ORDER BY unitprice DESC) AS pricerankFROM Production.ProductsORDER BY pricerank;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-17The partial result:productid productname unitprice pricerank----------- ------------- --------------------- ---------38 Product QDOMO 263.50 129 Product VJXYN 123.79 29 Product AOZBW 97.00 320 Product QHFFP 81.00 418 Product CKEDC 62.50 559 Product UKXRI 55.00 651 Product APITJ 53.00 762 Product WUXYK 49.30 843 Product ZZZHR 46.00 928 Product OFBNT 45.60 1027 Product SMIOH 43.90 1163 Product ICKNK 43.90 118 Product WVJFP 40.00 13For comparison, the following example adds a partition on categoryid (and adds categoryid to the finalORDER BY clause). Note that the ranking is calculated per partition:SELECT categoryid, productid, unitprice,RANK() OVER(PARTITION BY categoryid ORDER BY unitprice DESC) AS pricerankFROM Production.ProductsORDER BY categoryid, pricerank;The partial result, edited for space:categoryid productid unitprice pricerank----------- ----------- --------- ---------1 38 263.50 11 43 46.00 21 2 19.00 32 63 43.90 12 8 40.00 22 61 28.50 32 6 25.00 43 20 81.00 13 62 49.30 23 27 43.90 33 26 31.23 4Notice that the addition of partitioning allows the window function to operate at a more granular levelthan when OVER returns an unrestricted set.Note Repeating values and gaps in the pricerank column are expected when using RANKin case of ties. Use DENSE_RANK if gaps are not desired. See the next topics for moreinformation.


13-18 Using Window Ranking, Offset, and Aggregate FunctionsWindow Aggregate FunctionsWindow aggregate functions are similar to the aggregate functions that you have already used in thiscourse. They aggregate a set of rows and return a single value. However, when used in the context ofwindows, they operate on the set returned by the OVER clause, and not on a set defined by a groupedquery using GROUP BY.Window aggregate functions provide support for windowing elements you have learned about in thismodule, such as partitioning, ordering, and framing. Ordering is not required with aggregate functions,unlike with other window functions, unless you are also specifying a frame.The following example uses a SUM function to return the total sales per customer, displayed as a newcolumn:SELECT custid,ordermonth,qty,SUM(qty) OVER ( PARTITION BY custid ) AS totalpercustFROM Sales.CustOrders;The partial result, edited for space:custid ordermonth qty totalpercust----------- ----------------------- ----------- ------------1 2007-08-01 00:00:00.000 38 1741 2007-10-01 00:00:00.000 41 1741 2008-01-01 00:00:00.000 17 1742 2006-09-01 00:00:00.000 6 632 2007-08-01 00:00:00.000 18 633 2006-11-01 00:00:00.000 24 3593 2007-04-01 00:00:00.000 30 3593 2007-05-01 00:00:00.000 80 3594 2007-02-01 00:00:00.000 40 6504 2007-06-01 00:00:00.000 96 650


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-19While the repeating of the sum may not immediately seem to be useful, you can use any manipulationwith the result of the window aggregate, such as determining ratios of each sale to the total per customer:SELECT custid, ordermonth, qty,SUM(qty) OVER ( PARTITION BY custid ) AS custtotal,CAST(100. * qty/SUM(qty) OVER ( PARTITION BY custid )AS NUMERIC(8,2)) ASOfTotalFROM Sales.CustOrders;The result:custid ordermonthqty custtotal OfTotal------ ----------------------- --- ---------- -------1 2007-08-01 00:00:00.000 38 174 21.841 2007-10-01 00:00:00.000 41 174 23.561 2008-01-01 00:00:00.000 17 174 9.771 2008-03-01 00:00:00.000 18 174 10.341 2008-04-01 00:00:00.000 60 174 34.482 2006-09-01 00:00:00.000 6 63 9.522 2007-08-01 00:00:00.000 18 63 28.572 2007-11-01 00:00:00.000 10 63 15.872 2008-03-01 00:00:00.000 29 63 46.033 2006-11-01 00:00:00.000 24 359 6.693 2007-04-01 00:00:00.000 30 359 8.363 2007-05-01 00:00:00.000 80 359 22.283 2007-06-01 00:00:00.000 83 359 23.123 2007-09-01 00:00:00.000 102 359 28.413 2008-01-01 00:00:00.000 40 359 11.14


13-20 Using Window Ranking, Offset, and Aggregate FunctionsWindow Ranking FunctionsWindow ranking functions return a value representing the rank of a row with respect to other rows in thewindow. To accomplish this, ranking functions require an ORDER BY element within the OVER clause, toestablish the position of each row within the window.Note Remember that the ORDER BY element within the OVER clause affects only theprocessing of rows by the window function. To control the display order of the results, addan ORDER BY clause to the end of the SELECT statement, as with other queries.The primary difference between RANK and DENSE_RANK is the handling of rows when there are tievalues. For example, the following query uses RANK and DENSE_RANK side-by-side to illustrate howRANK inserts a gap in the numbering after a set of tied row values, whereas DENSE_RANK does not:SELECT CatID, CatName, ProdName, UnitPrice,RANK() OVER(PARTITION BY CatID ORDER BY UnitPrice DESC) AS PriceRank,DENSE_RANK() OVER(PARTITION BY CatID ORDER BY UnitPrice DESC) AS DensePriceRankFROM Production.CategorizedProductsORDER BY CatID;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-21The partial results follow. Note the rank numbering of the rows following the products with a unitpriceof 18.00:CatID CatName ProdName UnitPrice PriceRank DensePriceRank----- --------- ------------- --------- --------- --------------1 Beverages Product QDOMO 263.50 1 11 Beverages Product ZZZHR 46.00 2 21 Beverages Product RECZE 19.00 3 31 Beverages Product HHYDP 18.00 4 41 Beverages Product LSOFL 18.00 4 41 Beverages Product NEVTJ 18.00 4 41 Beverages Product JYGFE 18.00 4 41 Beverages Product TOONT 15.00 8 51 Beverages Product XLXQF 14.00 9 61 Beverages Product SWNJY 14.00 9 61 Beverages Product BWRLG 7.75 11 71 Beverages Product QOGNU 4.50 12 8For More Information See “Ranking Functions (Transact-<strong>SQL</strong>)” in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242968.


13-22 Using Window Ranking, Offset, and Aggregate FunctionsWindow Distribution FunctionsWindow distribution functions perform statistical analysis on the rows within the window or windowpartition. Partitioning a window is optional for distribution functions, but ordering is required.Distribution functions return a rank of a row, but instead of being expressed as an ordinal number as withRANK, DENSE_RANK, or ROW_NUMBER, it is expressed as a ratio between 0 and 1. <strong>SQL</strong> Server <strong>2012</strong>provides rank distribution with the PERCENT_RANK and CUME_DIST functions. It provides inversedistribution with the PERCENTILE_CONT and PERCENTILE_DISC functions.Note These functions are listed here for completeness only and are beyond the scopeof this course. For more information, see Books Online at http://go.microsoft.com/fwlink/?LinkId=242969.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-23Window Offset FunctionsWindows offset functions enable access to values located in rows other than the current row. This canenable queries that perform comparisons between rows, without the need to join the table to itself.Offset functions operate on a position that is either relative to the current row, or relative to the startingor ending boundary of the window frame. LAG and LEAD operate on an offset to the current row.FIRST_VALUE and LAST_VALUE operate on an offset from the window frame.Note Since FIRST_VALUE and LAST_VALUE operate on offsets from the window frame, it isimportant to remember to specify framing options other than the default of RANGEBETWEEN UNBOUND PRECEDING AND CURRENT ROW.The following example uses the LEAD function to compare year-over-year sales. The offset is 1, returningthe next row's value. LEAD returns a 0 if a NULL is found in the next row's value, such as when there areno sales past the latest year:SELECT employee, orderyear ,totalsales AS currsales,LEAD(totalsales, 1,0) OVER (PARTITION BY employee ORDER BY orderyear) AS nextsalesFROM Sales.OrdersByEmployeeYearORDER BY employee, orderyear;


13-24 Using Window Ranking, Offset, and Aggregate FunctionsThe partial results:employee orderyear currsales nextsales-------- --------- --------- ---------1 2006 38789.00 97533.581 2007 97533.58 65821.131 2008 65821.13 0.002 2006 22834.70 74958.602 2007 74958.60 79955.962 2008 79955.96 0.003 2006 19231.80 111788.613 2007 111788.61 82030.893 2008 82030.89 0.00


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-25Demonstration: Exploring Windows FunctionsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_13_PRJ\10774A_13_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


13-26 Using Window Ranking, Offset, and Aggregate FunctionsLab: Using Window Ranking, Offset, and AggregateFunctionsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-277. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You have been provided with a set of business requirements for data and youwill write T-<strong>SQL</strong> queries to retrieve the specified data from the databases. To fill these requests, you willneed to calculate ranking values, calculate the difference between two consecutive rows, and calculaterunning totals. You will use window functions to achieve these calculations.Important When comparing your results with the provided sample outputs, the column orderingand total number of affected rows should always match. However, remember that the order of therows in the output of a query without an ORDER BY clause is not guaranteed. Therefore, the order ofthe rows in the sample outputs may be different than yours. Also, the answer outputs includeabbreviated results.


13-28 Using Window Ranking, Offset, and Aggregate FunctionsExercise 1: Writing Queries That Use Ranking FunctionsScenarioThe sales department would like to rank orders by their values for each customer. You will provide thereport by using the RANK function. You will also practice how to add a calculated column to display therow number in the SELECT clause.The main tasks for this exercise are as follows:1. Write a SELECT statement with the ROW_NUMBER function.2. Write a SELECT statement with the RANK function.3. Write a SELECT statement to retrieve different groups of customers. Task 1: Write a SELECT statement that uses the ROW_NUMBER function to create acalculated column• Open the project file F:\10774A_Labs\10774A_13_PRJ\10774A_13_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the orderid, orderdate, and val columns as well as a calculatedcolumn named rowno from the view Sales.OrderValues. Use the ROW_NUMBER function to returnrowno. Order the row numbers by the orderdate column.• Execute the written statement and compare the results that you got with the desired results shown inthe file 52 - Lab Exercise 1 - Task 1 Result.txt. Task 2: Add an additional column using the RANK function• Copy the previous T-<strong>SQL</strong> statement and modify it by including an additional column named rankno.To create rankno, use the RANK function, with the rank order based on the orderdate column.• Execute the modified statement and compare the results that you got with the desired results shownin the file 53 - Lab Exercise 1 - Task 2 Result.txt. Notice the different values in the rowno and ranknocolumns for some of the rows.• What is the difference between the RANK and ROW_NUMBER functions? Task 3: Write a SELECT statement to calculate a rank, partitioned by customer andordered by the order value• Write a SELECT statement to retrieve the orderid, orderdate, custid, and val columns as well as acalculated column named orderrankno from the Sales.OrderValues view. The orderrankno columnshould display the rank per each customer independently, based on val ordering in descending order.• Execute the written statement and compare the results that you got with the desired results shown inthe file 54 - Lab Exercise 1 - Task 3 Result.txt.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-29 Task 4: Write a SELECT statement to rank orders, partitioned by customer and orderyear, and ordered by the order value• Write a SELECT statement to retrieve the custid and val columns from the Sales.OrderValues view.Add two calculated columns:• orderyear as a year of the orderdate column• orderrankno as a rank number, partitioned by the customer and order year, and ordered by theorder value in descending order• Execute the written statement and compare the results that you got with the desired results shown inthe file 55 - Lab Exercise 1 - Task 4 Result.txt. Task 5: Filter only orders with the top two ranks• Copy the previous query and modify it to filter only orders with the first two ranks based on theorderrankno column.• Execute the written statement and compare the results that you got with the desired results shown inthe file 56 - Lab Exercise 1 - Task 5 Result.txt.Results: After this exercise, you should know how to use ranking functions in T-<strong>SQL</strong> statements.


13-30 Using Window Ranking, Offset, and Aggregate FunctionsExercise 2: Writing Queries That Use Offset FunctionsScenarioYou need to provide different reports to analyze the difference between two consecutive rows. This willenable the business users to analyze growth and trends.The main tasks for this exercise are as follows:1. Write a SELECT statement to retrieve the next row using a common table expression (CTE).2. Write a SELECT statement using the LAG and LEAD functions.3. Write a SELECT statement to get the first value from the window frame. Task 1: Write a SELECT statement to retrieve the next row using a common tableexpression (CTE)• Open the project file F:\10774A_Labs\10774A_13_PRJ\10774A_13_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Define a CTE named OrderRows based on a query that retrieves the orderid, orderdate, and valcolumns from the Sales.OrderValues view. Add a calculated column named rowno using theROW_NUMBER function, ordering by the orderdate and orderid columns.• Write a SELECT statement against the CTE and use the LEFT JOIN with the same CTE to retrieve thecurrent row and the previous row based on the rowno column. Return the orderid, orderdate, and valcolumns for the current row and the val column from the previous row as prevval. Add a calculatedcolumn named diffprev to show the difference between the current val and previous val.• Execute the T-<strong>SQL</strong> code and compare the results that you got with the desired results shown in thefile 62 - Lab Exercise 2 - Task 1 Result.txt. Task 2: Write a SELECT statement that uses the LAG function• Write a SELECT statement that uses the LAG function to achieve the same results as the query in theprevious task. The query should not define a CTE.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 63 - Lab Exercise 2 - Task 2 Result.txt.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-31 Task 3: Analyze the sales information for the year 2007• Define a CTE named SalesMonth2007 that creates two columns: monthno (the month number of theorderdate column) and val (aggregated val column). Filter the results to include only the order year2007 and group by monthno.• Write a SELECT statement that retrieves the monthno and val columns from the CTE and adds threecalculated columns:• avglast3months. This column should contain the average sales amount for last three monthsbefore the current month. (Use multiple LAG functions and divide the sum by three.) You canassume that there’s a row for each month in the CTE.• diffjanuary. This column should contain the difference between the current val and the Januaryval. (Use the FIRST_VALUE function.)• nextval. This column should contain the next month value of the val column.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 64 - Lab Exercise 2 - Task 3 Result.txt. Notice that the average amount for last threemonths is not correctly computed because the total amount for the first two months is divided bythree. You will practice how to do this correctly in the next exercise.Results: After this exercise, you should be able to use the offset functions in your T-<strong>SQL</strong> statements.


13-32 Using Window Ranking, Offset, and Aggregate FunctionsExercise 3: Writing Queries That Use Window Aggregate FunctionsScenarioTo better understand the cumulative sales value of a customer through time and to provide the salesanalyst with a year-to-date analysis, you will have to write different SELECT statements that use thewindow aggregate functions.The main tasks for this exercise are as follows:1. Write a SELECT statement to display the contribution of each order value compared to the wholecustomer sales amount.2. Write a SELECT statement to retrieve the running sum of the sales value per customer.3. Write a SELECT statement to retrieve the year-to-date information. Task 1: Write a SELECT statement to display the contribution of each customer’sorder compared to that customer’s total purchase• Open the project file F:\10774A_Labs\10774A_13_PRJ\10774A_13_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the custid, orderid, orderdate, and val columns from theSales.OrderValues view. Add a calculated column named percoftotalcust that contains a percentagevalue of each order sales amount compared to the total sales amount for that customer.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 72 - Lab Exercise 3 - Task 1 Result.txt. Task 2: Add a column to display the running sales total• Copy the previous SELECT statement and modify it by adding a new calculated column named runval.This column should contain a running sales total for each customer based on order date, usingorderid as the tiebreaker.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 73 - Lab Exercise 3 - Task 2 Result.txt. Task 3: Analyze the year-to-date sales amount and average sales amount for the lastthree months• Copy the SalesMonth2007 CTE in the last task in exercise 2. Write a SELECT statement to retrieve themonthno and val columns. Add two calculated columns:• avglast3months. This column should contain the average sales amount for last three monthsbefore the current month using a window aggregate function. You can assume that there are nomissing months.• ytdval. This column should contain the cumulative sales value up to the current month.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 74 - Lab Exercise 3 - Task 3 Result.txt.Results: After this exercise, you should have a basic understanding of how to use window aggregatefunctions in T-<strong>SQL</strong> statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 13-33Module ReviewReview Questions1. What results will be returned by a ROW_NUMBER function if there is no ORDER BY clause in thequery?2. Which ranking function would you use to return the values 1,1,3? Which would return 1,1,2?3. Can a window frame extend beyond the boundaries of the window partition defined in the sameOVER() clause?


13-34 Using Window Ranking, Offset, and Aggregate Functions


14-1Module 14Pivoting and Grouping SetsContents:Lesson 1: Writing Queries with PIVOT and UNPIVOT 14-3Lesson 2: Working with Grouping Sets 14-10Lab: Pivoting and Grouping Sets 14-18


14-2 Pivoting and Grouping SetsModule OverviewThis module discusses more advanced manipulations of data, building on the basics you have learned sofar in the course. First, you will learn how to use the PIVOT and UNPIVOT operators to change theorientation of data from column-oriented to row-oriented and back. Next, you will learn how to use theGROUPING SET subclause of the GROUP BY clause to specify multiple groupings in a single query. Thiswill include the use of the CUBE and ROLLUP subclauses of GROUP BY to automate the setup of groupingsets.ObjectivesAfter completing this module, you will be able to:• Write queries that pivot and unpivot result sets.• Write queries that specify multiple groupings with grouping sets.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-3Lesson 1Writing Queries with PIVOT and UNPIVOTSometimes you may have a need to present data in a different orientation than it is stored in, with respectto row and column layout. For example, some data may be easier to compare if you can arrange valuesacross columns of the same row. In this lesson, you will learn how to use the T-<strong>SQL</strong> PIVOT operator toaccomplish this. You will also learn how to use the UNPIVOT operator to return the data to a rows-basedorientation.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe how pivoting data can be used in T-<strong>SQL</strong> queries.• Write queries that pivot data from rows to columns using the PIVOT operator.• Write queries that unpivot data from columns back to rows using the UNPIVOT operator.


14-4 Pivoting and Grouping SetsWhat Is Pivoting?Pivoting data in <strong>SQL</strong> Server rotates its display from a rows-based orientation to a columns-basedorientation. It does this by consolidating values in a column to a list of distinct values and then projectsthat list across as column headings. Typically this includes aggregation to column values in the newcolumns.For example, the partial source data below lists repeating values for Category and Orderyear, along withvalues for Qty, for each instance of a Category/Orderyear pair:Category Qty Orderyear--------------- ------ -----------Dairy Products 12 2006Grains/Cereals 10 2006Dairy Products 5 2006Seafood 2 2007Confections 36 2007Condiments 35 2007Beverages 60 2007Confections 55 2007Condiments 16 2007Produce 15 2007Dairy Products 60 2007Dairy Products 20 2007Confections 24 2007...Condiments 2 2008(2155 row(s) affected)


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-5To analyze this by category and year, you may want to arrange the values to be displayed as follows,summing the Qty column along the way:Category 2006 2007 2008-------------- ---- ---- ----Beverages 1842 3996 3694Condiments 962 2895 1441Confections 1357 4137 2412Dairy Products 2086 4374 2689Grains/Cereals 549 2636 1377Meat/Poultry 950 2189 1060Produce 549 1583 858Seafood 1286 3679 2716(8 row(s) affected)In the pivoting process, each distinct year was created as a column header, and values in the Qty columnwere grouped by Category and aggregated. This is a very useful technique in many scenarios.For More Information Additional reading can be found in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242971.


14-6 Pivoting and Grouping SetsElements of PIVOTThe T-<strong>SQL</strong> PIVOT table operator, introduced in Microsoft® <strong>SQL</strong> Server® 2005, operates on the output ofthe FROM clause in a SELECT statement. To use PIVOT, you need to supply three elements to theoperator:• Grouping: In the FROM clause, you need to provide the input columns. From those columns, PIVOTwill determine which column(s) will be used to group the data for aggregation. This is based onlooking at which columns are not being used as other elements in the PIVOT operator.• Spreading: You need to provide a comma-delimited list of values to be used as the column headingsfor the pivoted data. The values need to occur in the source data.• Aggregation: You need to provide an aggregation function (SUM, etc.) to be performed on thegrouped rowsAdditionally, you need to assign a table alias to the result table of the PIVOT operator. The followingexample shows the elements in place. In this example, Orderyear is the column providing the spreadingvalues, Qty is used for aggregation, and Category will be used for grouping. Orderyear values areenclosed in delimiters to indicate that they are identifiers of columns in the result:SELECT Category, [2006],[2007],[2008]FROM ( SELECT Category, Qty, Orderyear FROM Sales.CategoryQtyYear) AS DPIVOT(SUM(qty) FOR orderyear IN ([2006],[2007],[2008])) AS pvt;Note Any attributes in the source subquery not used for aggregation or spreading will beused as grouping elements, so be sure that no unnecessary attributes are included in thesubquery.One of the challenges in writing queries using PIVOT is the need to supply a fixed list of spreadingelements to the PIVOT operator, such as the specific order year values above. Later in this course, you willlearn how to write queries generated dynamically, which may help you write PIVOT queries with moreflexibility.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-7Writing Queries with UNPIVOTUnpivoting data is the logical reverse of pivoting data: instead of turning rows into columns, unpivot turnscolumns into rows. This is a technique useful in taking data that has already been pivoted (with or withoutusing a T-<strong>SQL</strong> PIVOT operator) and returning it into a row-oriented tabular display. <strong>SQL</strong> Server providesthe UNPIVOT table operator to accomplish this.When unpivoting data, one or more columns are defined as the source to be converted into rows. Thedata in those columns is spread, or split, into one or more new rows, depending on how many columnsare being unpivoted.In the following source data, three columns will be unpivoted. Each Orderyear value will be copied into anew row and associated with its Category value. Any NULLs will be removed in the process and no rowcreated.Category 2006 2007 2008--------------- ---- ---- ----Beverages 1842 3996 3694Condiments 962 2895 1441Confections 1357 4137 2412Dairy Products 2086 374 2689Grains/Cereals 549 2636 1377Meat/Poultry 950 2189 1060Produce 549 1583 858Seafood 1286 3679 2716


14-8 Pivoting and Grouping SetsFor each intersection of Category and Orderyear, a new row will be created, as in these partial results:category qty orderyear--------------- ---- ---------Beverages 1842 2006Beverages 3996 2007Beverages 3694 2008Condiments 962 2006Condiments 2895 2007Condiments 1441 2008Confections 1357 2006Confections 4137 2007Confections 2412 2008Note Unpivoting does not restore the original data. Detail-level data was lost during theaggregation process in the original pivot. UNPIVOT has no ability to allocate values toreturn to original detail values.To use the UNPIVOT operator, you need to provide three elements:• Source columns to be unpivoted• A name for the new column that will display the unpivoted values• A name for the column that will display the names of the unpivoted valuesNote As with PIVOT, you will define the output of the UNPIVOT table operator as aderived table and provide its name.The following example specifies 2006, 2007, and 2008 as the columns to be unpivoted using the newcolumn name orderyear and the qty values to be displayed in a new qty column. (This technique was usedto generate the sample data in the previous example.)SELECT category, qty, orderyearFROM Sales.PivotedCategorySalesUNPIVOT(qty FOR orderyear IN([2006],[2007],[2008])) AS unpvt;The partial results:category qty orderyear--------------- ----------- ---------Beverages 1842 2006Beverages 3996 2007Beverages 3694 2008Condiments 962 2006Condiments 2895 2007Condiments 1441 2008Confections 1357 2006Confections 4137 2007Confections 2412 2008Dairy Products 2086 2006Dairy Products 4374 2007Dairy Products 2689 2008


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-9Demonstration: Writing Queries with PIVOT and UNPIVOTDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_14_PRJ\10774A_14_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


14-10 Pivoting and Grouping SetsLesson 2Working with Grouping SetsAs you learned earlier in this course, you can use the GROUP BY clause in a SELECT statement to arrangerows in groups, typically to support aggregations. However, if you need to group by different attributes atthe same, for example to report at different levels, you will need multiple queries combined with UNIONALL. <strong>SQL</strong> Server 2008 and later provides the GROUPING SETS subclause to GROUP BY which enablesmultiple sets to be returned in the same query.Lesson ObjectivesAfter completing this lesson, you will be able to:• Write queries using the GROUPING SETS subclause.• Write queries that use ROLLUP AND CUBE.• Write queries that use the GROUPING_ID function.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-11Writing Queries with Grouping SetsIf you need to produce aggregates of multiple groupings in the same query, you can use the GROUPINGSETS subclause of the GROUP BY clause.GROUPING SETS provide an alternative to using UNION ALL to combine results from multiple individualqueries, each with its own GROUP BY clause. With GROUPING SETS, you can specify multiplecombinations of attributes on which to group, as in the following syntax example:SELECT FROM GROUP BYGROUPING SETS((),--one or more columns(),--one or more columns() -- empty parentheses if aggregating all rows);With GROUPING SETS, you can specify which attributes to group on and the order of those attributes. Ifyou instead want to group on any possible combination of attributes, see the topic on CUBE and ROLLUPlater in this lesson.The following example uses GROUPING SETS to aggregate on the Category and Cust columns, as well asthe empty parentheses notation to aggregate all rows:SELECT Category, Cust, SUM(Qty) AS TotalQtyFROM Sales.CategorySalesGROUP BYGROUPING SETS((Category),(Cust),())ORDER BY Category, Cust;


14-12 Pivoting and Grouping SetsThe results:Category Cust TotalQty----------- ---- --------NULL NULL 999NULL 1 80NULL 2 12NULL 3 154NULL 4 241NULL 5 512Beverages NULL 513Condiments NULL 114Confections NULL 372Note the presence of NULLs in the results. NULLs may be returned because a NULL was stored in theunderlying source, or because it is a placeholder in a row generated as an aggregate result. For example,in the previous results, the first row displays NULL, NULL, 999. This represents a grand total row. The NULLin the Category and Cust columns are placeholders since neither Category nor Cust take part in theaggregation.For More Information See Books Online athttp://go.microsoft.com/fwlink/?LinkId=242972.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-13CUBE and ROLLUPLike GROUPING SETS, the CUBE and ROLLUP subclauses also enable multiple groupings for aggregatingdata. However, CUBE and ROLLUP do not need you to specify each set of attributes to group. Instead,given a set of columns, CUBE will determine all possible combinations and output groupings. ROLLUPcreates combinations assuming the input columns represent a hierarchy. Therefore, CUBE and ROLLUPcan be thought of as shortcuts to GROUPING SETS.To use CUBE, append the keyword CUBE to the GROUP BY clause and provide a list of columns to group.For example, to group on all combinations of columns Category and Cust, use the following syntax inyour query:SELECT Category, Cust, SUM(Qty) AS TotalQtyFROM Sales.CategorySalesGROUP BY CUBE(Category,Cust);This will output groupings for the following combinations: (Category, Cust), (Cust, Category), (Cust),(Category) and the aggregate on all empty ().To use ROLLUP, append the keyword ROLLUP to the GROUP BY clause and provide a list of columns togroup. For example, to group on combinations of the Category, Subcategory, and Product columns, usethe following syntax in your query:SELECT Category, Subcategory, Product, SUM(Qty) AS TotalQtyFROM Sales.ProductSalesGROUP BY ROLLUP(Category,Subcategory, Product);


14-14 Pivoting and Grouping SetsThis will output groupings for the following combinations: (Category, Subcategory, Product),(Category, Subcategory), (Category), and the aggregate on all empty (). Note that the order in whichcolumns are supplied is significant: ROLLUP assumes that the columns are listed in an order that expressesa hierarchy.Note The example just given is for illustration only. Object names do not correspond tothe sample database supplied with the course.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-15GROUPING_IDAs you have seen, multiple grouping sets allow you to combine different levels of aggregation in the samequery. You have also seen that <strong>SQL</strong> Server will mark placeholder values with NULL if a row does not takepart in a grouping set. But in a query with multiple sets, how do you know whether a NULL marks aplaceholder or comes from the underlying data? If it marks a placeholder for a grouping set, which set?The GROUPING_ID function can help you provide additional information to answer these questions.For example, consider the following query and results, which contain numerous NULLs:SELECT Category, Cust, SUM(Qty) AS TotalQtyFROM Sales.CategorySalesGROUP BYGROUPING SETS((Category),(Cust),())ORDER BY Category, Cust;Category Cust TotalQty--------------- ----------- --------NULL NULL 999NULL 1 80NULL 2 12NULL 3 154NULL 4 241NULL 5 512Beverages NULL 513Condiments NULL 114Confections NULL 372


14-16 Pivoting and Grouping SetsAt a glance, it may be difficult to determine why a NULL appears in a column. The GROUPING_ID functioncan be used to associate result rows with their grouping sets, as follows:SELECTGROUPING_ID(Category)AS grpCat,GROUPING_ID(Cust) AS grpCust,Category, Cust, SUM(Qty) AS TotalQtyFROM Sales.CategorySalesGROUP BY CUBE(Category,Cust);The partial results:grpCat grpCust Category Cust TotalQty----------- ----------- --------------- ----------- -----------0 0 Beverages 1 360 0 Condiments 1 441 0 NULL 1 800 0 Beverages 2 50 0 Confections 2 71 0 NULL 2 120 0 Beverages 3 1050 0 Condiments 3 40 0 Confections 3 451 0 NULL 3 154...1 1 NULL NULL 9990 1 Beverages NULL 5130 1 Condiments NULL 1140 1 Confections NULL 372As you can see, the GROUPING_ID function returns a 1 when a row is aggregated as part of the currentgrouping set and a 0 when it is not. In the first row, both grpCat and grpCust return 0; therefore, the rowis part of the grouping set (Category, Cust).Note GROUPING_ID can also take multiple columns as inputs and return a unique integerbitmap, comprised of combined bits, per grouping set. For more information, see BooksOnline at http://go.microsoft.com/fwlink/?LinkId=242973. <strong>SQL</strong> Server also provides aGROUPING function, which accepts only one input to return a bit. See “GROUPING(Transact-<strong>SQL</strong>)” in Books Online at http://go.microsoft.com/fwlink/?LinkId=242974.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-17Demonstration: Using Grouping SetsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_14_PRJ\10774A_14_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


14-18 Pivoting and Grouping SetsLab: Pivoting and Grouping SetsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log onmessage” appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-197. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft <strong>SQL</strong> Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You have been provided with a set of business requirements for data and youwill write T-<strong>SQL</strong> queries to retrieve the specified data from the databases. The business requests areanalytical in nature. To fill those requests, you will need to provide crosstab reports and multipleaggregates based on different granularities. Therefore, you will need to use pivoting techniques andgrouping sets in your T-<strong>SQL</strong> code.Important When comparing your results with the provided sample outputs, the column orderingand total number of affected rows should always match. However, remember that the order of therows in the output of a query without an ORDER BY clause is not guaranteed. Therefore, the order ofthe rows in the sample outputs may be different than yours. Also, the answer outputs includeabbreviated results.


14-20 Pivoting and Grouping SetsExercise 1: Writing Queries That Use the PIVOT OperatorScenarioThe sales department would like to have a crosstab report displaying the number of customers for eachcustomer group and country. They would like to display each customer group as a new column. You willwrite different SELECT statements using the PIVOT operator to achieve the needed result.The main tasks for this exercise are as follows:1. Write a SELECT statement to retrieve the number of customers for a specific group of customers.2. Write a SELECT statement to better understand the PIVOT operator.3. Write a SELECT statement to retrieve the sales revenue for each customer for each product category. Task 1: Write a SELECT statement to retrieve the number of customers for a specificcustomer group• Open the project file F:\10774A_Labs\10774A_14_PRJ\10774A_14_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• The IT department has provided you with T-<strong>SQL</strong> code to generate a view named Sales.CustGroups,which contains three pieces of information about customers: their IDs, the countries in which they arelocated, and the customer group in which they have been placed. Customers are placed into one ofthree predefined customers groups (A, B, or C).• Execute the provided T-<strong>SQL</strong> code:CREATE VIEW Sales.CustGroups ASSELECTcustid,CHOOSE(custid % 3 + 1, N'A', N'B', N'C') AS custgroup,countryFROM Sales.Customers;• Write a SELECT statement that will return the custid, custgroup, and country columns from the newlycreated Sales.CustGroups view.• Execute the written statement and compare the results that you got with the desired results shown inthe file 52 - Lab Exercise 1 - Task 1_1 Result.txt.• Modify the SELECT statement. Begin by retrieving the column country. Then use the PIVOT operatorto retrieve three columns based on the possible values of the custgroup column (values A, B, and C),showing the number of customers in each group.• Execute the modified statement and compare the results that you got with the desired results shownin the file 53 - Lab Exercise 1 - Task 1_2 Result.txt.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-21 Task 2: Specify the grouping element for the PIVOT operator• The IT department has provided T-<strong>SQL</strong> code to add two new columns—city and contactname—to theSales.CustGroups view. Execute the provided T-<strong>SQL</strong> code:ALTER VIEW Sales.CustGroups ASSELECTcustid,CHOOSE(custid % 3 + 1, N'A', N'B', N'C') AS custgroup,country,city,contactnameFROM Sales.Customers;• Copy the last SELECT statement in task 1 and execute it.• Is this result the same as the result from the query in task 1? Is the number of rows retrieved thesame?• To better understand the reason for the different results, modify the copied SELECT statement toinclude the new city and contactname columns.• Execute the modified statement and compare the results that you got with the desired results shownin the file 54 - Lab Exercise 1 - Task 2 Result.txt.• Notice that this query returned the same number of rows as the previous SELECT statement. Why didyou get the same result with and without specifying the grouping columns for the PIVOT operator? Task 3: Use a common table expression (CTE) to specify the grouping element forthe PIVOT operator• Define a CTE named PivotCustGroups based on a query that retrieves the custid, country, andcustgroup columns from the Sales.CustGroups view. Write a SELECT statement against the CTE, usinga PIVOT operator to retrieve the same result as in task 1.• Execute the written T-<strong>SQL</strong> code and compare the results that you got with the desired results shownin the file 55 - Lab Exercise 1 - Task 3 Result.txt.• Is this result the same as the one returned by the last query in task 1? Can you explain why?• Why do you think it is beneficial to use the CTE when using the PIVOT operator?


14-22 Pivoting and Grouping Sets Task 4: Write a SELECT statement to retrieve the total sales amount for eachcustomer and product category• For each customer, write a SELECT statement to retrieve the total sales amount for each productcategory. Display each product category as a separate column. Here is how to accomplish this task:• Create a CTE named SalesByCategory to retrieve the custid column from the Sales.Orders table asa calculated column based on the qty and unitprice columns and the categoryname column fromthe table Production.Categories. Filter the result to include only orders in the year 2008.• You will need to JOIN tables Sales.Orders, Sales.OrderDetails, Production.Products, andProduction.Categories.• Write a SELECT statement against the CTE that returns a row for each customer (custid) and acolumn for each product category, with the total sales amount for the current customer andproduct category.• Display the following product categories: Beverages, Condiments, Confections, [Dairy Products],[Grains/Cereals], [Meat/Poultry], Produce, and Seafood.• Execute the complete T-<strong>SQL</strong> code (the CTE and the SELECT statement).• Observe and compare the results that you got with the desired results shown in the file 56 - LabExercise 1 - Task 4 Result.txt.Results: After this exercise, you should be able to use the PIVOT operator in T-<strong>SQL</strong> statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-23Exercise 2: Writing Queries That Use the UNPIVOT OperatorScenarioYou will now create multiple rows by turning columns into rows.The main task for this exercise is as follows:1. Write a SELECT statement to unpivot the source columns. Task 1: Create and query the Sales.PivotCustGroups view• Open the project file F:\10774A_Labs\10774A_14_PRJ\10774A_14_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Execute the provided T-<strong>SQL</strong> code to generate the Sales.PivotCustGroups view:CREATE VIEW Sales.PivotCustGroups ASWITH PivotCustGroups AS(SELECTcustid,country,custgroupFROM Sales.CustGroups)SELECTcountry,p.A,p.B,p.CFROM PivotCustGroupsPIVOT (COUNT(custid) FOR custgroup IN (A, B, C)) AS p;• Write a SELECT statement to retrieve the country, A, B, and C columns from the Sales.PivotCustGroupsview.• Execute the written statement and compare the results that you got with the desired results shown inthe file 62 - Lab Exercise 2 - Task 1 Result.txt. Task 2: Write a SELECT statement to retrieve a row for each country andcustomer group• Write a SELECT statement against the Sales.PivotCustGroups view that returns the following:• A row for each country and customer group.• The column country.• Two new columns—custgroup and numberofcustomers. The custgroup column should hold thenames of the source columns A, B, and C as character strings, and the numberofcustomerscolumn should hold their values (i.e., number of customers).• Execute the T-<strong>SQL</strong> code and compare the results that you got with the recommended results shownin the file 63 - Lab Exercise 2 - Task 2 Result.txt.


14-24 Pivoting and Grouping Sets Task 3: Remove the created views• Remove the created views by executing the provided T-<strong>SQL</strong> code:DROP VIEW Sales.CustGroups;DROP VIEW Sales.PivotCustGroups;Execute this code exactly as written inside a query window.Results: After this exercise, you should know how to use the UNPIVOT operator in your T-<strong>SQL</strong> statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-25Exercise 3: Writing Queries That Use the GROUPING SETS, CUBE, andROLLUP SubclausesScenarioYou have to prepare SELECT statements to retrieve a unified result set with aggregated data for differentcombination of columns. First, you have to retrieve the number of customers for all possible combinationsof the country and city columns. Instead of using multiple T-<strong>SQL</strong> statements with a GROUP BY clause andthen unifying them with the UNION ALL operator, you will use a more elegant solution using theGROUPING SETS subclause of the GROUP BY clause.The main tasks for this exercise are as follows:1. Write a SELECT statement to return multiple grouping sets for counting the number of customers.2. Write a SELECT statement to retrieve all possible grouping sets for determining sales amounts basedon yearly, monthly, and daily values.3. Write SELECT statements to see the difference between the CUBE and ROLLUP subclauses. Task 1: Write a SELECT statement that uses the GROUPING SETS subclause to returnthe number of customers for different grouping sets• Open the project file F:\10774A_Labs\10774A_14_PRJ\10774A_14_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement against the Sales.Customers table and retrieve the country column, the citycolumn, and a calculated column noofcustomers as a count of customers. Retrieve multiple groupingsets based on the country and city columns, the country column, the city column, and a column withan empty grouping set.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 72 - Lab Exercise 3 - Task 1 Result.txt. Task 2: Write a SELECT statement that uses the CUBE subclause to retrieve groupingsets based on yearly, monthly, and daily sales values• Write a SELECT statement against the view Sales.OrderValues and retrieve these columns:• Year of the orderdate column as orderyear• Month of the orderdate column as ordermonth• Day of the orderdate column as orderday• Total sales value using the val column as salesvalue• Return all possible grouping sets based on the orderyear, ordermonth, and orderday columns.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 73 - Lab Exercise 3 - Task 2 Result.txt. Notice the total number of rows in yourresults.


14-26 Pivoting and Grouping Sets Task 3: Write the same SELECT statement using the ROLLUP subclause• Copy the previous query and modify it to use the ROLLUP subclause instead of the CUBE subclause.• Execute the modified query and compare the results that you got with the recommended resultsshown in the file 74 - Lab Exercise 3 - Task 3 Result.txt. Notice the number of rows in your results.• What is the difference between the ROLLUP and CUBE subclauses?• Which is the more appropriate subclause to use in this example? Task 4: Analyze the total sales value by year and month• Write a SELECT statement against the Sales.OrderValues view and retrieve these columns:• Calculated column with the alias groupid (use the GROUPING_ID function with the order yearand order month as the input parameters)• Year of the orderdate column as orderyear• Month of the orderdate column as ordermonth• Total sales value using the val column as salesvalue• Since year and month form a hierarchy, return all interesting grouping sets based on theorderyear and ordermonth columns and sort the result by groupid, orderyear, and ordermonth.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 75 - Lab Exercise 3 - Task 4 Result.txt.Results: After this exercise, you should have an understanding of how to use the GROUPING SETS, CUBE,and ROLLUP subclauses in T-<strong>SQL</strong> statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 14-27Module ReviewReview Questions1. Once a dataset has been pivoted with aggregation, can the original detail rows be restored with anunpivot operation?2. What are the possible sources of NULLs returned by a query using grouping sets to createaggregations?3. Which subclause infers a hierarchy of columns to create meaningful grouping sets?


14-28 Pivoting and Grouping Sets


15-1Module 15<strong>Querying</strong> <strong>SQL</strong> Server MetadataContents:Lesson 1: <strong>Querying</strong> System Catalog Views and Functions 15-3Lesson 2: Executing System Stored Procedures 15-11Lesson 3: <strong>Querying</strong> Dynamic Management Objects 15-19Lab: <strong>Querying</strong> <strong>SQL</strong> Server Metadata 15-25


15-2 <strong>Querying</strong> <strong>SQL</strong> Server MetadataModule OverviewIn this course, you have learned how to retrieve data from user tables and objects. Whether you plan towrite reports or to continue learning Microsoft® <strong>SQL</strong> Server® development and administration, you willfind it useful to query <strong>SQL</strong> Server for server metadata. When writing queries, it is sometimes necessaryto learn which columns are in a particular table, what their data types are, or what collation is used by astring column. You may not have convenient access to a graphical tool such as <strong>SQL</strong> Server ManagementStudio (SSMS); however, if you can send queries to <strong>SQL</strong> Server, you can retrieve the same information thatSSMS displays. After all, SSMS is simply issuing metadata queries on your behalf in order to display its viewof a server or a database.<strong>SQL</strong> Server provides access to structured metadata through a variety of mechanisms, such as systemcatalog views, system functions, dynamic management objects, and system stored procedures. In thismodule, you will learn how to write queries to return system metadata using these mechanisms.ObjectivesAfter completing this module, you will be able to:• Write queries that retrieve system metadata using system views and functions.• Execute system stored procedures to return system information.• Write queries that retrieve system metadata and state information using system dynamicmanagement views and functions.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-3Lesson 1<strong>Querying</strong> System Catalog Views and Functions<strong>SQL</strong> Server provides a common interface to system metadata through a set of views, which you mayquery using standard T-<strong>SQL</strong> SELECT statements. By using regular relational views, you may choose whichattributes you want to display, join views to form a more complete picture of the system, and set a sortorder, just as you would with data stored in user tables.ObjectivesAfter completing this lesson, you will be able to:• Write queries that retrieve system metadata using system catalog views.• Write queries that retrieve system metadata using standard information schema views.• Write queries that retrieve system metadata using system functions.


15-4 <strong>Querying</strong> <strong>SQL</strong> Server MetadataSystem Catalog ViewsSystem catalog views contain information about the catalog, or inventory of objects, in a <strong>SQL</strong> Serversystem. These views hold a wide range of metadata of interest to developers, administrators, and reportwriters. This lesson is intended to provide an introduction to system catalog views and is not meant toprovide a comprehensive listing of all system views.In past versions of <strong>SQL</strong> Server, Microsoft has made an effort to consolidate access to system metadatainto system catalog views. In the past, users have had to query an assortment of documented andundocumented system tables, system views, and system functions. In the current version of <strong>SQL</strong> Server,all user-accessible catalog metadata can now be found by querying catalog views.Since you are querying relational views, you may use any of the techniques you have learned in thiscourse to query the system data. For example, the following query retrieves a list of user tables andattributes from the system catalog view sys.tables:USE T<strong>SQL</strong><strong>2012</strong>;GOSELECT name, object_id, principal_id, schema_id,parent_object_id, type, type_descFROM sys.tables;


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-5The partial results are:name object_id principal_id schema_id parent_object_id type type_desc-------------- ----------- ------------ ----------- ---------------- ---- ----------Employees 245575913 NULL 5 0 U USER_TABLESuppliers 309576141 NULL 6 0 U USER_TABLECategories 341576255 NULL 6 0 U USER_TABLEProducts 373576369 NULL 6 0 U USER_TABLECustomers 485576768 NULL 7 0 U USER_TABLEShippers 517576882 NULL 7 0 U USER_TABLEOrders 549576996 NULL 7 0 U USER_TABLEOrderDetails 645577338 NULL 7 0 U USER_TABLETests 805577908 NULL 8 0 U USER_TABLEScores 837578022 NULL 8 0 U USER_TABLENums 901578250 NULL 1 0 U USER_TABLEProductCatalog 1221579390 NULL 7 0 U USER_TABLENote that some of the columns reference ID values that are foreign key references to other system tables.Since other system tables are exposed via system views, you can join the sys.tables view to other views. Forexample, the following query joins the sys.tables view with the sys.schemas view to resolve schema IDsinto schema names:SELECT s.name AS schemaname, t.name AS tablename, t.object_id, type_desc, create_dateFROM sys.tables AS t JOIN sys.schemas AS s ON t.schema_id = s.schema_idORDER BY schemaname, tablename;The partial results are:schemaname tablename object_id type_desc create_date---------- -------------- ----------- ---------- -----------------------dbo Nums 901578250 USER_TABLE <strong>2012</strong>-02-20 21:07:41.407dbo sysdiagrams 1061578820 USER_TABLE <strong>2012</strong>-02-20 21:11:43.590HR Employees 245575913 USER_TABLE <strong>2012</strong>-02-20 21:07:40.070Production Categories 341576255 USER_TABLE <strong>2012</strong>-02-20 21:07:40.093Production Products 373576369 USER_TABLE <strong>2012</strong>-02-20 21:07:40.097Production Suppliers 309576141 USER_TABLE <strong>2012</strong>-02-20 21:07:40.090Sales Customers 485576768 USER_TABLE <strong>2012</strong>-02-20 21:07:40.100Sales OrderDetails 645577338 USER_TABLE <strong>2012</strong>-02-20 21:07:40.113Sales Orders 549576996 USER_TABLE <strong>2012</strong>-02-20 21:07:40.107Sales ProductCatalog 1221579390 USER_TABLE <strong>2012</strong>-02-20 21:12:54.267Sales Shippers 517576882 USER_TABLE <strong>2012</strong>-02-20 21:07:40.107Stats Scores 837578022 USER_TABLE <strong>2012</strong>-02-20 21:07:40.120Stats Tests 805577908 USER_TABLE <strong>2012</strong>-02-20 21:07:40.117Later in this module, you will also learn how to use a system function to decode the schema name as wellas the object_id column.For More Information A list of frequently asked questions (FAQs) about which systemcatalog object can be used to find certain data is available at http://go.microsoft.com/fwlink/?LinkId=242975.


15-6 <strong>Querying</strong> <strong>SQL</strong> Server MetadataInformation Schema ViewsLike system catalog views, information schema views may be queried to return system metadata. Providedto conform with standards, information schema views are useful to third-party tools that may not bewritten specifically for use with <strong>SQL</strong> Server. When deciding whether to query <strong>SQL</strong> Server-specific systemviews or information schema views, consider the following about information schema views:• They are stored in their own schema, INFORMATION_SCHEMA. <strong>SQL</strong> Server system views appear in thesys schema.• They typically use standard terminology instead of <strong>SQL</strong> Server terms. For example, they use “catalog”instead of “database” and “domain” instead of “user-defined data type.” So, you need to adjust yourqueries accordingly.• They may not expose all the metadata available to <strong>SQL</strong> Server's own catalog views. For example,sys.columns includes attributes for the identity property and computed column property, whileINFORMATION_SCHEMA.columns does not.To query an information schema view, you use a SELECT statement, as you would with any relational view.For example, the following code queries the INFORMATION_SCHEMA.TABLES view in the T<strong>SQL</strong><strong>2012</strong>sample database:SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPEFROM INFORMATION_SCHEMA.TABLES;


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-7The partial results are:For More Information For more details about information schema views, see BooksOnline at http://go.microsoft.com/fwlink/?LinkId=233866.


15-8 <strong>Querying</strong> <strong>SQL</strong> Server MetadataSystem Metadata FunctionsIn addition to views, <strong>SQL</strong> Server provides a number of built-in functions that return metadata to a query.These include scalar functions and table-valued functions, which can return information about systemsettings, session options, and a wide range of objects.<strong>SQL</strong> Server metadata functions come in a variety of formats. Some appear similar to standard scalarfunctions, such as ERROR_NUMBER(). Others use special prefixes, such as @@VERSION or $PARTITION. Asyou become familiar with and start to use metadata functions, you should consult <strong>SQL</strong> Server BooksOnline to determine the format of the functions you need to query.Some common system metadata functions include:Function Name Description ExampleOBJECT_ID()OBJECT_NAME()@@ERRORSERVERPROPERTY()Returns the object ID of adatabase object.Returns the namecorresponding to an object ID.Returns 0 if the last statementsucceeded; otherwise returnsthe error number.Returns the value of thespecified server property.OBJECT_ID('Sales.Customer')OBJECT_NAME(197575742)@@ERRORSERVERPROPERTY('Collation')You use a standard SELECT statement to query a system metadata function. You can include the functionin a WHERE clause or in the SELECT clause, as this query shows:SELECT SERVERPROPERTY('EDITION') AS <strong>SQL</strong>Edition;


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-9This query returns:<strong>SQL</strong>Edition--------------------------Developer Edition (64-bit)For More Information For more information about SERVERPROPERTY, including theproperties it returns, see Books Online at http://go.microsoft.com/fwlink/?LinkId=242976.


15-10 <strong>Querying</strong> <strong>SQL</strong> Server MetadataDemonstration: <strong>Querying</strong> System Catalog Views and FunctionsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_15_PRJ\10774A_15_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-11Lesson 2Executing System Stored ProceduresIn addition to views and functions, <strong>SQL</strong> Server provides system metadata through system storedprocedures. In this lesson, you will learn how to execute system stored procedures to return informationabout the system. First, you will learn the fundamentals needed to execute any stored procedure, andthen you will apply that knowledge to execute system stored procedures.ObjectivesAfter completing this lesson, you will be able to:• Describe how <strong>SQL</strong> Server stored procedures are executed.• Write queries that retrieve system metadata using system stored procedures.


15-12 <strong>Querying</strong> <strong>SQL</strong> Server MetadataExecuting Stored Procedures<strong>SQL</strong> Server exposes metadata through views, functions, and system stored procedures. Earlier in thiscourse, you learned how to access data through views and functions. In this lesson, you will learn how toaccess stored procedures and return metadata. However, the topic covers only the basics of working withstored procedures. Later in the course, you will learn more about creating basic stored procedures andexecuting them to retrieve user data.Like views and user-defined functions, stored procedures are objects whose definitions are stored ina database. However, unlike views and user-defined functions, stored procedures cannot be directlyinvoked from a SELECT statement or an expression. Instead, you invoke the procedure using the EXECUTEcommand, providing the name and any parameters if they exist. You may also use EXEC as a shortcut forEXECUTE. For example, to invoke the system metadata procedure sys.sp_databases, you can use thefollowing command:EXEC sys.sp_databases;The sys.sp_databases procedure returns a list of databases on the server, similar to the sys.databasescatalog view. Partial results appear as:


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-13Note that sys.sp_databases does not provide nearly as many attributes as sys.databases. When you areselecting objects to query, you may want to compare the metadata returned by system views to themetadata returned by system procedures. In addition, keep in mind that the output of stored procedurescannot be directly sorted or filtered, nor can columns be selected as they can when querying a view. Youmay find that system procedures are less flexible than their corresponding system catalog views (whenthey exist).Some system stored procedures accept input parameters. To pass parameters to a stored procedure,you supply the parameters in a comma-separated list after the name of the procedure. For example, toretrieve metadata about a user table, you can call sys.sp_help, which takes the name of the object as aparameter:EXEC sys.sp_help @objname = N'Sales.Customers';If there are multiple parameters, you may list them in the order in which they are defined in theprocedure's definition, or you may provide named pairs of parameters and values. For example, thefollowing two queries each provide a valid way of invoking the system stored procedure sys.sp_tables.However, the second method is considered the best practice:EXEC sys.sp_tables 'Customers', 'Sales';EXEC sys.sp_tables @table_name='Customers', @table_owner='Sales';For More Information For more details on executing stored procedures, see the nextmodule or see Books Online at http://go.microsoft.com/fwlink/?LinkId=242977.


15-14 <strong>Querying</strong> <strong>SQL</strong> Server MetadataExecuting System Stored ProceduresNow that you have learned the basics of executing any stored procedure, here are some considerationsfor using system stored procedures for accessing metadata:• <strong>SQL</strong> Server stores the definitions of system stored procedures in a hidden resource database. Systemprocedures appear to be stored in each user and system database; however, this is a logical view only.They are not copied into user databases but rather accessible from them without specifying theresource database by name.• Most system stored procedures are marked with a sp_ prefix.• Always use EXECUTE or its shortcut EXEC to invoke a system stored procedure.• Include the sys schema name when invoking a system stored procedure.• Name each parameter and specify its appropriate data type, such as Unicode character string (markedwith the N' prefix).For example, if you want to execute a system metadata procedure that returns information about thecolumns in a table, you would use sys.sp_columns in a query like this:EXEC sys.sp_columns @table_name=N'Customers', @table_owner=N'Sales';


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-15In the following partial results, some of the columns have been removed for print:Note As you learned earlier, you cannot directly filter the results of a stored procedurewith a WHERE clause, nor can you choose which columns you want to return. Considerusing a system catalog view (when a suitable one exists) if you need to customize theresults.


15-16 <strong>Querying</strong> <strong>SQL</strong> Server MetadataCommon System Stored Procedures<strong>SQL</strong> Server provides numerous system stored procedures, many of which perform administrative tasks.The list of metadata-related procedures includes general help procedures, such as sys.sp_help andsys.sp_helplanguage, as well as more specific procedures, such as sys.sp_tables and sys.sp_columns.For example, the sys.sp_helplanguage procedure provides information about date usage in varioussupported languages. To execute it, you would run the query:EXEC sys.sp_helplanguage;This query returns the following partial result set, cropped for print:


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-17Note Before trying out new procedures, be sure that you are executing metadata retrievalprocedures only, especially if you have administrative or elevated permissions on your <strong>SQL</strong>Server instance. There is no undo command in T-<strong>SQL</strong>!For More Information For a list of system catalog stored procedures, see Books Onlineat http://go.microsoft.com/fwlink/?LinkId=242978.


15-18 <strong>Querying</strong> <strong>SQL</strong> Server MetadataDemonstration: Executing System Stored ProceduresDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_15_PRJ\10774A_15_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-19Lesson 3<strong>Querying</strong> Dynamic Management ObjectsBeginning with <strong>SQL</strong> Server 2005 and continuing into the current version, Microsoft has made an effortto consolidate and standardize system metadata and state information into a consistent set of views andfunctions called dynamic management objects. As with system stored procedures, most of these systemviews and functions are intended for administrative and development work. However, they can also beused by reports and applications that need to return metadata. In this lesson, you will learn how to usedynamic management objects.ObjectivesAfter completing this lesson, you will be able to:• Describe the use of dynamic management objects for returning <strong>SQL</strong> Server metadata and stateinformation.• Write queries that retrieve system metadata using dynamic management views and functions.


15-20 <strong>Querying</strong> <strong>SQL</strong> Server MetadataAbout Dynamic Management Objects<strong>SQL</strong> Server <strong>2012</strong> provides nearly 200 dynamic management objects that return server and database stateinformation. Although the dynamic management objects include dynamic management functions, theobjects are generally referred to as dynamic management views (DMVs) to avoid confusion with DatabaseManagement Objects (DMOs), an older <strong>SQL</strong> Server technology.When planning the use of dynamic management objects in your queries, consider the followingguidelines:• Like system stored procedures, the definitions of DMVs are stored in the hidden resource databaseand appear logically in each database on a <strong>SQL</strong> Server instance.• DMVs are defined with a server scope or database scope, depending on the metadata being accessed.To query DMVs, you must have been granted VIEW SERVER STATE or VIEW DATABASE STATEpermission, depending on the scope of the DMV.• DMVs can be implemented as views or as table-valued functions. If a DMV is a view, it will not takeparameters. If it is a function, parameters may be required. Check the documentation for the DMVyou wish to use for its requirements.• Microsoft has adapted DMVs to address the changing functionality with each new version of<strong>SQL</strong> Server. Columns are added or dropped to reflect this. Therefore, avoid writing queries that useSELECT * to return all columns from a system DMV to avoid maintenance problems with the code inthe future.For More Information Additional reading can be found in Books Online athttp://go.microsoft.com/fwlink/?LinkId=233868.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-21Categorizing DMVsWhen looking through the list of DMVs in SSMS or <strong>SQL</strong> Server Books Online, note that there is a namingconvention that helps organize the DMVs by function. After the dm_ prefix, you will see a short descriptiveportion of the name. This descriptor places the DMV into a functional category, such as ”db” for databaserelated,“tran” for transaction-related, or ”exec” for query execution-related metadata.Within each grouping you will find one or more DMVs that provide detailed state or metadatainformation from the system. To query a DMV, you use a SELECT statement, as you would any userdefinedview or table-valued function. You may further manipulate the results of the DMV, such as joiningit to another DMV, view, or table, or filtering it with a WHERE clause. For examples, see the followingtopic.Note Most of the DMVs require additional knowledge about <strong>SQL</strong> Server development andadministration, which will be covered in Microsoft course 10775: Administering Microsoft®<strong>SQL</strong> Server® <strong>2012</strong> Databases and course 10776: Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong>Databases. However, the DMVs themselves are documented in Books Online athttp://go.microsoft.com/fwlink/?LinkId=233868.


15-22 <strong>Querying</strong> <strong>SQL</strong> Server Metadata<strong>Querying</strong> Dynamic Management Views and FunctionsTo query a dynamic management object, you use a SELECT statement as you would any user-defined viewor table-valued function. For example, the following query returns a list of current user connections fromthe sys.dm_exec_sessions view:SELECT session_id, login_time, program_nameFROM sys.dm_exec_sessionsWHERE is_user_process =1;Here is a sample result:The following code queries sys.dm_sql_referencing_entities, a table-valued dynamic management functionthat returns metadata about objects whose definitions reference the supplied object. Since this is afunction, parameters are supplied:SELECT referencing_schema_name, referencing_entity_name,referencing_class_descFROM sys.dm_sql_referencing_entities('Sales.Orders', 'OBJECT');


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-23When run in the T<strong>SQL</strong><strong>2012</strong> sample database, the query returns views that depend on the Sales.Orderstable, as these results shows:referencing_schema_name referencing_entity_name referencing_class_desc----------------------- ----------------------- ----------------------Sales CustOrders OBJECT_OR_COLUMNSales EmpOrders OBJECT_OR_COLUMNSales OrdersByEmployeeYear OBJECT_OR_COLUMNSales OrderTotalsByYear OBJECT_OR_COLUMNSales OrderValues OBJECT_OR_COLUMN(5 row(s) affected)


15-24 <strong>Querying</strong> <strong>SQL</strong> Server MetadataDemonstration: <strong>Querying</strong> Dynamic Management ObjectsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_15_PRJ\10774A_15_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 31 – Demonstration C.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-25Lab: <strong>Querying</strong> <strong>SQL</strong> Server MetadataLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


15-26 <strong>Querying</strong> <strong>SQL</strong> Server Metadata7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Expand the Options button, and then under the Connection Properties expand Connect todatabase drop-down list box and select . Choose Yes when prompted for theconnection to the database and then under User Databases, select T<strong>SQL</strong><strong>2012</strong> database and thenclick OK.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft <strong>SQL</strong> Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a business analyst for Adventure Works who will be creating reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You need to determine where the data required by your reports is located aswell as determine other system characteristics. You will be writing queries against system objects in orderto gather the required metadata.Important When comparing your results with the provided sample outputs, the column orderingand the total number of affected rows should always match. However, remember that the order of therows in the output of a query without an ORDER BY clause is not guaranteed. Therefore, the order ofthe rows in the sample outputs may be different than yours. Also, the answer outputs includeabbreviated results.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-27Exercise 1: <strong>Querying</strong> System Catalog ViewsScenarioYou will practice how to retrieve information about database objects (especially tables and views) andhow to get information about columns from the system catalog views.The main tasks for this exercise are as follows:1. Write a SELECT statement to retrieve all databases in <strong>SQL</strong> Server.2. Write a couple of SELECT statements to retrieve the information about tables, views, and columns. Task 1: Write a SELECT statement to retrieve all databases• Open the project file F:\10774A_Labs\10774A_15_PRJ\10774A_15_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement that will return the name, dbid, and crdate columns from the viewsys.sysdatabases.• Execute the SELECT statement and compare the results that you got with the desired results shownin the file 52 - Lab Exercise 1 - Task 1 Result.txt. Your result may be different depending on thedatabases that exist on the server you are connected to and on your user rights. The desired resultswere produced by a user with a sysadmin server role. Task 2: Write a SELECT statement to retrieve all user-defined tables in theT<strong>SQL</strong><strong>2012</strong> database• Write a SELECT statement to retrieve all database objects by selecting the object_id, name, schema_id,type, type_desc, create_date, and modify_date columns from the sys.objects table.• Execute the SELECT statement and compare the results that you got with the desired results shown inthe file 53 - Lab Exercise 1 - Task 2_1 Result.txt.• Write a SELECT statement to retrieve all the distinct object types by selecting the type and type_desccolumns in the sys.objects table. Order the results by the type_desc column.• Execute the SELECT statement and compare the results that you got with the desired results shown inthe file 54 - Lab Exercise 1 - Task 2_2 Result.txt. In the type_desc column, find a row with the valueUSER_TABLE. In that row, notice the value in the type column.• Copy the first query in this task and modify it to filter only user-based tables.• Execute the modified query and compare the results that you got with the desired results shown inthe file 55 - Lab Exercise 1 - Task 2_3 Result.txt.


15-28 <strong>Querying</strong> <strong>SQL</strong> Server Metadata Task 3: Use a different approach to retrieve all user-defined tables in theT<strong>SQL</strong><strong>2012</strong> database• Write a SELECT statement against the sys.tables view to show all user-defined tables. Retrieve thesame columns as in task 2, but use the system function SCHEMA_NAME with the schema_id column.Use the alias schemaname to display the name of the schema.• Execute the written statement and compare the results that you got with the desired results shown inthe file 56 - Lab Exercise 1 - Task 3_1 Result.txt.• Retrieve all views in the T<strong>SQL</strong><strong>2012</strong> database by writing a SELECT statement against the sys.views view,using the same columns as in the previous query.• Execute the written statement and compare the results that you got with the desired results shown inthe file 57 - Lab Exercise 1 - Task 3_2 Result.txt. Task 4: Write a SELECT statement to retrieve all columns from theSales.Customers table• Write a SELECT statement to retrieve the columns names from the sys.columns view, using the aliasescolumnname, column_id, system_type_id, max_length, precision, scale, and collation_name. Filter theresults to show only the columns from the Sales.Customers table.• Execute the written statement and compare the results that you got with the desired results shown inthe file 58 - Lab Exercise 1 - Task 4 Result.txt.Results: After this exercise, you should be able to retrieve some system information from the systemcatalog views.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-29Exercise 2: <strong>Querying</strong> System FunctionsScenarioYou will practice how to use system functions to retrieve additional system information from systemcatalog views.The main tasks for this exercise are as follows:1. Write a SELECT statement to retrieve the current database name and the user name.2. Write a couple of SELECT statements using different system functions to retrieve objects, schema, andcolumn names. Task 1: Write a SELECT statement to retrieve the current database name• Open the project file F:\10774A_Labs\10774A_15_PRJ\10774A_15_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve some calculated columns using different system functions:• Use the DB_ID function to retrieve the current database identification number. Give thiscalculated column the alias databaseid.• Use the DB_NAME function to retrieve the current database name. Give this calculated columnthe alias databasename.• Use the USER_NAME function to retrieve the current database user name. Give this calculatedcolumn the alias currusername.• Execute the written statement and compare the results that you got with the desired results shown inthe file 62 - Lab Exercise 2 - Task 1 Result.txt. Task 2: Write a SELECT statement to retrieve the object name and schema name• Write a SELECT statement to retrieve the name column and two calculated columns from thesys.columns view. To retrieve the first calculated column, use the OBJECT_NAME function with theobject_id column as a parameter. Give it the alias tablename. To retrieve the second calculatedcolumn, use the OBJECT_SCHEMA_NAME function with the object_id column as a parameter. Giveit the alias schemaname.• Execute the written statement and compare the results that you got with the recommended resultshown in the file 63 - Lab Exercise 2 - Task 2 Result.txt. Task 3: Write a SELECT statement to retrieve all the columns from the user-definedtables that contain the word “name” in the column name• Write a SELECT statement to retrieve the name column and two calculated columns from thesys.columns view. Give the name column the alias columnname. Use the OBJECT_NAME function toretrieve the first calculated column, giving it the alias tablename. Use the OBJECT_SCHEMA_NAMEfunction to retrieve the second calculated column, giving it the alias schemaname. Filter the result toinclude only columns that contain the word “name” in the column name and belong to user-definedtables. To do this, use the OBJECTPROPERTY function, passing it two parameters: object_id andIsUserTable with the value 1.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 64 - Lab Exercise 2 – Task 3 Result.txt.


15-30 <strong>Querying</strong> <strong>SQL</strong> Server Metadata Task 4: Retrieve the view definition• Write a SELECT statement to retrieve the view definition for the Sales.CustOrders view using theOBJECT_DEFINITION function. You will have to pass an object id to the function, so you can use theOBJECT_ID function to get the needed information.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 65 - Lab Exercise 2 - Task 4 Result.txt.Results: After this exercise, you should know how to use different system functions.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 15-31Exercise 3: <strong>Querying</strong> System Dynamic Management ViewsScenarioTo retrieve more dynamic information about <strong>SQL</strong> Server, you will write several SELECT statements toretrieve data from dynamic management views (DMVs).The main tasks for this exercise are as follows:1. Write a SELECT statement to return all current sessions.2. Execute a SELECT statement to retrieve the information about the computer on which <strong>SQL</strong> Server isinstalled.3. Write a SELECT statement to retrieve the current memory information. Task 1: Write a SELECT statement to return all current sessions• Open the project file F:\10774A_Labs\10774A_15_PRJ\10774A_15_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write a SELECT statement to retrieve the session_id, login_time, host_name, language, anddate_format columns from the sys.dm_exec_sessions DMV.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 72 - Lab Exercise 3 - Task 1 Result.txt. Task 2: Execute the provided T-<strong>SQL</strong> statement• Execute the provided T-<strong>SQL</strong> statement to retrieve the information about the computer on which<strong>SQL</strong> Server is installed.SELECTcpu_count AS 'Logical CPU Count',hyperthread_ratio AS 'Hyperthread Ratio',cpu_count/hyperthread_ratio As 'Physical CPU Count',physical_memory_kb/1024 AS 'Physical Memory (MB)',sqlserver_start_time AS 'Last <strong>SQL</strong> Start'FROM sys.dm_os_sys_info;• Observe and compare the results that you got with the recommended results shown in the file73 - Lab Exercise 3 - Task 2 Result.txt. Task 3: Write a SELECT statement to retrieve the current memory information• Write a SELECT statement to retrieve the total_physical_memory_kb, available_physical_memory_kb,total_page_file_kb, available_page_file_kb, and system_memory_state_desc columns from thesys.dm_os_sys_memory DMV.• Execute the written statement and compare the results that you got with the recommended resultsshown in the file 74 - Lab Exercise 3 - Task 3 Result.txt.Results: After this exercise, you should have an understanding of how to write queries against the systemDMVs.


15-32 <strong>Querying</strong> <strong>SQL</strong> Server MetadataModule ReviewReview Questions1. Why might you choose to query a system view rather than a system stored procedure that returnedthe same metadata?2. What issues might you face later if your application used SELECT * to query system catalog views?


16-1Module 16Executing Stored ProceduresContents:Lesson 1: <strong>Querying</strong> Data with Stored Procedures 16-3Lesson 2: Passing Parameters to Stored Procedures 16-7Lesson 3: Creating Simple Stored Procedures 16-12Lesson 4: Working with Dynamic <strong>SQL</strong> 16-17Lab: Executing Stored Procedures 16-23


16-2 Executing Stored ProceduresModule OverviewIn addition to writing standalone SELECT statements to return data from Microsoft® <strong>SQL</strong> Server®,you may need to execute T-<strong>SQL</strong> procedures created by an administrator or developer and stored in adatabase. This module will show you how to execute stored procedures, including how to pass parametersinto procedures written to accept them. This module will also show you how basic stored procedures arecreated, with a goal of better understanding what happens on the server when you execute one. Finally,this module will show you how to generate dynamic <strong>SQL</strong> statements, which is often a requirement indevelopment environments where stored procedures are not being used.ObjectivesAfter completing this module, you will be able to:• Return results by executing stored procedures.• Pass parameters to procedures.• Create simple stored procedures that encapsulate a SELECT statement.• Construct and execute dynamic <strong>SQL</strong> with EXEC and sp_executesql.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-3Lesson 1<strong>Querying</strong> Data with Stored ProceduresMany reporting and development tools offer the choice between writing and executing ad hoc T-<strong>SQL</strong>SELECT statements, and choosing from queries saved as stored procedures in <strong>SQL</strong> Server. While storedprocedures can encapsulate most T-<strong>SQL</strong> operations, including system administration tasks, this lesson willfocus on using stored procedures to return results sets, as an alternative to writing your own SELECTstatements.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe stored procedures and their use.• Write T-<strong>SQL</strong> statements that execute stored procedures to return data.


16-4 Executing Stored ProceduresExamining Stored ProceduresStored procedures are named collections of T-<strong>SQL</strong> statements created with the CREATE PROCEDUREcommand. They encapsulate many server and database commands, and can provide a consistentapplication programming interface (API) to client applications through the use of input parameters,output parameters, and return values.Since this course focuses primarily on retrieving results from databases through SELECT statements, thislesson will only cover the use of stored procedures that encapsulate SELECT queries. However, it may beuseful to note that stored procedures can also include INSERT, UPDATE, DELETE, and other valid T-<strong>SQL</strong>commands. In addition, they can be used to provide an interface layer between a database and anapplication. Using such a layer, developers and administrators can ensure that all activity is performedby trusted code modules that validate input and handle errors appropriately. Elements of such an APIwould include:• Views or table-valued functions as wrappers for simple retrieval.• Stored procedures for retrieval when complex validation or manipulation is required.• Stored procedures for inserting, updating, or deleting rows.In addition to encapsulating code and making it easier to maintain, this approach provides a securitylayer. Users may be granted access to objects rather than the underlying tables themselves. This ensuresthat users may only use the provided application to access data rather than other tools.Stored procedures offer other benefits as well, including network and database engine performanceimprovements. See Microsoft course 10776: Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases foradditional information on these benefits and more details on creating and using stored procedures.For More Information See Books Online at http://msdn.microsoft.com/en-us/library/ms190782(v=<strong>SQL</strong>.110).aspx.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-5Executing Stored ProceduresEarlier in this course, you learned how to execute system stored procedures. The same mechanism existsfor executing user procedures. Therefore some of the following guidelines are provided for review:• To execute a stored procedure, use the EXECUTE command or its shortcut, EXEC, followed by thetwo-part name of the procedure. Your reporting tool may provide a graphical interface for selectingprocedures by name, which will invoke the EXEC command for you.• If the procedure accepts parameters, pass them as name-value pairs. For example, if the parameter iscalled custid and the value to pass is 5, use this form: @custid=5. Multiple parameters are separatedwith commas.• Pass parameters of the appropriate data type to the stored procedure. For example, if a procedureaccepts an NVARCHAR, pass in the Unicode character string format: N'string'.• If the procedure encapsulates a simple SELECT statement, no additional elements are needed toexecute it. If the procedure includes an OUTPUT parameter, additional steps will be required. See thelesson on OUTPUT parameters later in this module.Note You may see sample code that omits the use of the EXEC command before thename of a procedure. While this works on the first line of a batch (or in the only line of aone-line batch), this is not a best practice. Always use EXECUTE or EXEC to invoke storedprocedures.For More Information See Books Online at http://go.microsoft.com/fwlink/?LinkId=233885.


16-6 Executing Stored ProceduresDemonstration: <strong>Querying</strong> Data with Stored ProceduresDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_16_PRJ\10774A_16_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-7Lesson 2Passing Parameters to Stored ProceduresProcedures can be written to accept parameters to provide greater flexibility. Most parameters are writtenas input parameters, which accept values passed in the EXEC statement and are used inside the procedure.Some procedures may also return values in the form of OUTPUT parameters, which require additionalhandling by the client when invoking the procedure. You will learn how to pass input and return outputparameters in this lesson.Lesson ObjectivesAfter completing this lesson, you will be able to:• Write EXECUTE statements that pass input parameters to stored procedures.• Write T-<strong>SQL</strong> batches that prepare output parameters and execute stored procedures.


16-8 Executing Stored ProceduresPassing Input Parameters to Stored ProceduresStored procedures can be written to accept input parameters to provide greater flexibility. Proceduresdeclare their parameters by name and data type in the header of the CREATE PROCEDURE statement, andthen use the parameters as local variables in the body of the procedure. For example, an input parametermight be used in the predicate of a WHERE clause or as the value in a TOP operator.To call a stored procedure and pass parameters, use the following syntax:EXEC . @ = [, ...]For example, if you have a procedure called ProductsBySuppliers stored in the Production schema and thisprocedure accepts a parameter named supplierid, you would use the following:EXEC Production.ProductsBySuppliers @supplierid = 1;To pass multiple input parameters, separate the name-value pairs with commas, as in this example:EXEC Sales.FindOrder @empid = 1, @custid=1;Note The previous example refers to a procedure that does not exist in the sampledatabase for the course. Other examples in the demonstration script for this lesson can beexecuted against procedures in the sample T<strong>SQL</strong><strong>2012</strong> database.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-9If you have not been provided with the names and data types of the parameters for the proceduresyou will be executing, you can typically discover them yourself, assuming you have permissions to do so.<strong>SQL</strong> Server Management Studio (SSMS) displays a parameters folder below each stored procedure, whichlists the names, types, and direction (input/output) of each defined parameter. Alternatively, you canquery a system catalog view such as sys.parameters to retrieve parameter definitions. See thedemonstration script provided for this lesson for an example.For More Information Additional reading about passing parameters to storedprocedures can be found in Books Online at http://go.microsoft.com/fwlink/?LinkId=242979.


16-10 Executing Stored ProceduresWorking with OUTPUT ParametersSo far in this module, you have seen procedures that return results through an embedded SELECTstatement. <strong>SQL</strong> Server also provides the capability to return a scalar value through a parameter markedas an OUTPUT parameter. This has several benefits: A procedure can return a result set via a SELECTstatement and provide an additional value, such as a row count, to the calling application. For somespecific scenarios where only a single value is desired, a procedure that returns an OUTPUT parametercan perform faster than a procedure that returns the scalar value in a result set.There are two aspects to working with stored procedures that use output parameters:• The procedure itself must mark a parameter with the OUTPUT keyword in the parameter declaration,as in the following example:CREATE PROCEDURE Sales.GetCustPhone(@custid AS INT, @phone AS nvarchar(24) OUTPUT)AS ...• The T-<strong>SQL</strong> batch that calls the procedure must add additional code to handle the output parameter.The code includes a local variable that acts as a container for the value that will be returned by theprocedure when it executes. The parameter is added to the EXEC statement, marked with theOUTPUT keyword. After the stored procedure has completed, the variable will contain the value ofthe output parameter set inside the procedure. The following example declares a local variable to bepassed as the output parameter, executes a procedure, and then examines the variable with a SELECTstatement:DECLARE @customerid INT =5, @phonenum NVARCHAR(24);EXEC Sales.GetCustPhone @custid=@customerid, @phone=@phonenum OUTPUT;SELECT @phonenum AS phone;


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-11Demonstration: Passing Parameters to Stored ProceduresDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_16_PRJ\10774A_16_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


16-12 Executing Stored ProceduresLesson 3Creating Simple Stored ProceduresIn order to better understand how to work with stored procedures written by developers andadministrators, it will be useful to learn how stored procedures are created. In this lesson, you will seehow to write a stored procedure that returns a result set from an encapsulated SELECT statement.Lesson ObjectivesAfter completing this lesson, you will be able to:• Use the CREATE PROCEDURE statement to write a stored procedure.• Create a stored procedure that accepts input parameters.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-13Creating Procedures to Return RowsStored procedures in <strong>SQL</strong> Server are used for many tasks, including system configuration andmaintenance as well as data manipulation. As previously mentioned, there are advantages to creatingprocedures to standardize access to data. To do that, you can create a stored procedure that is a wrapperfor a SELECT statement, which may include any of the data manipulations you have learned in this courseso far. The following example creates a procedure that aggregates order information:CREATE PROCEDURE Sales.OrderSummariesASSELECT O.orderid, O.custid, O.empid, O.shipperid, CAST(O.orderdate AS date)AS orderdate,SUM(OD.qty) AS quantity,CAST(SUM(OD.qty * OD.unitprice * (1 - OD.discount))AS NUMERIC(12, 2)) AS ordervalueFROM Sales.Orders AS OJOIN Sales.OrderDetails AS ODON O.orderid = OD.orderidGROUP BY O.orderid, O.custid, O.empid, O.shipperid, O.orderdate;GOTo execute this procedure, use the EXECUTE or EXEC command before the procedure's two-part name:EXEC [Sales].[OrderSummaries];A partial result:orderid custid empid shipperid orderdate quantity ordervalue------- ----- ------ --------- ---------- -------- ----------10248 85 5 3 2006-07-04 27 440.0010249 79 6 1 2006-07-05 49 1863.4010250 34 4 2 2006-07-08 60 1552.60


16-14 Executing Stored Procedures• To modify the design of the procedure, such as to change the columns in the SELECT list or add anORDER BY clause, use the ALTER PROCEDURE (abbreviated ALTER PROC) statement and supply thefull new code for the procedure:ALTER PROCEDURE Sales.OrderSummariesASSELECT O.orderid, O.custid, O.empid, O.shipperid, CAST(O.orderdate AS date)ASorderdate,SUM(OD.qty) AS quantity,CAST(SUM(OD.qty * OD.unitprice * (1 - OD.discount))AS NUMERIC(12, 2)) AS ordervalueFROM Sales.Orders AS OJOIN Sales.OrderDetails AS ODON O.orderid = OD.orderidGROUP BY O.orderid, O.custid, O.empid, O.shipperid, O.orderdateORDER BY orderid, orderdate;Note Changing the procedure with ALTER PROCEDURE is preferable to using DROPPROCEDURE to delete it and then using CREATE PROCEDURE to rebuild it with a newdefinition. By altering it in place, security permissions do not need to be reassigned. Formore information on modifying stored procedures, see Books Online athttp://go.microsoft.com/fwlink/?LinkId=242981.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-15Creating Procedures That Accept ParametersA stored procedure that accepts input parameters provides added flexibility to its use. To define inputparameters in your own stored procedures, declare them in the header of the CREATE PROCEDUREstatement, then refer to them in the body of the stored procedure. Define the parameters with an @prefix in the name, then assign them a data type.Note Parameters may also be assigned default values, including NULL.CREATE PROCEDURE .(@ AS )AS ...For example, the following procedure will accept the empid parameter as an integer and pass it to theWHERE clause to be used as a filter:CREATE PROCEDURE Sales.OrderSummariesByEmployee(@empid AS int)ASSELECT O.orderid, O.custid, O.empid, O.shipperid, CAST(O.orderdate AS date)AS orderdate,SUM(OD.qty) AS quantity,CAST(SUM(OD.qty * OD.unitprice * (1 - OD.discount))AS NUMERIC(12, 2)) AS ordervalueFROM Sales.Orders AS OJOIN Sales.OrderDetails AS ODON O.orderid = OD.orderidWHERE empid = @empidGROUP BY O.orderid, O.custid, O.empid, O.shipperid, O.orderdateORDER BY orderid, orderdate;GOTo call the procedure, use EXEC and pass in a value:EXEC Sales.OrderSummariesByEmployee @empid = 5;


16-16 Executing Stored ProceduresDemonstration: Creating Simple Stored ProceduresDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_16_PRJ\10774A_16_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 31 – Demonstration C.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-17Lesson 4Working with Dynamic <strong>SQL</strong>In organizations where creating parameterized stored procedures is not supported, you may need toexecute T-<strong>SQL</strong> code constructed in your application at runtime. Dynamic <strong>SQL</strong> provides a mechanism forconstructing a character string that is passed to <strong>SQL</strong> Server, interpreted as a command, and executed.In this lesson, you will learn how to pass dynamic <strong>SQL</strong> queries to <strong>SQL</strong> Server, using the EXEC statementand the system procedure sp_executesql.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe how T-<strong>SQL</strong> can be dynamically constructed.• Write queries that use dynamic <strong>SQL</strong>.


16-18 Executing Stored ProceduresConstructing Dynamic <strong>SQL</strong>Dynamic <strong>SQL</strong> provides a mechanism for constructing a character string that is passed to <strong>SQL</strong> Server,interpreted as a command, and executed. Why would you want to do this? You may not know all thevalues necessary for your query until execution time, such as taking the results of one query and usingthem as inputs to another query (e.g., a pivot query) or an administrative maintenance routine thataccepts object names at runtime.T-<strong>SQL</strong> supports two methods for building dynamic <strong>SQL</strong> expressions: using the EXECUTE command (or itsshortcut EXEC) with a string or invoking the system stored procedure sp_executesql:1. The EXECUTE or EXEC command supports the use of a string as an input in the following form, butdoes not support parameters, which need to be combined in the input string. The following exampleshows how individual strings may be concatenated to form a command:DECLARE @sqlstring AS VARCHAR(1000);SET @sqlstring='SELECT empid,' + ' lastname '+' FROM HR.employees;'EXEC(@sqlstring);GO2. The system stored procedure sp_executesql supports string input for the query, as well as inputparameters. The following example shows a simple string with a parameter passed to sp_executesql:DECLARE @sqlcode AS NVARCHAR(256) = N'SELECT GETDATE() AS dt';EXEC sys.sp_executesql @statement = @sqlcode;GO


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-19It is important to know that EXEC cannot accept parameters and does not promote query plan reuse.Therefore, it is preferred that you use sp_executesql for passing dynamic <strong>SQL</strong> to <strong>SQL</strong> Server.For More Information See the section "Using EXECUTE with a Character String" inthe "EXECUTE (Transact-<strong>SQL</strong>)" topic in Books Online at http://go.microsoft.com/fwlink/?LinkId=233911. For more information on using sp_executesql, see the next topic in thislesson. For information on avoiding <strong>SQL</strong> injection attacks, see "<strong>SQL</strong> Injection" in BooksOnline at http://go.microsoft.com/fwlink/?LinkId=242984.


16-20 Executing Stored ProceduresWriting Queries with Dynamic <strong>SQL</strong>In the previous topic, you learned that there were two methods for executing dynamic <strong>SQL</strong>. This topicfocuses on the preferred method, calling sp_executesql.Constructing and executing dynamic <strong>SQL</strong> with sp_executesql is preferred over using EXEC because EXECcannot take parameters at runtime. In addition, sp_executesql generates execution plans that are morelikely to be reused than EXEC. But perhaps most important, by defining data types for parameters, usingsp_executesql can provide a line of defense against <strong>SQL</strong> injection attacks.To use sp_executesql, provide a character string value that contains the query code as a parameter, as inthe following syntax example:DECLARE @sqlcode AS NVARCHAR(256) = N'';EXEC sys.sp_executesql @statement = @sqlcode;GOThe following example uses sp_executesql to execute a simple SELECT query:DECLARE @sqlcode AS NVARCHAR(256) =N'SELECT GETDATE() AS dt';EXEC sys.sp_executesql @statement = @sqlcode;GOTo use sp_executesql with parameters, provide the query code as well as two additional parameters:• @stmt, a Unicode string variable to hold the query text• @params, a Unicode string variable that holds a comma-separated list of parameter names and datatypesIn addition to these two variables, you will declare and assign variables to hold the values for theparameters you wish to pass in to sp_executesql.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-21The following example uses sp_executesql to dynamically generate a query that returns an employee'sinformation based on an empid value:DECLARE @sqlstring AS NVARCHAR(1000);DECLARE @empid AS INT;SET @sqlstring=N'SELECT empid, lastname FROM HR.employees WHERE empid=@empid;'EXEC sys.sp_executesql @statement = @sqlstring, @params=N'@empid AS INT',@empid = 5;The result:empid lastname----- --------5 BuckNote sp_executesql can also use output parameters marked with the OUTPUT keyword,which you learned about earlier in this module.For More Information For a discussion about query plan reuse and more coverage ofsp_executesql, see Books Online at http://go.microsoft.com/fwlink/?LinkId=242986.


16-22 Executing Stored ProceduresDemonstration: Working with Dynamic <strong>SQL</strong>Demonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_16_PRJ\10774A_16_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 41 – Demonstration D.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-23Lab: Executing Stored ProceduresLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


16-24 Executing Stored Procedures7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Expand the Options button, and then under the Connection Properties expand Connect todatabase drop-down list box and select . Choose Yes when prompted for theconnection to the database and then under User Databases, select T<strong>SQL</strong><strong>2012</strong> database and thenclick OK.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a business analyst for Adventure Works who will be writing reports using corporate databasesstored in <strong>SQL</strong> Server <strong>2012</strong>. You have been provided with a set of business requirements for data and willwrite T-<strong>SQL</strong> queries to retrieve the specified data from the databases. You have learned that some of thedata can only be accessed via stored procedures instead of directly querying the tables. Additionally,some of the procedures require parameters in order to interact with them.Important When comparing your results with the provided sample outputs, the column orderingand total number of affected rows should always match. However, remember that the order of therows in the output of a query without an ORDER BY clause is not guaranteed. Therefore, the order ofthe rows in the sample outputs may be different than yours. Also, the answer outputs includeabbreviated results.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-25Exercise 1: Using the EXECUTE Statement to Invoke Stored ProceduresScenarioThe IT department has supplied T-<strong>SQL</strong> code to create a stored procedure to retrieve the top 10 customersby the total sales amount. You will practice how to execute a stored procedure.The main tasks for this exercise are as follows:1. Create and execute a stored procedure.2. Answer questions. Task 1: Create and execute a stored procedure• Open the project file F:\10774A_Labs\10774A_16_PRJ\10774A_16_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Execute the provided T-<strong>SQL</strong> code to create the stored procedure Sales.GetTopCustomers:CREATE PROCEDURE Sales.GetTopCustomers ASSELECT TOP(10)c.custid,c.contactname,SUM(o.val) AS salesvalueFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidGROUP BY c.custid, c.contactnameORDER BY salesvalue DESC;• Write a T-<strong>SQL</strong> statement to execute the created procedure.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the desired results shown inthe file 52 - Lab Exercise 1 - Task 1 Result.txt. Task 2: Modify the stored procedure and execute it• The IT department has changed the stored procedure from task 1 and has supplied you with T-<strong>SQL</strong>code to apply the needed changes. Execute the provided T-<strong>SQL</strong> code:ALTER PROCEDURE Sales.GetTopCustomers ASSELECTc.custid,c.contactname,SUM(o.val) AS salesvalueFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidGROUP BY c.custid, c.contactnameORDER BY salesvalue DESCOFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;• Write a T-<strong>SQL</strong> statement to execute the modified stored procedure.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the desired results shown inthe file 53 - Lab Exercise 1 - Task 2 Result.txt.


16-26 Executing Stored Procedures• What is the difference between the previous T-<strong>SQL</strong> code and this one?• If some applications are using the stored procedure from task 1, would they still work properly afterthe changes you have applied in task 2?Results: After this exercise, you should be able to invoke a stored procedure using the EXECUTEstatement.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-27Exercise 2: Passing Parameters to Stored ProceduresScenarioThe IT department supplied you with additional modifications of the stored procedure in task 1. Themodified stored procedure lets you pass parameters that specify the order year and number of customersto retrieve. You will practice how to execute the stored procedure with a parameter.The main tasks for this exercise are as follows:1. Write an EXECUTE statement to invoke a stored procedure that has a parameter.2. Answer questions. Task 1: Execute a stored procedure with a parameter for order year• Open the project file F:\10774A_Labs\10774A_16_PRJ\10774A_16_PRJ.ssmssln and the <strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Execute the provided T-<strong>SQL</strong> code to modify the Sales.GetTopCustomers stored procedure to include aparameter for order year (@orderyear):ALTER PROCEDURE Sales.GetTopCustomers@orderyear intASSELECTc.custid,c.contactname,SUM(o.val) AS salesvalueFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidWHERE YEAR(o.orderdate) = @orderyearGROUP BY c.custid, c.contactnameORDER BY salesvalue DESCOFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;• Write an EXECUTE statement to invoke the Sales.GetTopCustomers stored procedure for theyear 2007.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the desired results shownin the file 62 - Lab Exercise 2 - Task 1_1 Result.txt.• Write an EXECUTE statement to invoke the Sales.GetTopCustomers stored procedure for theyear 2008.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the desired results shownin the file 63 - Lab Exercise 2 - Task 1_2 Result.txt.• Write an EXECUTE statement to invoke the Sales.GetTopCustomers stored procedure without aparameter.• Execute the T-<strong>SQL</strong> statement. What happened? What is the error message?• If an application was designed to use the exercise 1 version of the stored procedure, would themodification made to the stored procedure in this exercise impact the usability of that application?Please explain.


16-28 Executing Stored Procedures Task 2: Modify the stored procedure to have a default value for the parameter• Execute the provided T-<strong>SQL</strong> code to modify the Sales.GetTopCustomers stored procedure:ALTER PROCEDURE Sales.GetTopCustomers@orderyear int = NULLASSELECTc.custid,c.contactname,SUM(o.val) AS salesvalueFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidWHERE YEAR(o.orderdate) = @orderyear OR @orderyear IS NULLGROUP BY c.custid, c.contactnameORDER BY salesvalue DESCOFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;• Write an EXECUTE statement to invoke the Sales.GetTopCustomers stored procedure without aparameter.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the recommended resultsshown in the file 64 - Lab Exercise 2 - Task 2 Result.txt.• If an application was designed to use the exercise 1 version of the stored procedure, would thechange made to the stored procedure in this task impact the usability of that application? How doesthis change influence the design of future applications? Task 3: Pass multiple parameters to the stored procedure• Execute the provided T-<strong>SQL</strong> code to add the parameter @n to the Sales.GetTopCustomers storedprocedure. You use this parameter to specify how many customers you want retrieved. The defaultvalue is 10.ALTER PROCEDURE Sales.GetTopCustomers@orderyear int = NULL,@n int = 10ASSELECTc.custid,c.contactname,SUM(o.val) AS salesvalueFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidWHERE YEAR(o.orderdate) = @orderyear OR @orderyear IS NULLGROUP BY c.custid, c.contactnameORDER BY salesvalue DESCOFFSET 0 ROWS FETCH NEXT @n ROWS ONLY;• Write an EXECUTE statement to invoke the Sales.GetTopCustomers stored procedure without anyparameters.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the recommended resultsshown in the file 65 - Lab Exercise 2 - Task 3_1 Result.txt.• Write an EXECUTE statement to invoke the Sales.GetTopCustomers stored procedure for order year2008 and five customers.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-29• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the recommended resultsshown in the file 66 - Lab Exercise 2 - Task 3_2 Result.txt.• Write an EXECUTE statement to invoke the Sales.GetTopCustomers stored procedure for the orderyear 2007.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the recommended resultshown in the file 67 - Lab Exercise 2 - Task 3_3 Result.txt.• Write an EXECUTE statement to invoke the Sales.GetTopCustomers stored procedure to retrieve20 customers.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the recommended resultsshown in the file 68 - Lab Exercise 2 - Task 3_4 Result.txt.• Do the applications using the stored procedure need to be changed because another parameterwas added? Task 4: Return the result from a stored procedure using the OUTPUT clause• Execute the provided T-<strong>SQL</strong> code to modify the Sales.GetTopCustomers stored procedure to returnthe customer contact name based on a specified position in a ranking of total sales, which is providedby the parameter @customerpos. The procedure also includes a new parameter named@customername, which has an OUTPUT option.ALTER PROCEDURE Sales.GetTopCustomers@customerpos int = 1,@customername nvarchar(30) OUTPUTASSET @customername = (SELECTc.contactnameFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidGROUP BY c.custid, c.contactnameORDER BY SUM(o.val) DESCOFFSET @customerpos - 1 ROWS FETCH NEXT 1 ROW ONLY);• The IT department also supplied you with T-<strong>SQL</strong> code to declare the new variable@outcustomername. You will use this variable as an output parameter for the stored procedure.DECLARE @outcustomername nvarchar(30);• Write an EXECUTE statement to invoke the Sales.GetTopCustomers stored procedure and retrieve thefirst customer.• Write a SELECT statement to retrieve the value of the output parameter @outcustomername.• Execute the batch of T-<strong>SQL</strong> code consisting of the provided DECLARE statement, the written EXECUTEstatement, and the written SELECT statement.• Observe and compare the results that you got with the recommended results shown in the file69 - Lab Exercise 2 - Task 4 Result.txt.Results: After this exercise, you should know how to invoke stored procedures that have parameters.


16-30 Executing Stored ProceduresExercise 3: Executing System Stored ProceduresScenarioIn the previous module, you learned how to query the system catalog. Now you will practice how toexecute some of the most commonly used system stored procedures to retrieve information about tablesand columns.The main task for this exercise is as follows:1. Write EXECUTE statements to invoke different system stored procedures. Task 1: Execute the stored procedure sys.sp_help• Open the project file F:\10774A_Labs\10774A_16_PRJ\10774A_16_PRJ.ssmssln and the <strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write an EXECUTE statement to invoke the sys.sp_help stored procedure without a parameter.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the recommended resultsshown in the file 72 - Lab Exercise 3 - Task 1_1 Result.txt.• Write an EXECUTE statement to invoke the sys.sp_help stored procedure for a specific table bypassing the parameter Sales.Customers.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the recommended resultsshown in the file 73 - Lab Exercise 3 - Task 1_2 Result.txt. Task 2: Execute the stored procedure sys.sp_helptext• Write an EXECUTE statement to invoke the sys.sp_helptext stored procedure, passing theSales.GetTopCustomers stored procedure as a parameter.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the recommended resultsshown in the file 74 - Lab Exercise 3 - Task 2 Result.txt. Task 3: Execute the stored procedure sys.sp_columns• Write an EXECUTE statement to invoke the sys.sp_columns stored procedure for the tableSales.Customers. You will have to pass two parameters: @table_name and @table_owner.• Execute the T-<strong>SQL</strong> statement and compare the results that you got with the recommended resultsshown in the file 75 - Lab Exercise 3 - Task 3 Result.txt. Task 4: Drop the created stored procedure• Execute the provided T-<strong>SQL</strong> statement to remove the Sales.GetTopCustomers stored procedure:DROP PROCEDURE Sales.GetTopCustomers;Results: After this exercise, you should have a basic knowledge of invoking different system storedprocedures.


10774A: <strong>Querying</strong> <strong>SQL</strong> Server <strong>2012</strong> 16-31Module ReviewReview Questions1. What benefits do stored procedures provide for data retrieval that views do not?2. What form should parameter and value pairs take when passed to a stored procedure in theEXECUTE statement?3. Which method for constructing dynamic <strong>SQL</strong> allows parameters to be passed at runtime?


16-32 Executing Stored Procedures


17-1Module 17Programming with T-<strong>SQL</strong>Contents:Lesson 1: T-<strong>SQL</strong> Programming Elements 17-3Lesson 2: Controlling Program Flow 17-11Lab: Programming with T-<strong>SQL</strong> 17-17


17-2 Programming with T-<strong>SQL</strong>Module OverviewIn addition to the data retrieval and manipulation statements you have learned about in this course,T-<strong>SQL</strong> provides some basic programming features, such as variables, control-of-flow elements, andconditional execution. In this module, you will learn how to enhance your T-<strong>SQL</strong> code with programmingelements.ObjectivesAfter completing this module, you will be able to:• Describe the language elements of T-<strong>SQL</strong> used for simple programming tasks.• Describe batches and how they are handled by <strong>SQL</strong> Server.• Declare and assign variables and synonyms.• Use IF and WHILE blocks to control program flow.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 17-3Lesson 1T-<strong>SQL</strong> Programming ElementsWith a few exceptions, most of your work with T-<strong>SQL</strong> in this course so far has focused on single-statementstructures, such as SELECT statements. As you move from executing code objects to creating them, youwill need to understand how multiple statements interact with the server on execution. You will also needto be able to temporarily store values. For example, you might need to temporarily store values that willbe used as parameters in stored procedures. Finally, you may want to be able to create aliases, or pointers,to objects so that you can reference them by a different name or from a different location than wherethey are defined. This lesson will cover each of these topics.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe how Microsoft® <strong>SQL</strong> Server® treats collections of statements as batches.• Create and submit batches of T-<strong>SQL</strong> code for execution by <strong>SQL</strong> Server.• Describe how <strong>SQL</strong> Server stores temporary objects as variables.• Write code that declares and assigns variables.• Create and invoke synonyms.


17-4 Programming with T-<strong>SQL</strong>Introducing T-<strong>SQL</strong> BatchesT-<strong>SQL</strong> batches are collections of one or more T-<strong>SQL</strong> statements that are submitted to <strong>SQL</strong> Server by aclient as a single unit. <strong>SQL</strong> Server operates on all the statements in a batch at the same time when parsing,optimizing, and executing the code.If you are a report writer tasked primarily with writing SELECT statements and not writing procedures,it is still important to understand batch boundaries since they will affect your work with variables andparameters in stored procedures and other routines. As you will see, you must declare a variable in thesame batch in which the variable is referenced. Therefore, being able to recognize what is contained in abatch is important.Batches are delimited by the client application, and how you mark the end of a batch will depend onthe settings of your client. For example, the default batch terminator in <strong>SQL</strong> Server Management Studio(SSMS) is the keyword GO. GO is not a T-<strong>SQL</strong> keyword, but instead a keyword recognized by SSMS toindicate the end of a batch.When working with T-<strong>SQL</strong> batches, there are two important considerations to keep in mind:• Batches are boundaries for variable scope, which means that a variable defined in one batch may onlybe referenced by other code in the same batch.• Some statements, typically data definition statements such as CREATE VIEW, may not be combinedwith others in the same batch. See Books Online for the complete list.For More Information Additional reading can be found in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242987.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 17-5Working with BatchesAs you have seen, batches are collections of T-<strong>SQL</strong> statements submitted as a unit to <strong>SQL</strong> Server forparsing, optimization, and execution. Understanding how batches are parsed will be useful in identifyingerror messages and behavior.When a batch is submitted by a client (such as when you press the Execute button in SSMS), the batch isparsed for syntax errors by the <strong>SQL</strong> Server engine. Any errors found will cause the entire batch to berejected; there will be no partial execution of statements within the batch.If the batch passes the syntax check, then <strong>SQL</strong> Server proceeds with additional steps: resolving objectnames, checking permissions, and optimizing the code for execution. Once this process completes andexecution begins, statements succeed or fail individually. This is an important contrast to syntax checking.If a runtime error occurs on one line, the next line may be executed, unless you've added error handlingto the code.Note Error handling will be covered in a later module.For example, the following batch contains a syntax error in the first line:INSERT INTO dbo.t1 VALUE(1,2,N'abc');INSERT INTO dbo.t1 VALUES(2,3,N'def');GO


17-6 Programming with T-<strong>SQL</strong>Upon submitting the batch, the following error is returned:Msg 102, Level 15, State 1, Line 1Incorrect syntax near 'VALUE'.The error occurred in line 1. However, the entire batch is rejected, and execution does not continue withline 2. Even if the lines were reversed and the syntax error occurred in the second line, the first line wouldnot be executed since the entire batch would be rejected.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 17-7Introducing T-<strong>SQL</strong> VariablesIn T-<strong>SQL</strong>, as with other programming languages, variables are objects that allow temporary storage of avalue for later use. You have already encountered variables in this course. You used them to passparameter values to stored procedures and functions.In T-<strong>SQL</strong>, variables must be declared before they can be used. They may be assigned a value, or initialized,when they are declared. Declaring a variable includes providing a name and a data type, as shown below.As you have previously learned, variables must be declared in the same batch in which they arereferenced. In other words, all T-<strong>SQL</strong> variables are local in scope to the batch, both in visibility andlifetime. Only other statements in the same batch can see a variable declared in the batch, and a variableis automatically destroyed when the batch ends.The following example shows the use of variables to store values that will be passed to a stored procedurein the same batch:--Declare and initialize the variables.DECLARE @numrows INT = 3, @catid INT = 2;--Use variables to pass the parameters to the procedure.EXEC Production.ProdsByCategory@numrows = @numrows, @catid = @catid;GOFor More Information Additional reading can be found in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242988.


17-8 Programming with T-<strong>SQL</strong>Working with VariablesOnce you have declared a variable, you must initialize it, or assign it a value. You may do that three ways:• In <strong>SQL</strong> Server 2008 or later, you may initialize a variable using the DECLARE statement.• In any version of <strong>SQL</strong> Server, you may assign a single (scalar) value using the SET statement.• In any version of <strong>SQL</strong> Server, you can assign a value to a variable using a SELECT statement. Be surethat the SELECT statement returns exactly one row. An empty result will leave the variable with itsoriginal value; more than one result will cause an error.The following example shows the three ways of declaring and assigning values to variables:DECLARE @var1 AS INT = 99;DECLARE @var2 AS NVARCHAR(255);SET @var2 = N'string';DECLARE @var3 AS NVARCHAR(20);SELECT @var3 = lastname FROM HR.Employees WHERE empid=1;SELECT @var1 AS var1, @var2 AS var2, @var3 AS var3;GOThe results are:var1 var2 var3---- ------ ----99 string Davis


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 17-9Working with SynonymsIn <strong>SQL</strong> Server, synonyms provide a method for creating a link, or alias, to an object stored in the samedatabase or even on another instance of <strong>SQL</strong> Server. Objects that may have synonyms defined for theminclude tables, views, stored procedures, and user-defined functions.Synonyms can be used to make a remote object appear local or to provide an alternative name for a localobject. For example, synonyms can be used to provide an abstraction layer between client code and theactual database objects used by the code. The code references objects by their aliases, regardless of whatthe actual name of the object is.Note A synonym can be created that points to an object that does not yet exist. This iscalled deferred name resolution. The <strong>SQL</strong> Server engine will not check for the existence ofthe actual object until the synonym is used at runtime.To manage synonyms, use the Data Definition Language commands CREATE SYNONYM, ALTERSYNONYM, and DROP SYNONYM, as in the following example:CREATE SYNONYM dbo.ProdsByCategory FOR T<strong>SQL</strong><strong>2012</strong>.Production.ProdsByCategory;GOEXEC dbo.ProdsByCategory @numrows = 3, @catid = 2;To create a synonym, you must have CREATE SYNONYM permission as well as permission to alter theschema in which the synonym will be stored.For More Information See "Using Synonyms (Database Engine)" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242989.


17-10 Programming with T-<strong>SQL</strong>Demonstration: T-<strong>SQL</strong> Programming ElementsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_17_PRJ\10774A_17_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 17-11Lesson 2Controlling Program FlowAll programming languages include language elements that allow you to determine the flow of theprogram, or the order in which statements are executed. While not as fully featured as languages like C#,T-<strong>SQL</strong> provides a set of control-of-flow keywords that you can use to perform logic tests and create loopscontaining your T-<strong>SQL</strong> data manipulation statements. In this lesson, you will learn how to use the T-<strong>SQL</strong>IF and WHILE keywords.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the control-of-flow elements in T-<strong>SQL</strong>.• Write T-<strong>SQL</strong> code using IF...ELSE blocks.• Write T-<strong>SQL</strong> code that uses WHILE.


17-12 Programming with T-<strong>SQL</strong>Understanding T-<strong>SQL</strong> Control-of-Flow Language<strong>SQL</strong> Server provides language elements that control the flow of program execution within T-<strong>SQL</strong> batches,stored procedures, and multi-statement user-defined functions. These control-of-flow elements allow youto programmatically determine whether or not to execute statements and programmatically determinethe order of those statements that should be executed.These elements include, but are not limited to:• IF...ELSE, which executes code based on a Boolean expression.• WHILE, which creates a loop that executes as long as a condition is true.• BEGIN…END, which defines a series of T-<strong>SQL</strong> statements that should be executed together.• Other keywords (e.g., BREAK, CONTINUE, WAITFOR, and RETURN), which are used to support T-<strong>SQL</strong>control-of-flow operations.You will learn how to use some of these elements in the next lesson.For More Information Additional reading can be found in Books Online athttp://go.microsoft.com/fwlink/?LinkId=242991.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 17-13Working with IF…ELSEThe IF...ELSE structure is used in T-<strong>SQL</strong> to conditionally execute a block of code based on a predicate. TheIF statement determines whether the following statement or block (if BEGIN...END is used) executes. If thepredicate evaluates to TRUE, the code in the block is executed. If the predicate evaluates to FALSE orUNKNOWN, the block is not executed, unless the optional ELSE keyword is used to identify another blockof code.For example, the following IF statement, without an ELSE, will only execute the statements between BEGINand END if the predicate evaluates to TRUE, indicating that the object exists. If it evaluates to FALSE orUNKNOWN, no action is taken and execution resumes after the END statement:USE T<strong>SQL</strong><strong>2012</strong>;GOIF OBJECT_ID('HR.Employees') IS NULL --this object does exist in the sample databaseBEGINPRINT 'The specified object does not exist';END;With the use of ELSE, you have another execution option if the IF predicate evaluates to FALSE orUNKNOWN, as in the following example:IF OBJECT_ID('HR.Employees') IS NULLBEGINPRINT 'The specified object does not exist';ENDELSEBEGINPRINT 'The specified object exists';END;


17-14 Programming with T-<strong>SQL</strong>Within data manipulation operations, using IF with the EXISTS keyword can be a useful tool for efficientexistence checks, as in the following example:IF EXISTS (SELECT * FROM Sales.EmpOrders WHERE empid =5)BEGINPRINT 'Employee has associated orders';END;For More Information See Books Online at http://go.microsoft.com/fwlink/?LinkId=242992.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 17-15Working with WHILEThe WHILE statement is used to execute code in a loop based on a predicate. Like the IF statement, theWHILE statement determines whether the following statement or block (if BEGIN...END is used) executes.The loop ends when the predicate evaluates to FALSE or UNKNOWN. Typically, you control the loop witha variable tested by the predicate and manipulated in the body of the loop itself. The following exampleuses the @empid variable in the predicate and changes its value in the BEGIN...END block:DECLARE @empid AS INT = 1, @lname AS NVARCHAR(20);WHILE @empid


17-16 Programming with T-<strong>SQL</strong>Demonstration: Controlling Program FlowDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_17_PRJ\10774A_17_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 17-17Lab: Programming with T-<strong>SQL</strong>Lab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


17-18 Programming with T-<strong>SQL</strong>7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a junior database developer for Adventure Works who has so far focused on writing reports usingcorporate databases stored in <strong>SQL</strong> Server <strong>2012</strong>. To prepare for upcoming tasks, you will be working withsome basic T-<strong>SQL</strong> programming objects.Important When comparing your results with the provided sample outputs, the column orderingand total number of affected rows should always match. However, remember that the order of therows in the output of a query without an ORDER BY clause is not guaranteed. Therefore, the order ofthe rows in the sample outputs may be different than yours. Also, the answer outputs includeabbreviated results.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 17-19Exercise 1: Declaring Variables and Delimiting BatchesScenarioYou will practice how to declare variables, retrieve their values, and use variables in a SELECT statement toreturn specific employee information.The main tasks for this exercise are as follows:1. Declare a variable and set its value.2. Retrieve a variable and use it in a SELECT statement.3. Practice delimiting batches. Task 1: Declare a variable and retrieve the value• Open the project file F:\10774A_Labs\10774A_17_PRJ\10774A_17_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write T-<strong>SQL</strong> code that will create a variable called @num as an int data type. Set the value of thevariable to 5 and display the value of the variable using the alias mynumber. Execute the T-<strong>SQL</strong> code.• Observe and compare the results that you got with the desired results shown in the file 52 - LabExercise 1 - Task 1_1 Result.txt.• Write the batch delimiter GO after the written T-<strong>SQL</strong> code. In addition, write new T-<strong>SQL</strong> code thatdefines two variables, @num1 and @num2, both as an int data type. Set the values to 4 and 6,respectively. Write a SELECT statement to retrieve the sum of both variables using the alias totalnum.Execute the T-<strong>SQL</strong> code.• Observe and compare the results that you got with the desired results shown in the file53 - Lab Exercise 1 - Task 1_2 Result.txt. Task 2: Set the variable value using a SELECT statement• Write T-<strong>SQL</strong> code that defines the variable @empname as an nvarchar(30) data type.• Set the value by executing a SELECT statement against the HR.Employees table. Compute a value thatconcatenates the firstname and lastname column values. Add a space between the two column valuesand filter the results to return the employee whose empid value is equal to 1.• Return the @empname variable’s value using the alias employee.• Execute the T-<strong>SQL</strong> code.• Observe and compare the results that you got with the desired results shown in the file54 - Lab Exercise 1 - Task 2Result.txt.• What would happen if the SELECT statement would return more than one row?


17-20 Programming with T-<strong>SQL</strong> Task 3: Use a variable in the WHERE clause• Copy the T-<strong>SQL</strong> code from task 2 and modify it by defining an additional variable named @empidwith an int data type. Set the variable’s value to 5. In the WHERE clause, modify the SELECT statementto use the newly created variable as a value for the column empid.• Execute the modified T-<strong>SQL</strong> code.• Observe and compare the results that you got with the desired results shown in the file55 - Lab Exercise 1 - Task 3 Result.txt.• Change the @empid variable’s value from 5 to 2 and execute the modified T-<strong>SQL</strong> code to observethe changes. Task 4: Add a batch delimiter• Copy the T-<strong>SQL</strong> code from task 3 and modify it by adding the batch delimiter GO before thestatement:SELECT @empname AS employee;• Execute the modified T-<strong>SQL</strong> code.• What happened? What is the error message? Can you explain why the batch delimiter caused anerror?Results: After this exercise, you should know how to declare and use variables in T-<strong>SQL</strong> code.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 17-21Exercise 2: Using Control-of-Flow ElementsScenarioYou would like to include conditional logic in your T-<strong>SQL</strong> code to control the flow of elements by settingdifferent values to a variable using the IF statement.The main tasks for this exercise are as follows:1. Write a couple of examples of T-<strong>SQL</strong> code with conditional statements.2. Execute a loop by using the WHILE statement. Task 1: Write basic conditional logic• Open the project file F:\10774A_Labs\10774A_17_PRJ\10774A_17_PRJ.ssmssln and the <strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write T-<strong>SQL</strong> code that defines the variable @result as an nvarchar(20) data type and the variable @ias an int data type. Set the value of the @i variable to 8. Write an IF statement that implements thefollowing logic:• For @i variable values less than 5, set the value of the @result variable to “Less than 5”.• For @i variable values between 5 and 10, set the value of the @result variable to “Between 5and 10”.• For all @i variable values over 10, set the value of the @result variable to “More than 10”.• For other @i variable values, set the value of the @result variable to “Unknown”.• At the end of the T-<strong>SQL</strong> code, write a SELECT statement to retrieve the value of the @result variableusing the alias result. Highlight the complete T-<strong>SQL</strong> code and execute it.• Observe and compare the results that you got with the desired results shown in the file62 - Lab Exercise 2 - Task 1 Result.txt.• Copy the T-<strong>SQL</strong> code and modify it by replacing the IF statement with a CASE expression to get thesame result. Task 2: Check the employee birthdate• Write T-<strong>SQL</strong> code that declares two variables: @birthdate (data type date) and @cmpdate (datatype date).• Set the value of the @birthdate variable by writing a SELECT statement against the HR.Employeestable and retrieving the column birthdate. Filter the results to include only the employee with anempid equal to 5.• Set the @cmpdate variable to the value January 1, 1970.• Write an IF conditional statement by comparing the @birthdate and @cmpdate variable values.If @birthdate is less than @cmpdate, use the PRINT statement to print the message “The personselected was born before January 1, 1970”. Otherwise, print the message “The person selected wasborn on or after January 1, 1970”.


17-22 Programming with T-<strong>SQL</strong>• Execute the T-<strong>SQL</strong> code.• Observe and compare the results that you got with the recommended results shown in the file63 - Lab Exercise 2 - Task 2 Result.txt. This is a simple example for the purpose of this exercise.Typically, there would be a different statement block that would execute in each case. Task 3: Create and execute a stored procedure• The IT department has provided T-<strong>SQL</strong> code that encapsulates the previous task in a storedprocedure named Sales.CheckPersonBirthDate. It has two parameters: @empid, which you use tospecify an employee id, and @cmpdate, which you use as a comparison date. Execute the providedT-<strong>SQL</strong> code:CREATE PROCEDURE Sales.CheckPersonBirthDate@empid int,@cmpdate dateASDECLARE@birthdate date;SET @birthdate = (SELECT birthdate FROM HR.Employees WHERE empid = @empid);IF @birthdate < @cmpdatePRINT 'The person selected was born before ' + FORMAT(@cmpdate, 'MMMM d, yyyy','en-US')ELSEPRINT 'The person selected was born on or after ' + FORMAT(@cmpdate, 'MMMM d,yyyy', 'en-US');• Write an EXECUTE statement to invoke the Sales.CheckPersonBirthDate stored procedure using theparameters of 3 for @empid and January 1, 1990, for @cmpdate. Execute the T-<strong>SQL</strong> code.• Observe and compare the results that you got with the recommended results shown in the file64 - Lab Exercise 2 - Task 3 Result.txt. Task 4: Execute a loop using the WHILE statement• Write T-<strong>SQL</strong> code to loop 10 times, displaying the current loop information each time.• Define the @i variable as an int data type. Write a WHILE statement to execute while the @i variablevalue is less or equal 10. Inside the loop statement, write a PRINT statement to display the value ofthe @i variable using the alias loopid. Add T-<strong>SQL</strong> code to increment the @i variable value by 1.• Observe and compare the results that you got with the recommended results shown in the file65 - Lab Exercise 2 - Task 4 Result.txt. Task 5: Remove the stored procedure• Execute the provided T-<strong>SQL</strong> code to remove the created stored procedure.Results: After this exercise, you should know how to control the flow of the elements inside the T-<strong>SQL</strong>code.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 17-23Exercise 3: Generating a Dynamic <strong>SQL</strong> StatementScenarioYou will practice how to invoke dynamic <strong>SQL</strong> code and how to pass variables to it.The main tasks for this exercise are as follows:1. Write a dynamic <strong>SQL</strong> statement that does not use a parameter.2. Write a dynamic <strong>SQL</strong> statement that uses a parameter. Task 1: Write a dynamic <strong>SQL</strong> statement that does not use a parameter• Open the project file F:\10774A_Labs\10774A_17_PRJ\10774A_17_PRJ.ssmssln and the T-<strong>SQL</strong> script71 - Lab Exercise 3.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write T-<strong>SQL</strong> code that defines the variable @<strong>SQL</strong>str as nvarchar(200) data type. Set the value of thevariable to a SELECT statement that retrieves the empid, firstname, and lastname columns in theHR.Employees table.• Write an EXECUTE statement to invoke the written dynamic <strong>SQL</strong> statement inside the @<strong>SQL</strong>strvariable. Execute the T-<strong>SQL</strong> code.• Observe and compare the results that you got with the recommended results shown in the file72 - Lab Exercise 3 - Task 1 Result.txt. Task 2: Write a dynamic <strong>SQL</strong> statement that uses a parameter• Copy the previous T-<strong>SQL</strong> code and modify it to include in the dynamic batch stored in @<strong>SQL</strong>str, afilter in which empid is equal to a parameter named @empid. In the calling batch, define a variablenamed @<strong>SQL</strong>param as nvarchar(100). This variable will hold the definition of the @empid parameter.This means setting the value of the @<strong>SQL</strong>param variable to @empid int.• Write an EXECUTE statement that uses sp_executesql to invoke the code in the @<strong>SQL</strong>str variable,passing the parameter definition stored in the @<strong>SQL</strong>param variable to sp_executesql. Assign the value5 to the @empid parameter in the current execution.• Observe and compare the results that you got with the recommended results shown in the file73 - Lab Exercise 3 - Task 2 Result.txt.Results: After this exercise, you should have a basic knowledge of generating and invoking dynamic <strong>SQL</strong>statements.


17-24 Programming with T-<strong>SQL</strong>Exercise 4: Using SynonymsScenarioYou will practice how to create a synonym for a table inside the AdventureWorks2008R2 database andhow to write a query against it.The main tasks for this exercise are as follows:1. Create a synonym for a table.2. Write a SELECT statement against the synonym. Task 1: Create and use a synonym for a table• Open the project file F:\10774A_Labs\10774A_17_PRJ\10774A_17_PRJ.ssmssln and the T-<strong>SQL</strong> script81 - Lab Exercise 4.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Write T-<strong>SQL</strong> code to create a synonym named dbo.Person for the Person.Person table in theAdventureWorks2008R2 database. Execute the written statement.• Write a SELECT statement against the dbo.Person synonym and retrieve the FirstName and LastNamecolumns. Execute the SELECT statement.• Observe and compare the results that you got with the recommended results shown in the file82 - Lab Exercise 4 - Task 1 Result.txt. Task 2: Drop the synonym• Execute the provided T-<strong>SQL</strong> code to remove the synonym.Results: After this exercise, you should know how to create and use a synonym.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 17-25Module ReviewReview Questions1. Can a variable be declared in one batch and referenced in multiple batches?2. Can a synonym be created that references an object that doesn’t exist?3. Will a WHILE loop exit when the predicate evaluates to NULL?


17-26 Programming with T-<strong>SQL</strong>


18-1Module 18Implementing Error HandlingContents:Lesson 1: Using TRY / CATCH Blocks 18-3Lesson 2: Working with Error Information 18-7Lab: Implementing Error Handling 18-13


18-2 Implementing Error HandlingModule OverviewAs you continue to work with T <strong>SQL</strong>, you will surely encounter errors when your code executes. In thismodule, you will learn how to handle errors as well as how to gather detailed information about runtimeerrors. While this module is not intended to be a comprehensive treatment of error-handling, it willintroduce you to the methods available in <strong>SQL</strong> Server <strong>2012</strong>. See Microsoft Course 10776: DevelopingMicrosoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases for more information.ObjectivesAfter completing this module, you will be able to:• Describe <strong>SQL</strong> Server's behavior when errors occur in T-<strong>SQL</strong> code.• Implement structured exception handling in T-<strong>SQL</strong>.• Return information about errors from system objects.• Raise user-defined errors and pass system errors in T-<strong>SQL</strong> code.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 18-3Lesson 1Using TRY / CATCH BlocksEarlier in this course you learned that some errors, such as syntax errors, will prevent a batch of T-<strong>SQL</strong>statements from executing. However, many runtime errors will allow execution to continue to the nextline in a batch. To control this behavior, you can add structured exception handling to your code in theform of TRY / CATCH blocks. They will allow you to redirect failed executions to your custom errorhandlingcode and prevent unanticipated problems from code that returns an error but continues toexecute.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe structured exception handling support in <strong>SQL</strong> Server.• Create TRY and CATCH blocks in T-<strong>SQL</strong> code.


18-4 Implementing Error HandlingStructured Exception Handling<strong>SQL</strong> Server 2005 introduced support for structured exception handling, which is a feature of manymodern programming languages, such as those used with the .NET Framework. Unlike simple errorchecking, structured exception handling allows the program flow to be transferred to another section ofcode when an error is detected. This gives you the ability to create centralized error-handling routines inyour procedures and even dedicated error-handling procedures that can be called from other routines.<strong>SQL</strong> Server supports several ways of checking for and handling runtime errors in your code. Previousversions of <strong>SQL</strong> Server used the @@ERROR system function, which would return a nonzero value ifqueried immediately after an error occurred. However, this was problematic and required checking for anerror after each operation:INSERT INTO SomeTable VALUES(1,2,3); --perform an operationIF @@ERROR 0PRINT 'An error occurred';To implement structured exception handling, <strong>SQL</strong> Server provides support for protected blocks of codebetween BEGIN TRY and END TRY statements. If a runtime error occurs within a TRY block, execution istransferred to a block of code that is between BEGIN CATCH and END CATCH statements. (The BEGINCATCH statement must immediately follow the END TRY statement.) The CATCH block executes code thatcan inspect the error, manage transactions, and return information about the error to the client.It is important to note that structured exception handling operates on errors during runtime only. Syntaxand compilation errors that prevent a batch from starting cannot be handled by a TRY / CATCH block atthe same level. Also note that <strong>SQL</strong> Server does not currently support all aspects of structured exceptionhandling, such as FINALLY.For More Information Additional reading can be found in Books Online athttp://go.microsoft.com/fwlink/?LinkId=243001.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 18-5Creating TRY and CATCH BlocksTo use <strong>SQL</strong> Server's structured exception handling in your stored procedures or other code, you will needto create two fundamental sections, or blocks, of code. One block will contain the T-<strong>SQL</strong> statements thatcarry out the core functionality of your procedure, such as inserting or updating tables. This will bereferred to as the TRY block. A TRY block is marked with BEGIN TRY and END TRY statements:BEGIN TRY --start the protected blockEND TRY --end the protected blockA TRY block must be immediately followed by a CATCH block. (No code may be placed betweenEND TRY and BEGIN CATCH.) The CATCH block will contain code to handle the error. At runtime, an errorencountered in the TRY block will cause the program flow to branch to the CATCH block. Even if the erroris not handled in the CATCH block, execution of the code in the TRY block will not continue. The followingexample illustrates the flow (line numbers added for purposes of explanation):1) BEGIN TRY2) INSERT INTO TABLE1...3) INSERT INTO TABLE2... --error occurs4) INSERT INTO TABLE3...5) END TRY6) BEGIN CATCH7) --Handle error8) END CATCH;9) Execution begins with line 1, which starts the TRY block. It continues until an error occurs in line 3.Execution is redirected to line 6, where it enters the CATCH block. Any code in the CATCH block isexecuted, and the CATCH block ends in line 8. Any code that follows the CATCH block is then executednormally. It is important to note that line 4 never executes!


18-6 Implementing Error HandlingDemonstration: Using TRY / CATCH BlocksDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_18_PRJ\10774A_18_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 18-7Lesson 2Working with Error InformationIdentifying errors is an important part of responding and resolving issues in your T <strong>SQL</strong> code. <strong>SQL</strong> Serverprovides a set of functions that you can use to return information about errors as they occur. You can alsouse the new THROW statement to return your own custom error messages. The THROW statement canalso be used to raise system errors that have been handled by a CATCH block, in order to pass them tothe calling procedure or application. You will learn how to use the system error functions as well as theTHROW statement in this lesson.Lesson ObjectivesAfter completing this lesson, you will be able to:• Return detailed information about errors using the ERROR object functions.• Use THROW to raise user-defined errors and pass runtime errors.


18-8 Implementing Error Handling<strong>Querying</strong> the ERROR Object<strong>SQL</strong> Server provides a set of metadata about runtime errors that may be queried (usually in a CATCHblock) to return information about runtime errors. This metadata includes information about:• The unique ID number of the error. This ID number is accessible with the ERROR_NUMBER function.• The text of the error message. This text is accessible with the ERROR_MESSAGE function.• The severity of the error, expressed as a number between 1 and 25. This number is accessible with theERROR_SEVERITY function.• The name of the stored procedure or other routine that was executing when the error occurred. Thisname is accessible with the ERROR_PROCEDURE function. This function will return a NULL if the errorwas encountered outside of a named stored procedure or function.• The number of the line in which the error was encountered in the batch or routine. This line numberis accessible with the ERROR_LINE function.These ERROR object functions extend the information available from the older @@ERROR function.The following example shows how to use the ERROR object functions to return information about aruntime error:BEGIN TRYSELECT 1/0; --generate errorEND TRYBEGIN CATCHSELECTERROR_NUMBER() AS errnum,ERROR_MESSAGE() AS errmsg,ERROR_SEVERITY() AS errsev,ERROR_PROCEDURE() AS errproc,ERROR_LINE() AS errline;END CATCH;


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 18-9The result is:errnum errmsg errsev errproc errline----------- --------------------------------- ----------- ------- -----------8134 Divide by zero error encountered. 16 NULL 2Question Why did ERROR_PROCEDURE return a NULL in the example?


18-10 Implementing Error HandlingUsing the THROW Statement<strong>SQL</strong> Server <strong>2012</strong> provides the new THROW statement. THROW enables you to include error-handlingcode in a CATCH block to raise the original runtime error and pass it to an upper layer, such as a callingprocedure or client application.There are two methods for using THROW:1. From any location within your T-<strong>SQL</strong> code, you can invoke THROW with parameters to raise a userdefinederror message:THROW 55000, 'The object does not exist.', 1;The result is:Msg 55000, Level 16, State 1, Line 1The object does not exist.2. From within a CATCH block (and only from within a CATCH block), you can use THROW without anyparameters to re-raise the original error that invoked the CATCH block:BEGIN TRYSELECT 100/0;--generate an errorEND TRYBEGIN CATCHPRINT 'Code inside CATCH is beginning'PRINT 'Error: ' + CAST(ERROR_NUMBER() AS VARCHAR(255));THROW;END CATCH


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 18-11The result is:Code inside CATCH is beginningError: 8134Msg 8134, Level 16, State 1, Line 2Divide by zero error encountered.In previous versions of <strong>SQL</strong> Server, developers and administrators used the RAISERROR function to passuser-defined error messages to procedures and client applications. This required adding the messages tothe system catalog via the sys.sp_addmessage procedure, and added complexity to deploying andmanaging <strong>SQL</strong> Server-based applications. Additionally, RAISERROR could only invoke user-definedmessages; it was unable to pass a system error. THROW enables you to raise user-defined errors withoutstoring them in sys.messages.


18-12 Implementing Error HandlingDemonstration: Working with Error InformationDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_18_PRJ\10774A_18_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 18-13Lab: Implementing Error HandlingLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


18-14 Implementing Error Handling7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a junior database developer for Adventure Works who will be creating stored procedures usingcorporate databases stored in <strong>SQL</strong> Server <strong>2012</strong>. In order to create more robust procedures, you will beimplementing error handling in your code.Important When comparing your results with the provided sample outputs, the column orderingand total number of affected rows should always match. However, remember that the order of therows in the output of a query without an ORDER BY clause is not guaranteed. Therefore, the order ofthe rows in the sample outputs may be different than yours. Also, the answer outputs includeabbreviated results.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 18-15Exercise 1: Redirecting Errors with TRY / CATCHScenarioYou will practice how to capture and handle an error using the TRY / CATCH construct and display errorinformation with different ERROR functions.The main tasks for this exercise are as follows:1. Write basic TRY / CATCH constructs.2. Create error-handling routines in a CATCH block with ERROR functions. Task 1: Write a basic TRY / CATCH construct• Open the project file F:\10774A_Labs\10774A_18_PRJ\10774A_18_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Execute the provided SELECT statement:SELECT CAST(N'Some text' AS int);• Notice that you get an error. Write a TRY / CATCH construct by placing the SELECT statement ina TRY block. In the CATCH block, use the PRINT command to display the text “Error”. Execute theT-<strong>SQL</strong> code.• Observe and compare the results that you got with the desired results shown in the file52 - Lab Exercise 1 - Task 1 Result.txt. Task 2: Display an error number and an error message• The IT department has provided T-<strong>SQL</strong> code that looks like this:DECLARE @num varchar(20) = '0';BEGIN TRYPRINT 5. / CAST(@num AS numeric(10,4));END TRYBEGIN CATCHEND CATCH;Execute the provided T-<strong>SQL</strong> code. Notice that nothing happens, although based on the @numvariable’s value, you should get an error because of the division by zero. Why didn’t you get an error?• Modify the CATCH block by adding two PRINT statements. The first statement should display theerror number by using the ERROR_NUMBER function. The second statement should display the errormessage by using the ERROR_MESSAGE function. Also, include a label in each printed message, suchas “Error Number:” for the first message and “Error Message:” for the second one.• Execute and compare the results that you got with the desired results shown in the file53 - Lab Exercise 1 - Task 2_1 Result.txt.• Change the value of the @num variable from 0 to A and execute the T-<strong>SQL</strong> code.


18-16 Implementing Error Handling• Observe and compare the results that you got with the desired results shown in the file54 - Lab Exercise 1 - Task 2_2 Result.txt.• Change the value of the @num variable from A to 1000000000 and execute the T-<strong>SQL</strong> code.• Observe and compare the results that you got with the desired results shown in the file55 - Lab Exercise 1 - Task 2_3 Result.txt. Task 3: Add conditional logic to a CATCH block• Copy the T-<strong>SQL</strong> code from the previous task and modify it by including an IF statement in the CATCHblock before the added PRINT statements. The IF statement should check to see whether the errornumber is equal to 245 or 8114. If this condition is true, display the message “Handling conversionerror…” using a PRINT statement. If this condition is not true, display the message “Handling nonconversionerror…”.• Set the value of the @num variable to A and execute the T-<strong>SQL</strong> code.• Observe and compare the results that you got with the desired results shown in the file56 - Lab Exercise 1 - Task 3_1 Result.txt.• Change the value of the @num variable to 0 and execute the T-<strong>SQL</strong> code.• Observe and compare the results that you got with the desired results shown in the file57 - Lab Exercise 1 - Task 3_2 Result.txt. Task 4: Execute a stored procedure in the CATCH block• The IT department has provided you with T-<strong>SQL</strong> code to create a stored procedure nameddbo.GetErrorInfo to display different information about the error. Execute the provided T-<strong>SQL</strong> code:CREATE PROCEDURE dbo.GetErrorInfo ASPRINT 'Error Number: ' + CAST(ERROR_NUMBER() AS varchar(10));PRINT 'Error Message: ' + ERROR_MESSAGE();PRINT 'Error Severity: ' + CAST(ERROR_SEVERITY() AS varchar(10));PRINT 'Error State: ' + CAST(ERROR_STATE() AS varchar(10));PRINT 'Error Line: ' + CAST(ERROR_LINE() AS varchar(10));PRINT 'Error Proc: ' + COALESCE(ERROR_PROCEDURE(), 'Not within procedure');• Copy the T-<strong>SQL</strong> code in task 2 and modify it by removing the PRINT statements and writing anEXECUTE statement in the CATCH block to invoke the stored procedure dbo.GetErrorInfo.• Set the value of the @num variable to 0 and execute the T-<strong>SQL</strong> code.• Observe and compare the results that you got with the desired results shown in the file58 - Lab Exercise 1 - Task 4 Result.txt.Results: After this exercise, you should be able to capture and handle errors using a TRY / CATCHconstruct.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 18-17Exercise 2: Using THROW to Pass an Error Message Back to a ClientYou will practice how to pass an error message using the THROW statement and how to send customerror messages.The main tasks for this exercise are as follows:1. Write a THROW statement to pass an error message back to a client.2. Create and pass a custom error message. Task 1: Re-throw the existing error back to a client• Open the project file F:\10774A_Labs\10774A_18_PRJ\10774A_18_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Copy the T-<strong>SQL</strong> code from exercise 1, task 4, and modify it to include the THROW statement in theCATCH block after the EXECUTE statement. Execute the T-<strong>SQL</strong> code.• Observe and compare the results that you got with the desired results shown in the file62 - Lab Exercise 2 - Task 1 Result.txt. Task 2: Add an error handling routine• Copy the T-<strong>SQL</strong> code in the previous task and modify it by replacing a THROW statement with an IFstatement. Write a condition to compare the error number to the value 8134. If this condition is true,display the message “Handling division by zero…”. Otherwise, display the message “Throwing originalerror” and add a THROW statement.• Set the value of the @num variable to A and execute the T-<strong>SQL</strong> code.• Observe and compare the results that you got with the recommended results shown in the file63 - Lab Exercise 2 - Task 2 Result.txt. Task 3: Add a different error handling routine• The IT department has provided you with T-<strong>SQL</strong> code to create a new variable named @msg and setits value:DECLARE @msg AS varchar(2048);SET @msg = 'You are doing the module 18 on ' + FORMAT(CURRENT_TIMESTAMP, 'MMMM d,yyyy', 'en-US') + '. It''s not an error but it means that you are near the finalmodule!';• Write a THROW statement and specify the message ID of 50001 for the first argument, the @msgvariable for the second argument, and the value 1 for the third argument. Highlight the completeT-<strong>SQL</strong> code and execute it.• Observe and compare the results that you got with the recommended results shown in the file64 - Lab Exercise 2 - Task 3 Result.txt. Task 4: Remove the stored procedure• Execute the provided T-<strong>SQL</strong> code to remove the stored procedure dbo.GetErrorInfo.Results: After this exercise, you should know how to throw an error to pass messages back to a client.


18-18 Implementing Error HandlingModule ReviewReview Questions1. What type of errors cannot by caught by structured exception handling?2. Can TRY / CATCH blocks be nested?3. How can THROW be used outside of a CATCH block?


19-1Module 19Implementing TransactionsContents:Lesson 1: Transactions and the Database Engine 19-3Lesson 2: Controlling Transactions 19-10Lab: Implementing Transactions 19-18


19-2 Implementing TransactionsModule OverviewAs you continue to move past SELECT statements and into data modification operations with T-<strong>SQL</strong>,you must begin to consider how to structure batches that contain multiple modification statementsand batches that might encounter errors. In this module, you will learn how to define transactions tocontrol the behavior of batches of T-<strong>SQL</strong> statements submitted to Microsoft® <strong>SQL</strong> Server®. You will alsolearn how to determine whether a runtime error has occurred after work has begun and whether the workneeds to be undone.ObjectivesAfter completing this module, you will be able to:• Describe transactions and the differences between batches and transactions.• Describe batches and how they are handled by <strong>SQL</strong> Server.• Create and manage transactions with transaction control language statements.• Use SET XACT_ABORT to define <strong>SQL</strong> Server's handling of transactions outside TRY / CATCH blocks.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server 19-3Lesson 1Transactions and the Database EngineIn this lesson, you will compare simple batches of T-<strong>SQL</strong> statements to transactions, which allow you tocontrol the behavior of code submitted to <strong>SQL</strong> Server. You will decide whether special action is needed torespond to a runtime error after work has begun and whether the work needs to be undone.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe a <strong>SQL</strong> Server database transaction.• Describe the difference between a batch and a transaction.• Describe how transactions extend batches.


19-4 Implementing TransactionsDefining TransactionsEarlier in this course, you learned that a batch was a collection of T-<strong>SQL</strong> statements sent to <strong>SQL</strong> Serveras a unit for parsing, optimization, and execution. A transaction extends a batch from a unit submitted tothe database engine to a unit of work performed by the database engine. A transaction is a sequence ofT-<strong>SQL</strong> statements performed in an all-or-nothing fashion by <strong>SQL</strong> Server.Transactions are commonly created in two ways:• Autocommit transactions. Individual data modification statements (e.g., INSERT, UPDATE, andDELETE) submitted separately from other commands are automatically wrapped in a transaction by<strong>SQL</strong> Server. These single-statement transactions are automatically committed when the statementsucceeds or are automatically rolled back when the statement encounters a runtime error.• Explicit transactions. User-initiated transactions are created through the use of transaction controllanguage (TCL) commands that begin, commit, or roll back work based on user-issued code. TCL isa subset of T-<strong>SQL</strong>.The primary characteristic of a transaction is that all activity within a transaction's boundaries mustsucceed or must all fail—no partial completion is permitted. User transactions are typically defined toencapsulate operations that must logically occur together, such as entries into related tables as part of asingle business operation.For example, the following batch inserts data into two tables using two INSERT statements that are part ofa single order-processing operation:INSERT INTO dbo.SimpleOrders(custid, empid, orderdate)VALUES (68,9,'2006-07-12');INSERT INTO dbo.SimpleOrderDetails(orderid,productid,unitprice,qty)VALUES (1, 2,15.20,20);GO


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server 19-5Business rules might dictate that an order is complete only if the data was successfully inserted into bothtables. As you will see in the next lesson, a runtime error in this batch might result in data being insertedinto one table but not the other. Enclosing both INSERT statements in a user-defined transaction providesthe ability to undo the data insertion in one table if the INSERT statement in the other table fails. A simplebatch does not provide this capability.<strong>SQL</strong> Server manages resources on behalf of transactions while the transactions are active. These resourcesmay include locks and entries in the transaction log to allow <strong>SQL</strong> Server to undo changes made by thetransaction should a rollback be required.For More Information Additional reading can be found in Books Online athttp://go.microsoft.com/fwlink/?LinkId=243002. For more information on locking, seeMicrosoft course 10776: Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases.


19-6 Implementing TransactionsThe Need for Transactions: Issues with BatchesWhile batches of T-<strong>SQL</strong> statements provide a unit of code submitted to the server, they do not includeany logic for dealing with partial success when a runtime error occurs, even with the use of structuredexception handling's TRY / CATCH blocks.The following example illustrates this problem:BEGIN TRYINSERT INTO dbo.SimpleOrders(custid, empid, orderdate)VALUES (68,9,'2006-07-12');INSERT INTO dbo.SimpleOrders(custid, empid, orderdate)VALUES (88,3,'2006-07-15');INSERT INTO dbo.SimpleOrderDetails(orderid,productid,unitprice,qty)VALUES (1, 2,15.20,20);INSERT INTO dbo.SimpleOrderDetails(orderid,productid,unitprice,qty)VALUES (999,77,26.20,15);END TRYBEGIN CATCHSELECT ERROR_NUMBER() AS ErrNum, ERROR_MESSAGE() AS ErrMsg;END CATCH;If the first INSERT statement succeeds but a subsequent INSERT statement fails, the new row in thedbo.SimpleOrders table will persist after the end of the batch, even after the execution branches to theCATCH block. This issue applies to any successful statements, if a later statement fails with a runtime error.Note Remember that syntax or name-resolution errors cause the entire batch to return anerror, preventing any execution. Runtime errors only occur once the batch has beensubmitted, parsed, planned, and compiled for execution.To work around this situation, you will need to direct <strong>SQL</strong> Server to treat the batch as a transaction. Youwill learn more about creating transactions in the next topic.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server 19-7Transactions Extend BatchesAs you have seen, runtime errors encountered during the execution of simple batches create thepossibility of partial success, which is not typically a desired outcome. To address this, you will add codeto identify the batch as a transaction by placing the batch between BEGIN TRANSACTION and COMMITTRANSACTION statements. You will also add error-handling code to roll back the transaction should anerror occur. This error-handling code will undo the partial changes made before the error occurred.The following example shows the addition of TCL commands to address the possibility of an erroroccurring after some work has been performed:BEGIN TRYBEGIN TRANSACTION;INSERT INTO dbo.SimpleOrders(custid, empid, orderdate)VALUES (68,9,'2006-07-15');INSERT INTO dbo.SimpleOrderDetails(orderid,productid,unitprice,qty)VALUES (99, 2,15.20,20);COMMIT TRANSACTION;END TRYBEGIN CATCHSELECT ERROR_NUMBER() AS ErrNum, ERROR_MESSAGE() AS ErrMsg;ROLLBACK TRANSACTION;END CATCH;Within the TRY block, the INSERT statements are wrapped by BEGIN TRANSACTION and COMMITTRANSACTION statements. This identifies the INSERT statements as a single unit of work that mustsucceed or fail together. If no runtime error occurs, the transaction commits, and the result of eachINSERT is allowed to persist in the database.If an error occurs during the execution of the first INSERT statement, the execution branches to theCATCH block, bypassing the second INSERT statement. The ROLLBACK statement in the CATCH blockterminates the transaction, releasing its resources.


19-8 Implementing TransactionsIf an error occurs during the execution of the second INSERT statement, the execution branches to theCATCH block. Because the first INSERT completed successfully and added rows to the dbo.SimpleOrderstable, the ROLLBACK statement is used to undo the successful INSERT operation.Note You will learn how to use the BEGIN TRANSACTION, COMMIT TRANSACTION, andROLLBACK TRANSACTION statements in the next lesson.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server 19-9Demonstration: Transactions and the Database EngineDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_19_PRJ\10774A_19_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


19-10 Implementing TransactionsLesson 2Controlling TransactionsIn order to control how <strong>SQL</strong> Server treats your data modification statements, you need to useTCL statements. By enclosing batches between BEGIN TRANSACTION and COMMIT or ROLLBACKTRANSACTION statements, you will identify the units of work to be performed together and providepoints of recovery in your code.Lesson ObjectivesAfter completing this lesson, you will be able to:• Mark the beginning of units of work with BEGIN TRANSACTION.• Mark successful completion of batches with COMMIT TRANSACTION.• Undo failed transactions with ROLLBACK TRANSACTION.• Describe how to use XACT_ABORT to automatically roll back failed T-<strong>SQL</strong> statements.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server 19-11BEGIN TRANSACTION<strong>SQL</strong> Server will automatically wrap individual data modification statements (e.g., INSERT, UPDATE, andDELETE) in their own transactions, which auto-commit on success and auto-rollback on failure. While thisbehavior is transparent to the user, you have seen the results of this when you have executed a batch ofT-<strong>SQL</strong> statements with partial success. Successful INSERTS have written their values to the target tables,while failed statements have not left values behind.If you need to identify a group of statements as a transactional unit of work, you cannot rely on thisautomatic behavior. Instead, you will need to manually specify the boundaries of the unit. To mark thestart of a transaction, use the BEGIN TRANSACTION statement, which may also be stated as BEGIN TRAN.If you are using T-<strong>SQL</strong> structured exception handling, you will want to begin the transaction inside a TRYblock, so that you may decide, within the exception handler, whether to COMMIT or ROLLBACK thetransaction depending on its outcome.When you identify your own transactions with BEGIN TRANSACTION, consider the following:• Once you initiate a transaction, you must properly end the transaction. Use COMMIT TRANSACTIONon success or ROLLBACK TRANSACTION on failure.• While transactions may be nested, inner transactions will be rolled back, even if committed, if theouter transaction rolls back. Therefore, nested transactions are not typically useful in user code.• Transactions last until a COMMIT TRANSACTION or a ROLLBACK TRANSACTION is issued, or until theoriginating connection is dropped, at which point <strong>SQL</strong> Server will roll the transaction backautomatically.• A transaction's scope is the connection in which it was started. Transactions cannot span connections(except by bound sessions, a deprecated feature that is beyond the scope of this course).


19-12 Implementing Transactions• <strong>SQL</strong> Server may take and hold locks on resources during the lifespan of the transaction. To reduceconcurrency issues, consider keeping your transactions as short as possible. See Microsoft course10776: Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases for more information on locking in<strong>SQL</strong> Server.For More Information Additional reading on BEGIN TRANSACTION statements can befound in Books Online at http://go.microsoft.com/fwlink/?LinkId=233920. Guidance on theuse of nested transactions can be found in Books Online athttp://go.microsoft.com/fwlink/?LinkId=243003.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server 19-13COMMIT TRANSACTIONOnce the statements in your transaction have completed without error, you need to instruct <strong>SQL</strong> Serverto end the transaction, making the modifications permanent and releasing resources that were held onbehalf of the transaction. To do this, use the COMMIT TRANSACTION (or COMMIT TRAN) statement.If you are using T-<strong>SQL</strong> structured exception handling, you will want to COMMIT the transaction inside theTRY block in which you began it.The following example shows the use of COMMIT TRANSACTION to mark a batch as completed:BEGIN TRYBEGIN TRANSACTIONINSERT INTO dbo.SimpleOrders(custid, empid, orderdate)VALUES (68,9,'2006-07-12');INSERT INTO dbo.SimpleOrderDetails(orderid,productid,unitprice,qty)VALUES (1, 2,15.20,20);COMMIT TRANSACTIONEND TRYNote The previous example does not contain logic to determine if the transaction shouldbe committed or rolled back. It is relying on the success of the statements to provide thelogic to implement error handling.


19-14 Implementing TransactionsROLLBACK TRANSACTIONIn order to end a failed transaction, you will use the ROLLBACK command. ROLLBACK undoes anymodifications made to data during the transaction, reverting it to the state it was in when the transactionstarted. This includes rows inserted, deleted, or updated, as well as objects created. ROLLBACK also allows<strong>SQL</strong> Server to release resources, such as locks, held during the transaction's lifespan.If you are using T-<strong>SQL</strong> structured exception handling, you will want to ROLLBACK the transaction insidethe CATCH block that follows the TRY block containing the BEGIN and COMMIT statements.The following example shows the use of the ROLLBACK TRANSACTION statement inside a CATCH block,where the transaction will only be rolled back in case of an error:BEGIN TRYBEGIN TRANSACTION;INSERT INTO dbo.SimpleOrders(custid, empid, orderdate)VALUES (68,9,'2006-07-12');INSERT INTO dbo.SimpleOrderDetails(orderid,productid,unitprice,qty)VALUES (1, 2,15.20,20);COMMIT TRANSACTION;END TRYBEGIN CATCHSELECT ERROR_NUMBER() AS ErrNum, ERROR_MESSAGE() AS ErrMsg;ROLLBACK TRANSACTION;END CATCH;Before issuing a ROLLBACK command, you may wish to test to see if a transaction is active. You can usethe T-<strong>SQL</strong> XACT_STATE function to determine if there is an active transaction to be rolled back. This canhelp avoid errors being raised inside the CATCH block.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server 19-15XACT_STATE returns the following values:XACT_STATE ResultsDescription0 There is no active user transaction.1 The current request has an active, committable, user transaction.-1 The current request has an active user transaction, but an error hasoccurred. The transaction can only be rolled back.The following example shows the use of XACT_STATE to issue a ROLLBACK statement only if thetransaction is active but cannot be committed:BEGIN TRYBEGIN TRANSACTION;INSERT INTO dbo.SimpleOrders(custid, empid, orderdate)VALUES (68,9,'2006-07-12');INSERT INTO dbo.SimpleOrderDetails(orderid,productid,unitprice,qty)VALUES (1, 2,15.20,20);COMMIT TRANSACTION;END TRYBEGIN CATCHSELECT ERROR_NUMBER() AS ErrNum, ERROR_MESSAGE() AS ErrMsg;IF (XACT_STATE()) = -1BEGINROLLBACK TRANSACTION;END;ELSE .... -- provide for other outcomes of XACT_STATE()END CATCH;For More Information See "Transaction Statements (Transact-<strong>SQL</strong>)" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=243002.


19-16 Implementing TransactionsUsing XACT_ABORTAs you have seen, <strong>SQL</strong> Server does not automatically roll back transactions when errors occur. In thismodule, most of the discussion about controlling transactions has assumed the use of TRY / CATCH blocksto perform the logic and either commit or roll back a transaction. For situations in which you are notusing TRY / CATCH blocks, another option exists for automatically rolling back a transaction when an erroroccurs. The XACT_ABORT setting can be used to specify whether <strong>SQL</strong> Server rolls back the currenttransaction when a runtime error occurs during the execution of T-<strong>SQL</strong> code.By default XACT_ABORT is off. Change the XACT_ABORT setting with the SET command:SET XACT_ABORT ON;When SET XACT_ABORT is ON, the entire transaction is terminated and rolled back on error, unless theerror occurs in a TRY block. An error in a TRY block leaves the transaction open but uncommittable,despite the setting of XACT_ABORT.For More Information See Books Online at http://go.microsoft.com/fwlink/?LinkId=233930.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server 19-17Demonstration: Controlling TransactionsDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_19_PRJ\10774A_19_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


19-18 Implementing TransactionsLab: Implementing TransactionsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server 19-197. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft <strong>SQL</strong> Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a junior database developer for Adventure Works who will be creating stored procedures usingcorporate databases stored in <strong>SQL</strong> Server <strong>2012</strong>. In order to create more robust procedures, you will beimplementing transactions in your code.Important When comparing your results with the provided sample outputs, the column orderingand total number of affected rows should always match. However, remember that the order of therows in the output of a query without an ORDER BY clause is not guaranteed. Therefore, the order ofthe rows in the sample outputs may be different than yours. Also, the answer outputs includeabbreviated results.


19-20 Implementing TransactionsExercise 1: Controlling Transactions with BEGIN, COMMIT, and ROLLBACKScenarioThe IT department has supplied different examples of INSERT statements to practice executing multiplestatements inside one transaction. You will practice how to start a transaction, commit or abort it, andreturn the database to its state before the transaction.The main tasks for this exercise are as follows:1. Write code to control the transaction using the BEGIN TRAN and COMMIT statements.2. Issue a ROLLBACK statement to roll back a transaction. Task 1: Commit a transaction• Open the project file F:\10774A_Labs\10774A_19_PRJ\10774A_19_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• The IT department has provided the following T-<strong>SQL</strong> code:INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Johnson', N'Test 1', N'Sales Manager', N'Mr.', '19700101', '20110101',N'Some Address 18', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386) 113322', 2);INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Robertson', N'Test 2', N'Sales Representative', N'Mr.', '19850101','20110601', N'Some Address 22', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386)553344', 10);• This code inserts two rows into the HR.Employees table. By default, <strong>SQL</strong> Server treats each individualstatement as a transaction. In other words, by default, <strong>SQL</strong> Server automatically commits thetransaction at the end of each individual statement. So in this case the default behavior would betwo transactions since you have two INSERT statements. (Do not worry about the details of theINSERT statements because they are only meant to provide sample code for the transaction scenario.)In this example, you would like to control the transaction and execute both INSERT statements insideone transaction.• Before the supplied T-<strong>SQL</strong> code, write a statement to open a transaction. After the suppliedINSERT statements, write a statement to commit the transaction. Highlight all of the T-<strong>SQL</strong> codeand execute it.• Observe and compare the results that you got with the desired results shown in the file52 - Lab Exercise 1 - Task 1_1 Result.txt.• Write a SELECT statement to retrieve the empid, lastname, and firstname columns from theHR.Employees table. Order the employees by the empid column in a descending order. Executethe SELECT statement.• Observe and compare the results that you got with the desired results shown in the file3 - Lab Exercise 1 - Task 1_2 Result.txt. Notice the two new rows in the result set.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server 19-21 Task 2: Delete the previously inserted rows from the HR.Employees table• Execute the provided T-<strong>SQL</strong> code to delete rows inserted from the previous task.DELETE HR.EmployeesWHERE empid IN (10, 11);DBCC CHECKIDENT ('HR.Employees', RESEED, 9);• Note that this is cleanup code that will not be explained in this course. Task 3: Open a transaction and use the ROLLBACK statement• The IT department has provided T-<strong>SQL</strong> code (which happens to the same code as in task 1). Beforethe provided T-<strong>SQL</strong> code, write a statement to start a transaction.• Highlight the written statement and the provided T-<strong>SQL</strong> code, and execute it.• Write a SELECT statement to retrieve the empid, lastname, and firstname columns from theHR.Employees table. Order the employees by the empid column.• Execute the written SELECT statement and notice the two new rows in the result set.• Observe and compare the results that you got with the desired results shown in the file54 - Lab Exercise 1 - Task 3_1 Result.txt.• After the written SELECT statement, write a ROLLBACK statement to cancel the transaction. Executeonly the ROLLBACK statement.• Highlight and again execute the written SELECT statement against the HR.Employees table.• Observe and compare the results that you got with the desired results shown in the file55 - Lab Exercise 1 - Task 3_2 Result.txt. Notice that the two new rows are no longer present in thetable. Task 4: Clear the modifications against the HR.Employees table• Execute the provided T-<strong>SQL</strong> code:DBCC CHECKIDENT ('HR.Employees', RESEED, 9);Results: After this exercise, you should be able to control a transaction using the BEGIN TRAN, COMMIT,and ROLLBACK statements.


19-22 Implementing TransactionsExercise 2: Adding Error Handling to a CATCH BlockScenarioIn the previous module, you learned how to add error handling to T-<strong>SQL</strong> code. Now you will practice howto properly control a transaction by testing to see if an error occurred.The main tasks for this exercise are as follows:1. Execute the provided T-<strong>SQL</strong> code and observe the results.2. Modify the provided T-<strong>SQL</strong> code to properly manage a transaction. Task 1: Observe the provided T-<strong>SQL</strong> code• Open the project file F:\10774A_Labs\10774A_19_PRJ\10774A_19_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• The IT department has provided T-<strong>SQL</strong> code that is similar to the code in the previous exercise:SELECT empid, lastname, firstnameFROM HR.EmployeesORDER BY empid DESC;GOBEGIN TRAN;INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Johnson', N'Test 1', N'Sales Manager', N'Mr.', '19700101', '20110101',N'Some Address 18', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386) 113322', 2);INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Robertson', N'Test 2', N'Sales Representative', N'Mr.', '19850101','10110601', N'Some Address 22', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386)553344', 10);COMMIT TRAN;• Execute only the SELECT statement.• Observe and compare the results that you got with the desired results shown in the file62 - Lab Exercise 2 - Task 1_1 result.txt. Notice the number of employees in the HR.Employees table.• Execute the part of the T-<strong>SQL</strong> code that starts with a BEGIN TRAN statement and ends with theCOMMIT TRAN statement. You will get a conversion error in the second INSERT statement.• Again execute only the SELECT statement.• Observe and compare the results that you got with the desired results shown in the file63 - Lab Exercise 2 - Task 1_2 Result.txt. Notice that although you got an error inside the transactionblock, one new row was added to the HR.Employees table based on the first INSERT statement.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server 19-23 Task 2: Delete the previously inserted row in the HR.Employees table• Execute the provided T-<strong>SQL</strong> code to delete the row inserted from the previous task.DELETE HR.EmployeesWHERE empid IN (10, 11);DBCC CHECKIDENT ('HR.Employees', RESEED, 9); Task 3: Abort both INSERT statements if an error occurs• Modify the provided T-<strong>SQL</strong> code to include a TRY / CATCH block that rolls back the entire transactionif any of the INSERT statements throws an error:BEGIN TRAN;INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Johnson', N'Test 1', N'Sales Manager', N'Mr.', '19700101', '20110101',N'Some Address 18', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386) 113322', 2);INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Robertson', N'Test 2', N'Sales Representative', N'Mr.', '19850101','10110601', N'Some Address 22', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386)553344', 10);COMMIT TRAN;• In the CATCH block, include a PRINT statement that prints the message “Rollback the transaction…” ifan error occurred and the message “Commit the transaction…” if no error occurred.• Execute the modified T-<strong>SQL</strong> code.• Observe and compare the results that you got with the recommended results shown in the file64 - Lab Exercise 2 - Task 3_1 Result.txt.• Write a SELECT statement against the HR.Employees table to see if any new rows were inserted (likeyou did in exercise 1). Execute the SELECT statement.• Observe and compare the results that you got with the recommended results shown in the file65 - Lab Exercise 2 - Task 3_2 Result.txt. Task 4: Clear the modifications against the HR.Employees table• Execute the provided T-<strong>SQL</strong> code:DBCC CHECKIDENT ('HR.Employees', RESEED, 9);Results: After this exercise, you should have a basic understanding how to control a transaction inside aTRY / CATCH block to efficiently handle possible errors.


19-24 Implementing TransactionsModule ReviewReview Questions1. What happens to a nested transaction when the outer transaction is rolled back?2. When a runtime error occurs in a transaction and SET XACT_ABORT is ON, is the transaction alwaysautomatically rolled back?


20-1Module 20Improving Query PerformanceContents:Lesson 1: Factors in Query Performance 20-3Lesson 2: Displaying Query Performance Data 20-15Lab: Improving Query Performance 20-24


20-2 Improving Query PerformanceModule OverviewIn this course, you have learned many techniques for retrieving data using T-<strong>SQL</strong> queries. You also needto be aware of the performance impact of your queries. This module presents several key guidelines forwriting well-performing queries, as well as ways to monitor the execution of your queries and their impacton Microsoft® <strong>SQL</strong> Server®.ObjectivesAfter completing this module, you will be able to:• Describe components of well-performing queries.• Describe the role of indexes and statistics in <strong>SQL</strong> Server.• Display and interpret basic query plans.• Display and interpret basic query performance data.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-3Lesson 1Factors in Query Performance<strong>SQL</strong> Server performance is an extremely broad set of topics that commonly involve the use of tools andconcepts beyond the scope of this course. In this lesson, you will learn about those aspects of <strong>SQL</strong> Serverperformance that pertain to writing well-performing queries. You will also learn about the basics ofindexes, distribution statistics, and how to avoid cursors in your queries.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe components of well-performing queries.• Describe how <strong>SQL</strong> Server uses clustered and nonclustered indexes.• Describe how <strong>SQL</strong> Server uses distribution statistics.• Compare the use of cursors to sets in queries.


20-4 Improving Query PerformanceWriting Well-Performing QueriesWhile <strong>SQL</strong> Server performance has many aspects, including CPU, memory, storage subsystems, andnetworks, you can have an impact on server performance even at the level of a single query. Here aresome considerations for writing well-performing queries:• Only retrieve what you need. Asking for more data than you require adds to the I/O footprint of yourquery without adding benefit. Specifically, avoid the use of the * alias to request all columns, and filterrows by providing a WHERE clause.Note In addition to avoiding the use of * for performance reasons, it is recommended thatyou avoid using * to protect your application code from changes to the design of theunderlying tables or views.• Improve the performance of WHERE clauses by avoiding search operators that don’t perform well(such as ) and by avoiding manipulation of column values in the predicate. For example, thefollowing query can be rewritten to avoid manipulating a column in an expression for better searchperformance:SELECT empid, hiredateFROM hr.employeesWHERE DATEDIFF(yy, hiredate, GETDATE())>=8;The following example shows the query rewritten for better search performance. The column hasbeen separated from the function:SELECT empid, hiredateFROM hr.employeesWHERE hiredate


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-5• Minimize the use of temporary tables or table variables in your queries. In this course, you havelearned how to use window functions and table expressions as an alternative to queries that createand populate temporary tables before further manipulating them.• Avoid cursors and other iterative approaches that resemble procedural languages, in favor of setbasedoperations. You will learn more about cursors and avoiding them later in this module.• If your role is that of report writer, consider monitoring the performance of your queries (with toolsyou will learn about in this module) and working with your database administrators to arrange goodindexes that will support your queries. If you will also be acting in a database development oradministration role, you will need to learn more about indexing in <strong>SQL</strong> Server than this course willprovide. See Microsoft course 10776: Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases for moreinformation.• Learn how to address tasks with different query approaches. This will enable you to compare theperformance of each approach and have alternative queries that might perform better than others indiffering conditions, such as when the server load varies.For More Information See "Query Performance" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=243004.


20-6 Improving Query PerformanceIndexing in <strong>SQL</strong> Server<strong>SQL</strong> Server uses indexes to improve the performance of queries when they are searching and filteringrows, and when they are ordering data (e.g., grouping, joining, or sorting). When examining queryperformance, you will find it useful to have a basic understanding of how <strong>SQL</strong> Server uses indexes in orderto interpret the results of query execution plans. Later in this module, you will learn how to view andinterpret query execution plans, which may contain references to index use. This topic is designed tointroduce indexes and provide enough information so you will be able to interpret basic execution plans.Note This lesson is intended only to provide an introduction to indexing concepts. Formore information on index design, creation, and maintenance, see Microsoft course 10776:Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases.When executing a query, <strong>SQL</strong> Server will either read all rows in the source table(s) or use a relevant indexto locate the required data. When no index is defined or none is useful to the query optimizer (due tocolumns indexed, distribution statistics, or other factors), <strong>SQL</strong> Server must examine each row in the table.This is called a table scan. For example, the following query is not selective, so <strong>SQL</strong> Server will scan theentire table to return results:SELECT empid, lastname, firstname, title, hiredateFROM hr.employees;When an index is defined and considered useful by the query optimizer, <strong>SQL</strong> Server can use the index tolocate the data requested by the query. If an individual row location is retrieved by the index, theoperation is called an index seek; if a range of values is retrieved, this is an index scan.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-7The following query is highly selective. If an index is defined and useful to <strong>SQL</strong> Server, such as index onthe empid column, <strong>SQL</strong> Server might use it to perform an index seek to return the results.SELECT empid, lastname, firstname, title, hiredateFROM hr.employeesWHERE empid = 7;Note There are additional considerations beyond the presence or absence of an index todetermine whether <strong>SQL</strong> Server will use an index to solve a query. The purpose of theseexamples is to illustrate the terminology, and not to cover all possible scenarios.


20-8 Improving Query Performance<strong>SQL</strong> Server Index Basics: Clustered IndexesIn <strong>SQL</strong> Server, a table may have no indexes, or it may have one or more indexes. Indexes are not requiredfor data access, although there are some features, such as constraints, that create indexes to support themand cannot be removed without dropping the constraint.If a table has no clustered indexes, it is said to be a heap. In a heap, there is no order to the way thetable's rows are organized.Note For more information on table structures and objects such as data and index pages,see Microsoft course 10776: Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databases.A database developer or administrator may choose to add an index called a clustered index to a table.A clustered index causes the rows in the table to be logically stored in order of the column(s) specifiedin the index, called the index key. (The columns used as the index key in a clustered index are called theclustering key.) Tables with clustered indexes are maintained in index order, and rows are inserted into thecorrect logical location determined by their index key value. Rows are stored with their index key value.Clustered indexes are not stored as separate structures in the database.Since the clustered index determines the order of the rows in the table, only one clustered index ispermitted per table.When <strong>SQL</strong> Server searches for and locates an index key value in the clustered index, it locates data for thatrow as well. No additional navigation is required, except in the case of special data types. Conceptually, atable with a clustered index is like a dictionary, whose terms are the index key. The terms appear in thedictionary in alphabetical order. When you search the dictionary for a term and locate it, you are also atthe definition for the term.For More Information Since there is only one clustered index permitted per table, careshould be taken when choosing the column(s) used as the clustering key. See "CreateClustered Indexes" in Books Online at http://go.microsoft.com/fwlink/?LinkId=243005.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-9<strong>SQL</strong> Server Index Basics: Nonclustered IndexesIn addition to clustered indexes, <strong>SQL</strong> Server supports another type of common index, called anonclustered index. Nonclustered indexes are separate structures that contain one or more columns asa key as well as a pointer back to the source row in the table. Nonclustered indexes may be created ontables that are heaps, or they may be created on tables organized by clustered indexes. The pointerinformation stored in the nonclustered index depends on whether the underlying table is organized asa heap or by a clustered index, but is otherwise transparent to a query.Since the nonclustered index is a separate structure and stores only key data and a pointer, queries thatuse a nonclustered index may require an additional lookup operation before accessing the underlyingdata. Conceptually, a nonclustered index is like a subject index printed at the back of a book, in which asorted list of items appears, along with a page number that points to the location of the subject in themain section of the book. When a key value is located in a nonclustered index, <strong>SQL</strong> Server may use thepointer to locate the data in the table itself.Nonclustered indexes are often added to tables to improve specific query performance and avoidresource-intensive table scans. However, nonclustered indexes require additional disk space for storage,and are updated in real time as the underlying data changes, adding to the duration of transactions. Forthese reasons, database administrators may decide not to add nonclustered indexes on every columnreferenced by a query.For More Information See "Create Nonclustered Indexes" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=233852.


20-10 Improving Query Performance<strong>SQL</strong> Server Indexes: Performance ConsiderationsFor report and query writers, having a basic understanding of indexes will be useful in identifying poorlyperforming queries. In the next lesson, you will learn how to display and interpret query execution plans,which may include symbols indicating index usage. Being able to spot problems with indexes, such asspotting a table scan when you expected an index to be used, can be very helpful in tuning anapplication. Similarly, <strong>SQL</strong> Server might opt to scan an entire table when you expect the use of anonclustered index. Understanding that nonclustered indexes involve an additional lookup operationversus scanning the table in a single pass might help you understand the choices of the optimizer.For More Information See the section "How Indexes are Used by the Query Optimizer"in the topic "Clustered and Nonclustered Indexes Described" in Books Online athttp://go.microsoft.com/fwlink/?LinkId=243006.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-11Distribution Statistics<strong>SQL</strong> Server creates and maintains statistics on the distribution of values in columns in tables. Distributionstatistics are used by the query optimizer to estimate the number of rows involved in a query (selectivity).The optimizer uses this information to help determine the optimal access method for the query. Forexample, statistics about the number of rows in a table might cause <strong>SQL</strong> Server to seek through an indexrather than scan the entire table.By default, distribution statistics are automatically created and maintained by <strong>SQL</strong> Server for:• The leading key column in all indexes• Any column used as a predicate as part of a WHERE clause or JOIN ON clause• Columns used in temp tables (although not in table variables)Administrators and database developers may also manually create statistics and update them manually orby way of scheduled jobs.Note Manually creating, updating, and reviewing statistics is beyond the scope of thiscourse. See Microsoft course 10776: Developing Microsoft® <strong>SQL</strong> Server® <strong>2012</strong> Databasesfor more information.As a query writer, you will be able to see the effect of statistics by viewing estimates in execution plans.Later in this module, you will learn how to view estimated execution plans as well as actual executionplans. Estimated execution plans, as the name might imply, are based on estimates of row counts, derivedfrom the distribution statistics. Large variances between estimated and actual values might indicate aproblem with the estimates, which may be addressed through updating statistics. Being able to bring thisto the attention of the database administrator is a useful skill.For More Information See the technical article "Statistics Used by the Query Optimizer inMicrosoft <strong>SQL</strong> Server 2008" on MSDN at http://go.microsoft.com/fwlink/?LinkId=243007.


20-12 Improving Query PerformanceDefining CursorsSo far in this course, you have learned a set-based approach for working with data in <strong>SQL</strong> Server.However, many people who are new to T-<strong>SQL</strong> come from a procedural development background andseek a familiar methodology for working with one row at a time. In this topic, you will see how cursors canfill that need. However, you should continue to work on developing set-based approaches for mostsituations.<strong>SQL</strong> Server provides server-side cursors (as opposed to client API cursors such as those provided byOLEDB, for example) that allow applications to work with a single row at a time in a certain order, asopposed to the all-at-once, unordered set-based approach.A cursor operates on the result of a SELECT statement and moves through the results, one row at a time.Conceptually, a cursor behaves in a similar fashion to a WHILE loop, cycling through data one step at atime.The general steps for working with a cursor in T-<strong>SQL</strong> are as follows:1. Declare variables to hold the data manipulated by the cursor.2. Declare a variable of type cursor and assign to it the results of a SELECT statement.3. Open the cursor.4. Move to the next row, fetch its data, and operate on it.5. Repeat step 4 until the end of the rows reached.6. Close and de-allocate the cursor.While this approach may present a familiar, granular method for working in <strong>SQL</strong> Server, it is best reservedfor scenarios in which a set-based approach is not feasible.For More Information See Books Online at http://go.microsoft.com/fwlink/?LinkId=242838.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-13Avoiding CursorsWhile cursors do provide a familiar row-at-a-time-in-order methodology to some, generally they shouldbe avoided for most <strong>SQL</strong> Server query tasks. Here are some reasons why you should avoid cursors:• Iterative approaches such as cursors contradict the relational model, which operates on unorderedsets. With sets, you tell <strong>SQL</strong> Server what you want to work with. With cursors you specify how youwant the engine to do the work.• Cursors typically require more code than a set-based approach. Not only is a SELECT statementrequired to supply data to the cursor, but the cursor requires loop management, navigation, andstate-checking code.• Cursors typically incur more overhead than a set operation with comparable output. While the setoperation acts on all rows in the set at once, the cursor must repeat the same row-by-rowmanipulation for each row accessed by the cursor. Cursors can be an order of magnitude slower (ormore) than a set-based operation.Many of the techniques and query components you have learned to use in this course, such as windowingfunctions, can be used in place of cursor code.There are exceptions to this general guidance to avoid cursors. Some operations require row-at-a timeprocessing or require the results of a cursor to populate variables in dynamic <strong>SQL</strong> code. For example,database administrators may use cursors to iterate over a list of databases to build a script to perform amaintenance task. However, the exceptions are just that—exceptions to the best practice of avoidingcursors.


20-14 Improving Query PerformanceDemonstration: Factors in Query PerformanceDemonstration Steps1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_20_PRJ\10774A_20_PRJ.ssmssln and click Open.2. On the View menu, click Solution Explorer.3. Open the 11 – Demonstration A.sql script file.4. Follow the instructions contained within the comments of the script file.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-15Lesson 2Displaying Query Performance DataThe tools that ship with <strong>SQL</strong> Server <strong>2012</strong> provide access to a great deal of system-level information aboutthe execution of your queries. In this lesson, you will learn how to use <strong>SQL</strong> Server Management Studio(SSMS) to display information about query execution plans selected by the <strong>SQL</strong> Server optimizer, as wellas performance data showing elapsed time and resources used by queries.Lesson ObjectivesAfter completing this lesson, you will be able to:• Describe the role of execution plans in <strong>SQL</strong> Server.• Describe the difference between estimated and actual execution plans.• Display graphical query execution plans.• Interpret graphical execution plans.• Display and interpret basic query execution statistics.


20-16 Improving Query PerformanceWhat Is an Execution Plan?When you submit a query to <strong>SQL</strong> Server, the database engine goes through several phases in order toexecute your code. These include parsing (and checking for syntax errors), resolving (and binding to)object names, and optimizing the query. This last phase produces the execution plan for the query, unlessone already exists and was located in <strong>SQL</strong> Server's cache. The execution plan is then used to execute thequery.The execution plan contains information about the objects to be accessed by the query, which indexesexist and are relevant, what operators to use, what joins to perform, and estimates about the number ofrows involved.Note As you learned earlier, the estimated row counts are based on the distributionstatistics where available.<strong>SQL</strong> Server tools, such as SSMS and some T-<strong>SQL</strong> commands, provide access to execution plans for queries.These plans, which are available in several formats, provide insight into how <strong>SQL</strong> Server executes yourqueries. They can help you and your organization make decisions about how queries are written, whichindexes are added, and other tuning techniques.Plan formats include:• Plain text, which is being deprecated in the current version of <strong>SQL</strong> Server.• XML text, which can be saved, shared, and opened in SSMS or any XML editor.• Graphical renderings of XML, which uses icons and other symbols to represent the execution plandata. This lesson will focus on using graphical plans.For More Information Additional reading on execution plans can be found in BooksOnline at http://go.microsoft.com/fwlink/?LinkId=243008.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-17Actual and Estimated Execution PlansSSMS provides convenient access to graphical execution plans through its menu and toolbar. Two types ofplans are accessible: estimated and actual.Estimated execution plans display how <strong>SQL</strong> Server likely would execute the query if it were run. Displayingestimated execution plans does not execute the query. Instead, a graphical plan represents the optimizer'sestimates. Variances may occur between the estimated plan and the final plan used when the query is run,due to factors such as statistics being out of date.Instead of generating a graphical plan to generate an XML representation of an estimated execution plan,you can use the SET SHOWPLAN_XML ON T-<strong>SQL</strong> command, as in the following example:USE T<strong>SQL</strong><strong>2012</strong>;GOSET SHOWPLAN_XML ON;GO-- Execute a query.SELECT custid, ordermonth, qty FROM Sales.CustOrders WHERE custid =4;GOSET SHOWPLAN_XML OFF;The results will appear as a hyperlink in SSMS's results pane. Clicking the link will open a new SSMSdocument window displaying the XML representation of the execution plan. The XML document can besaved. If the document is saved with a .sqlplan extension, SSMS will be associated with it and will interpretit graphically when opened.The actual execution plan displays the plan that was used by the engine. In SSMS, selecting the option toinclude the actual plan does not immediately run the query and display the plan. A toggle is set to displaythe plan with the results when the query is next run within the same SSMS session.


20-18 Improving Query PerformanceViewing Graphical Execution PlansTo display the graphical estimated execution plan in SSMS, follow these steps:1. Enter or select the query text whose plan you wish to view. (As with query execution in SSMS,selecting a portion of text will attempt to produce a plan for the selected portion only. Selectingnothing will operate on all the text in the query window.)2. On the Query menu, click the Display Estimated Execution Plan or Display Estimated Execution Planbutton on the <strong>SQL</strong> Editor toolbar. Ctrl+L is the default keyboard shortcut.3. In the Results tab, switch to the Execution Plan tab.To include the actual execution plan in SSMS, follow these steps:1. Enter or select the query text whose plan you wish to view. (As with query execution in SSMS,selecting a portion of text will attempt to produce a plan for the selected portion only. Selectingnothing will operate on all the text in the query window.)2. On the Query menu, click the Include Actual Execution Plan or Include Actual Execution Plan buttonon the <strong>SQL</strong> Editor toolbar. Ctrl+M is the default keyboard shortcut.3. Execute the query as you would any other query in SSMS: Press F5, click the Execute Query toolbarbutton, or use any other shortcut.4. In the Results tab, switch to the Execution Plan tab.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-19Interpreting the Execution PlanExecution plans can contain information about a wide range of query operations. This topic is designed tointroduce you to some basic operators and concepts to help you tune your queries:• Most execution plans are read from right to left, top to bottom.• Icons represent the logical and physical operations performed by the query, such as joins, sorts, andindex usage. In a SELECT query’s plan, the icon representing the SELECT operator itself will typicallybe the one that is highest and furthest to the left. You might see other operators, depending on thequery you submit. The complete list of operators is too long to include here, but here are somecommon operators:OperatorsJoinScan and SeekLookupDescriptionIncludes nested loops, merges, and hash joins. Indicates <strong>SQL</strong> Server ismatching rows between tables.Indicates <strong>SQL</strong> Server is retrieving rows from tables and indexes. Scan looksat all rows, whereas seek uses an index to find matches.Includes key and RID lookups. Indicates <strong>SQL</strong> Server is finding a single row ofdata.• Percentages indicate the cost of each operator, relative to the total cost of the plan.• Arrows show the path of the data through the operators to the final step. The thickness of the arrows’bodies indicates estimated rowcounts in estimated plans and actual rowcounts in actual plans. Theselines can draw attention to problem areas within the plan. For example, thick lines leading to a highcostoperator could indicate a bottleneck within the query plan.


20-20 Improving Query Performance• Generally, you won’t see differences between the estimated and actual plans, but variances betweenthem might indicate issues with the estimates and therefore possible issues with the statistics. Bringvariances to the attention of your database administrator.For More Information To learn more about the symbols in an execution plan, see BooksOnline at http://go.microsoft.com/fwlink/?LinkId=243009.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-21Displaying Query StatisticsIn addition to execution plan internals, <strong>SQL</strong> Server can return details about the execution of T-<strong>SQL</strong>statements by the use of the SET STATISTICS group of commands:• SET STATISTICS TIME ON|OFF controls the display of metrics about the time taken to prepare andcompile (pre-execution phases) as well as the totals elapsed when the query has completed.• SET STATISTICS IO ON|OFF controls the display of information about the amount of disk (and datacache) activity generated by a query. Results are displayed in units of 8kb data pages, which storetable rows.For example, the following batch enables STATISTICS TIME, runs a SELECT statement, and disablesSTATISTICS TIME:SET STATISTICS TIME ON;GOSELECT orderid, custid, empid, orderdate FROM Sales.Orders;GOSET STATISTICS TIME OFF;GOThe results look like:<strong>SQL</strong> Server parse and compile time:CPU time = 0 ms, elapsed time = 0 ms.(830 row(s) affected)<strong>SQL</strong> Server Execution Times:CPU time = 0 ms, elapsed time = 107 ms.These results indicate that the system spent 0 milliseconds preparing the query (it was likely found in plancache) and 107 milliseconds spent retrieving the results and returning them to the client.


20-22 Improving Query PerformanceNote The values depicted are for illustration only. Actual values will depend on manyfactors, including system performance and caching of plans and data.The following batch enables STATISTICS IO, runs a SELECT statement, displays the I/O statistics, and thendisables STATISTICS IO:SET STATISTICS IO ON;GOSELECT orderid, custid, empid, orderdate FROM Sales.Orders;GOSET STATISTICS IO OFF;GOThe partial results, edited for clarity:(830 row(s) affected)Table 'Orders'. Scan count 1, logical reads 21, physical reads 3These results indicate that the system accessed the Sales.Orders table once and read 21 data pages fromthe data cache and 3 pages from disk.For More Information For more information about data pages and other on-diskstructures in <strong>SQL</strong> Server, see Books Online at http://go.microsoft.com/fwlink/?LinkId=243010. To read more about SET STATISTICS TIME and SET STATISTICS IO,see http://go.microsoft.com/fwlink/?LinkId=243011 and http://go.microsoft.com/fwlink/?LinkId=243012, respectively.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-23Demonstration: Displaying Query Performance Data1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio. In the Connect to Server window, type Proseware in the Servername text box and click Connect. On the File menu, click Open and click Project/Solution.Navigate to F:\10774A_Labs\10774A_20_PRJ\10774A_20_PRJ.ssmssln and click Open.2. From the View menu, click Solution Explorer.3. Open the 21 – Demonstration B.sql script file.4. Follow the instructions contained within the comments of the script file.


20-24 Improving Query PerformanceLab: Improving Query PerformanceLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log onmessage” appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-257. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, type Proseware in the Server name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Microsoft <strong>SQL</strong> Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.Lab ScenarioYou are a junior database developer for Adventure Works who has created reports and procedures usingcorporate databases stored in <strong>SQL</strong> Server <strong>2012</strong>. In order to determine the performance impact of yourqueries on the system, you will use SSMS and T-<strong>SQL</strong> code to monitor your queries as they run in a testenvironment.Important When comparing your results with the provided sample outputs, the column orderingand total number of affected rows should always match. However, remember that the order of therows in the output of a query without an ORDER BY clause is not guaranteed. Therefore, the order ofthe rows in the sample outputs may be different than yours. Also, the answer outputs includeabbreviated results.


20-26 Improving Query PerformanceExercise 1: Viewing Query Execution PlansScenarioThe IT department has supplied T-<strong>SQL</strong> code to generate a sample table with around 100,000 rows to testdifferent execution plans. The data is based on the Sales.Orders table. You will practice how to observe theexecution plan and read basic properties.The main tasks for this exercise are as follows:1. Write a SELECT statement and observe the estimated execution plan and the actual execution plan.2. Write a SELECT statement to retrieve only one row and notice the difference between bothexecution plans. Task 1: Create and populate the sample table Sales.TempOrders• Open the project file F:\10774A_Labs\10774A_20_PRJ\10774A_20_PRJ.ssmssln and the T-<strong>SQL</strong> script51 - Lab Exercise 1.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• The IT department has provided the following T-<strong>SQL</strong> code that creates and populates a sample tablenamed Sales.TempOrders:IF OBJECT_ID('Sales.TempOrders') IS NOT NULLDROP TABLE Sales.TempOrders;SELECTorderid, custid, empid, orderdate, requireddate, shippeddate, shipperid, freight,shipname, shipaddress, shipcity, shipregion, shippostalcode, shipcountryINTO Sales.TempOrdersFROM Sales.Orders AS oCROSS JOIN dbo.Nums AS nWHERE n.n


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-27 Task 3: Analyze the execution plan of another SELECT statement• Copy the previous SELECT statement and modify it to retrieve only one row using a TOP clause.• Show the estimated execution plan.• Compare this execution plan with the one in the previous task. Which operator is new?• Notice the size of the arrows, as the size reflects the number of rows being passed from one operatorto another in the execution plan. Task 4: Graphically compare two execution plans• Copy the written SELECT statement in task 2.• Copy the modified SELECT statement in task 3, putting it after the first copied SELECT statement.• Highlight both statements and show first an estimated and then show an actual execution plan.• Observe the results. Compare the query cost information provided for the SELECT statements.Results: After this exercise, you should be able to display estimated and actual execution plans.


20-28 Improving Query PerformanceExercise 2: Viewing Index Usage and Using SET STATISTICS StatementsScenarioYou will practice how to enable I/O statistics, write two SELECT statements, and observe their executionplans to see how an index was used.The main tasks for this exercise are as follows:1. Create a clustered index and write a SELECT statement.2. Enable I/O statistics and modify the SELECT statement to use a search argument in the WHERE clause. Task 1: Create a clustered index and write a SELECT statement• Open the project file F:\10774A_Labs\10774A_20_PRJ\10774A_20_PRJ.ssmssln and the T-<strong>SQL</strong> script61 - Lab Exercise 2.sql. Ensure that you are connected to the T<strong>SQL</strong><strong>2012</strong> database.• Execute the statement that the IT department provided:CREATE CLUSTERED INDEX CX_Sales_TempOrders_orderdate ON Sales.TempOrders (orderdateASC);This T-<strong>SQL</strong> code generates a clustered index on top of the Sales.TempOrders table.• After the provided T-<strong>SQL</strong> code, write a SELECT statement to retrieve the orderid, custid, andorderdate columns from the Sales.TempOrders table. Filter the result to include only the rows withthe order year equal to 2007 and the order month equal to 6 by executing the YEAR and MONTHfunctions against the orderdate column. Execute the SELECT statement.• Observe and compare the results that you got with the desired results shown in the file62 - Lab Exercise 2 - Task 1 Result.txt.• Show the execution plan. Notice the Clustered Index Scan operator and remember that this is thesame operation as a table scan. (Do not worry if some concepts are hard to grasp at this point. Theywill become clearer when you work more with <strong>SQL</strong> Server, gain experience, and attend moreadvanced training courses.)• Note that although you created an index on the orderdate column, the whole table was scanned insearch of rows that matched your predicate in the WHERE clause. Task 2: Enable I/O statistics to observe the number of needed reads• Enable I/O statistics by executing the SET STATISTICS IO statement.• Copy the written query in task 1 and execute it.• Notice the number of logical reads displayed in the Messages tab. This number is based onI/O statistics.


10774A: <strong>Querying</strong> Microsoft <strong>SQL</strong> Server <strong>2012</strong> 20-29 Task 3: Modify the SELECT statement to use a search argument in the WHERE clause• Copy the written SELECT statement in task 1 and modify it by replacing the existing predicates in theWHERE clause with a range predicate based on the orderdate column. Of course, the result must bethe same. Execute the SELECT statement.• Observe and compare the results that you got with the recommended results shown in the file63 - Lab Exercise 2 - Task 3 Result.txt. Notice the number of logical reads displayed in the Messagestab. It is more than 25 times lower than the previous SELECT statement.• Show the query execution plan. Notice a new operator named Clustered Index Seek. Task 4: Compare both SELECT statements• Copy the written SELECT statement in task 1.• Copy the written SELECT statement in task 3, putting it after the first copied SELECT statement.• Highlight both statements and execute them.• Notice the difference in logical reads. Although the result set is the same, the SELECT statement fromtask 3 scans 25 times less data than the SELECT statement from task 1.• Highlight both statements and show their estimated execution plans. Notice the query cost (relativeto batch) between the statements.• Why is the SELECT statement from task 3 so much faster? Task 5: Remove the created table and disable I/O statistics• Execute the provided T-<strong>SQL</strong> code.Results: After this exercise, you should have a basic understanding how to enable SET STATISTICS optionsand remember to invest time in understanding indexes so that you can write efficient queries.


20-30 Improving Query PerformanceModule ReviewReview Questions1. Why should you avoid the use of * in a SELECT clause?2. How many clustered indexes are permitted per table?3. Which type of execution plan can be displayed without running a query?


L1-1Module 1: Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Lab: Working with <strong>SQL</strong> Server <strong>2012</strong> ToolsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.


L1-2 Module 1: Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>Exercise 1: Working with <strong>SQL</strong> Server Management Studio Task 1: Open Microsoft <strong>SQL</strong> Server Management Studio1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.2. In the Connect to Server window, click Cancel.3. Close the Object Explorer window by clicking the close icon.4. Close the Solution Explorer window by clicking the close icon.5. Open the Object Explorer window by selecting Object Explorer on the View menu (or press F8 onthe keyboard).6. Open the Solution Explorer window by selecting Solution Explorer on the View menu (or pressCtrl+Alt+L on the keyboard). Task 2: Configure the editor settings1. On the Tools menu, select Options to open the Options window in SSMS.2. Expand the Environment option and select Fonts and Colors. In the Show settings for box, selectText Editor and set the font size in the Size box to 14.3. In the left pane, expand the Text Editor option, expand the Transact-<strong>SQL</strong> option, and selectIntelliSense. Under Transact-<strong>SQL</strong> IntelliSense Settings, clear the Enable IntelliSense check box.4. In the left pane, select the Tabs option under Text Editor and Transact-<strong>SQL</strong>. In the Tab frame,change the Tab size property to 6.5. In the left pane, expand Query Results, expand <strong>SQL</strong> Server, and select Results to Grid. Enable theoption Include column headers when copying or saving the results by selecting the check box.6. Accept the changes by clicking the OK button.


Lab: Working with <strong>SQL</strong> Server <strong>2012</strong> Tools L1-3Exercise 2: Creating and Organizing T-<strong>SQL</strong> scripts Task 1: Create a project1. On the File menu, select New and click Project.2. In the New Project window, type MyFirstProject in the Name textbox andF:\10774A_Labs\10774A_01_PRJ in the Location text box. Click the OK button to create the newproject.3. In the Solution Explorer window, right-click the Queries folder under MyFirstProject and selectNew Query.4. Right-click the query file <strong>SQL</strong>Query1.sql under the Queries folder, choose Rename, and typeMyFirstQueryFile.sql as the new name for the file.5. On the File menu, select Save All. Task 2: Add an additional query file1. In the Solution Explorer window, right-click the Queries folder under MyFirstProject and selectNew Query.2. In the Queries folder, right-click the query file <strong>SQL</strong>Query1.sql, choose Rename, and typeMySecondQueryFile.sql as the new name for the file.3. Open Windows Explorer by clicking Start, expanding All Programs, expanding Accessories, andclicking Windows Explorer.4. In Windows Explorer, navigate to the folder F:\10774A_Labs\10774A_01_PRJ\MyFirstProject\MyFirstProject and observe the created files.5. In the Solution Explorer window in SSMS, right-click the query file MySecondQueryFile.sql andselect Remove. When the confirmation dialog appears, click the Remove button.6. In Windows Explorer, press F5 to refresh the Windows Explorer window and notice that the fileMySecondQueryFile.sql is still there.7. In the Solution Explorer window in SSMS, right-click the query file MyFirstQueryFile.sql and selectRemove. When the confirmation dialog appears, click the Delete button.8. In Windows Explorer, press F5 to refresh the Windows Explorer window. Notice that the fileMyFirstQueryFile.sql was deleted from the file system.


L1-4 Module 1: Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong> Task 3: Reopen the created project1. On the File menu, select Save All.2. On the File menu, select Exit to close the project and SSMS.3. Click Start, expand All Programs, expand Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click <strong>SQL</strong> ServerManagement Studio.4. In the Connect to Server window, click Cancel.5. On the File menu, click Open and click Project / Solution. In the Open Project window, select theproject F:\10774A_Labs\10774A_01_PRJ\MyFirstProject\MyFirstProject.ssmssln.6. Click Open.7. In Windows Explorer, navigate to the folder F:\10774A_Labs\10774A_01_PRJ\MyFirstProject\MyFirstProject. Drag the file MySecondQueryFile.sql to the Queries folder in the SolutionExplorer window in SSMS.8. On the File menu, select Save All.


Lab: Working with <strong>SQL</strong> Server <strong>2012</strong> Tools L1-5Exercise 3: Using Books Online Task 1: Launch Books Online1. On the virtual machine, click Start, expand All Programs, expand Microsoft <strong>SQL</strong> Server <strong>2012</strong>,expand Documentation & Community, and click <strong>SQL</strong> Server Documentation.2. In the Microsoft Help Viewer window, click the Help Library Manager icon.3. In the Help Library Manager window, select Choose online or local help.4. Under Set your preferred help experience, click I want to use local help and click the OK buttonto confirm.5. Click the Exit button to leave the Help Library Manager window. Task 2: Search for the SELECT syntax1. In the left pane of the Microsoft Help Viewer, click Index.2. Type SELECT in the text box on the top left side, then find and click the entry SELECT statement[<strong>SQL</strong> Server].3. Browse the SELECT statement’s definition. Click the SELECT Examples (Transact-<strong>SQL</strong>) link underReference in the See Also section. Under the topic A. Using SELECT to retrieve rows and columns,click the link Copy to Clipboard on the Transact-<strong>SQL</strong> tab.4. In the Solution Explorer window in SSMS, right-click the Queries folder under MyFirstProject andselect New Query.5. In the Queries folder, right-click the query file <strong>SQL</strong>Query1.sql, choose Rename, and typeMyThirdQueryFile.sql as the new name for the file.6. Click inside the query window of the file MyThirdQueryFile.sql and select Paste on the Edit menu. Task 3: Use context-sensitive help1. Close Microsoft Help Viewer by clicking the close icon for the window.2. In the query window in SSMS, highlight the ORDER BY clause in the file MyThirdQueryFile.sql andpress the F1 key.3. Browse the ORDER BY definition in Books Online.4. In SSMS, select Save All on the File menu.5. On the File menu, select Exit.


L1-6 Module 1: Introduction to Microsoft <strong>SQL</strong> Server <strong>2012</strong>


L3-7Module 3: Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Lab: Introduction to T-<strong>SQL</strong> <strong>Querying</strong>Lab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• Right-click 10774A-MIA-<strong>SQL</strong>1 in the Virtual Machines list and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L3-8 Module 3: Introduction to T-<strong>SQL</strong> <strong>Querying</strong>11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.13. On the File menu, click Open and click Project / Solution. In the Project Open window, selectproject F:\10774A_Labs\10774A_03_PRJ\10774A_03_PRJ.ssmssln.14. Create and populate database T<strong>SQL</strong><strong>2012</strong>:• For on-premise, database T<strong>SQL</strong><strong>2012</strong> is already created and populated in the VM so no furthersteps are needed. However, if the database was damaged and you would like to create it fromscratch, follow the steps below.• For Microsoft <strong>SQL</strong> Azure, follow the steps below if you haven’t done so already in module 2.15. In Solution Explorer, double-click 00 - Setup.sql. (If Solution Explorer is not visible, select SolutionExplorer on the View menu or press Ctrl+Alt+L on the keyboard.)16. When the query window opens, follow the instructions inside the 00 – Setup.sql to setup theT<strong>SQL</strong><strong>2012</strong> database and populate it with sample data.17. Close <strong>SQL</strong> Server Management Studio.


Lab: Introduction to T-<strong>SQL</strong> <strong>Querying</strong> L3-9Exercise 1: Executing Basic SELECT Statements Task 1: Open the T-<strong>SQL</strong> script using Microsoft <strong>SQL</strong> Server Management Studio1. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.2. In the Connect to Server window, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.3. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database. If the T<strong>SQL</strong><strong>2012</strong> database is not visible please look at thesteps 10 to 16 under Lab Setup.4. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.5. On the File menu, click Open and click Project / Solution. In the Project Open window, selectproject F:\10774A_Labs\10774A_03_PRJ\10774A_03_PRJ.ssmssln.6. In Solution Explorer, double-click 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible, selectSolution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.) Task 2: Execute the T-<strong>SQL</strong> script1. When the query window opens, click the Execute button on the toolbar (or press F5 on thekeyboard).2. If you are using <strong>SQL</strong> Azure you will get an error, because the USE statement is not supported and youmust manually set the database context using the Available Databases box.3. For on-premises Microsoft <strong>SQL</strong> Server you will notice that the T<strong>SQL</strong><strong>2012</strong> database is selected in theAvailable Databases box. The Available Databases box displays the current database context underwhich the T-<strong>SQL</strong> script will run. This information is also visible on the status bar.


L3-10 Module 3: Introduction to T-<strong>SQL</strong> <strong>Querying</strong> Task 3: Execute a part of the T-<strong>SQL</strong> script1. Highlight the following statement under the task 2 description:SELECTfirstname, lastname, city, countryFROM HR.Employees;To highlight it, you can move the pointer over the statement while pressing the left mouse button oruse the arrow keys to move the pointer while pressing the Shift key.2. Click Execute (or press F5). It is very important to understand that you can highlight a specific part ofthe code inside the T-<strong>SQL</strong> script and execute only that part. If you click Execute without selecting anypart of the code, the whole T-<strong>SQL</strong> script will be executed. If you highlight a specific part of the codeby mistake, the <strong>SQL</strong> Server will attempt to run only that part.


Lab: Introduction to T-<strong>SQL</strong> <strong>Querying</strong> L3-11Exercise 2: Executing Queries That Filter Data Using Predicates Task 1: Execute the T-<strong>SQL</strong> script1. Close <strong>SQL</strong> Server Management Studio.2. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.3. In the Connect to Server window, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.4. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database. If the T<strong>SQL</strong><strong>2012</strong> database is not visible please look at thesteps 10 to 16 under Lab Setup.5. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.6. On the File menu, click Open and click Project / Solution. In the Project Open window, selectproject F:\10774A_Labs\10774A_03_PRJ\10774A_03_PRJ.ssmssln.7. In Solution Explorer, double-click 61 - Lab Exercise 2.sql.8. When the query window opens, click Execute.9. Notice that you get the error message:Invalid object name 'HR.Employees'.Why do you think you got this error? This error is very common when you are beginning to learnT-<strong>SQL</strong>. The message tells you that <strong>SQL</strong> Server could not find the object HR.Employees. This is becausethe current database context is set to the master database (look at the Available Databases boxwhere the current database is displayed), but the IT department supplied T-<strong>SQL</strong> scripts to be runagainst the T<strong>SQL</strong><strong>2012</strong> database. So, you need to change the database context from master toT<strong>SQL</strong><strong>2012</strong>. You will learn how to change the database context in the next task. Task 2: Apply the needed changes and execute the T-<strong>SQL</strong> script1. In the Available Databases box, select T<strong>SQL</strong><strong>2012</strong> to change the database context.2. Click Execute.3. Notice that the result from the SELECT statement returns fewer rows than the one in exercise 1. Thatis because it has a predicate in the WHERE clause to filter out all rows that do not have the value USAin the column country. Only rows for which the logical expression evaluates to TRUE are returned bythe WHERE phase to the subsequent logical query processing phase.


L3-12 Module 3: Introduction to T-<strong>SQL</strong> <strong>Querying</strong> Task 3: Uncomment the USE statement1. In the script 61 - Lab Exercise 2.sql, find the line:-- USE T<strong>SQL</strong><strong>2012</strong>;2. Delete the first two characters, so that the line looks like this:USE T<strong>SQL</strong><strong>2012</strong>;By deleting these two characters, you have removed the comment mark. Now the line will not beignored by <strong>SQL</strong> Server.3. On the File menu, click Save 61 - Lab Exercise 2.sql.4. On the File menu, click Close. This will close the T-<strong>SQL</strong> script.5. In Solution Explorer, double-click 61 - Lab Exercise 2.sql.6. Click Execute. Again notice that you got an error if using <strong>SQL</strong> Azure.7. If using on-premises <strong>SQL</strong> Server, observe the results. Why did the script executed with no errors? Thescript now includes the uncommented USE T<strong>SQL</strong><strong>2012</strong>; statement. When you execute the whole T-<strong>SQL</strong>script, the USE statement applies the database context to the T<strong>SQL</strong><strong>2012</strong> database. The next statementin the T-<strong>SQL</strong> script then executes against the T<strong>SQL</strong><strong>2012</strong> database.


Lab: Introduction to T-<strong>SQL</strong> <strong>Querying</strong> L3-13Exercise 3: Executing Queries That Sort Data Using ORDER BY Task 1: Execute the T-<strong>SQL</strong> script1. In Solution Explorer, double-click 71 - Lab Exercise 3.sql.2. Click Execute.3. Notice that the result window is empty. All the statements inside the T-<strong>SQL</strong> script are commentedout, so <strong>SQL</strong> Server ignores all the statements inside the T-<strong>SQL</strong> script. Task 2: Uncomment the needed T-<strong>SQL</strong> statements and execute them1. Locate the line:-- USE T<strong>SQL</strong><strong>2012</strong>;2. Delete the two characters before the USE statement. The line should now look like this:USE T<strong>SQL</strong><strong>2012</strong>;3. Locate the block comment start element /* after the task 1 description and delete it.4. Locate the block comment end element */ and delete it. Any text residing within a block starting with/* and ending with */ is treated as a block comment and is ignored by <strong>SQL</strong> Server.5. Highlight the statement:USE T<strong>SQL</strong><strong>2012</strong>;Click Execute. The database context is now changed to the T<strong>SQL</strong><strong>2012</strong> database.6. Highlight the statement:SELECTfirstname, lastname, city, countryFROM HR.EmployeesWHERE country = 'USA'ORDER BY lastname;Click Execute.7. Observe the result and notice that the rows are sorted by the lastname column in ascending order.


L3-14 Module 3: Introduction to T-<strong>SQL</strong> <strong>Querying</strong>


L4-15Module 4: Writing SELECT QueriesLab: Writing Basic SELECT StatementsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, click the Cancel button.


L4-16 Module 4: Writing SELECT QueriesExercise 1: Writing Simple SELECT Statements Task 1: View all the tables in the T<strong>SQL</strong><strong>2012</strong> database in Object Explorer1. In Object Explorer, click Connect and select Database Engine. (If Object Explorer is not visible, selectObject Explorer on the View menu or press F8 on the keyboard.)2. In the Connect to Server window, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box (ask yourinstructor for a current list of Microsoft <strong>SQL</strong> Azure enabled labs).3. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.4. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.5. In Object Explorer, expand the server Proseware (if using an on-premises Microsoft <strong>SQL</strong> Serverinstance) or expand the Azure <strong>SQL</strong> server, expand Databases, expand the database T<strong>SQL</strong><strong>2012</strong>, andexpand Tables.6. Under Tables, notice that there are four table objects in the Sales schema:• Sales.Customers• Sales.OrderDetails• Sales.Orders• Sales.Shippers Task 2: Write a simple SELECT statement1. On the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_04_PRJ\10774A_04_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If you are using <strong>SQL</strong> Azure you will get an error, because theUSE statement is not supported and you must manually set the database context using the AvailableDatabases box.


Lab: Writing Basic SELECT Statements L4-17It is very important to understand that you can highlight a specific part of the code inside the T-<strong>SQL</strong>script and execute it. If you click Execute on the toolbar without selecting any part of the code, thewhole T-<strong>SQL</strong> script will be executed.Tip One way to highlight a portion of code is to hold down the Alt key while drawing arectangle around it with your mouse. The code inside the drawn rectangle will be selected.5. In the query pane, type the following query after the task 2 description:SELECT*FROM Sales.Customers;Note that when writing production queries, the best practice is to avoid using the * argument toreturn all columns and instead specify only the needed columns. However, since you are learning towrite queries, it is fine to use * for your first query. Later on, you should use * only when you aredoing some testing or ad-hoc querying. You should never use * in production code.One way to enumerate all columns using <strong>SQL</strong> Server Management Studio is to expand the <strong>SQL</strong><strong>2012</strong>database in Object Explorer, expand the Sales.Customers table, drag the Columns folder into thequery window, and drop it right after the SELECT clause. Your query would then look like this:SELECTcustid, companyname, contactname, contacttitle, address, city, region, postalcode,country, phone, faxFROM Sales.Customers;6. Highlight the query you typed in step 5 and click Execute.7. In the query pane, type the following code after the first query:SELECT*FROM8. In Object Explorer, select the Sales.Customers table under Proseware (if using an on-premisesMicrosoft <strong>SQL</strong> Server instance) or under connected Azure <strong>SQL</strong> server, T<strong>SQL</strong><strong>2012</strong>, Tables. Using themouse, drag the selected table to the query pane and drop it after the FROM clause. Add a semicolonto the end of the SELECT statement. It is important to terminate all of your T-<strong>SQL</strong> statements with asemicolon. This is considered a best practice, is a requirement of standard <strong>SQL</strong>, and will likely becomemandatory for all T-<strong>SQL</strong> statements in a future version of Microsoft <strong>SQL</strong> Server. Your result shouldlook like this:SELECT*FROM [Sales].[Customers];9. Highlight the written query and click Execute.


L4-18 Module 4: Writing SELECT Queries Task 3: Write a SELECT statement that includes specific columns1. In Object Explorer, expand the Sales.Customers table under Proseware (if using an on-premisesMicrosoft <strong>SQL</strong> Server instance) or under connected Azure <strong>SQL</strong> server, T<strong>SQL</strong><strong>2012</strong>, Tables.2. Expand Columns and observe all the columns in the Sales.Customers table.3. In the query pane, type the following query after the task 3 description:SELECTcontactname, address, postalcode, city, countryFROM Sales.Customers;4. Highlight the written query and click Execute.5. Observe the result. How many rows are affected by the last query? There are multiple ways to answerthis question using <strong>SQL</strong> Server Management Studio. One way is to select the previous query and clickExecute. The total number of rows affected by the executed query is written in the Results paneunder the Messages tab:(91 row(s) affected)Another way is to look at the status bar displayed below the Results pane. On the left side of thestatus bar, there is a message stating “Query executed successfully.” On the right side, the totalnumber of rows affected by the current query is displayed (91 rows).


Lab: Writing Basic SELECT Statements L4-19Exercise 2: Eliminating Duplicates Using DISTINCT Task 1: Write a SELECT statement that includes a specific column1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTcountryFROM Sales.Customers;4. Highlight the written query and click Execute.5. Observe that you have multiple rows with the same values. This occurs because the Sales.Customerstable has multiple rows with the same value for the country column. Task 2: Write a SELECT statement that uses the DISTINCT clause1. Highlight the previous query. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 2 description. On the toolbar, click Edit and thenPaste. You have now copied the previous query to the same query window after the task 2description.3. Modify the query by typing DISTINCT after the SELECT clause. Your query should look like this:SELECT DISTINCTcountryFROM Sales.Customers;4. Highlight the written query and click Execute.5. Observe the result and answer these questions:• How many rows did the query in task 1 return?To answer this question, you can highlight the query written under the task 1 description, clickExecute, and read the Results pane. (If you forgot how to access this pane, look at task 4 inexercise 1.) The number of rows affected by the query is 91.• How many rows did the query in Task 2 return?To answer this question, you can highlight the query written under the task 2 description, clickExecute, and read the Results pane. The number of rows affected by the query is 21. This meansthat there are 21 distinct values for the country column in the Sales.Customers table.• Under which circumstances do the following queries against the Sales.Customers table return thesame result?SELECT city, region FROM Sales.Customers;SELECT DISTINCT city, region FROM Sales.Customers;Both queries would return the same number of rows if all combinations of values in the city andregion columns in the Sales.Customers table are unique. If they are not unique, the first querywould return more rows than the second one with the DISTINCT clause.


L4-20 Module 4: Writing SELECT Queries• Is the DISTINCT clause applied to all columns specified in the query or just the first column?The DISTINCT clause is always applied to all columns specified in the SELECT list. It is veryimportant to remember that the DISTINCT clause does not apply to just the first column in thelist.


Lab: Writing Basic SELECT Statements L4-21Exercise 3: Using Table and Column Aliases Task 1: Write a SELECT statement that uses a table alias1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTc.contactname, c.contacttitleFROM Sales.Customers AS c;Tip To use the IntelliSense feature when entering column names in a SELECT statement,you can use keyboard shortcuts. To enable IntelliSense, press Ctrl+Q+I. To list all of the aliasmembers, position your pointer after the alias and dot (e.g., after “c.”) and press Ctrl+J.4. Highlight the written query and click Execute. Task 2: Write a SELECT statement that uses a column alias1. In the query pane, type the following query after the task 2 description:SELECTc.contactname AS Name, c.contacttitle AS Title, c.companyname AS [Company Name]FROM Sales.Customers AS c;Observe that the column alias [Company Name] is enclosed in square brackets. Column names andcolumn aliases that have embedded spaces or reserved keywords must be delimited. This exampleuses square brackets as the delimiter, but you can also use the ANSI <strong>SQL</strong> standard delimiter of doublequotes, as in “Company Name”.2. Highlight the written query and click Execute. Task 3: Write a SELECT statement that uses a table alias and a column alias1. In the query pane, type the following query after the task 3 description:SELECTp.productname AS [Product Name]FROM Production.Products AS p;2. Highlight the written query and click Execute.


L4-22 Module 4: Writing SELECT Queries Task 4: Analyze and correct the query1. Highlight the written query under the task 4 description and click Execute.2. Observe the result. Note that only one column is retrieved. The problem is that the developer forgotto add a comma after the first column name, so <strong>SQL</strong> Server treated the second word after the firstcolumn name as an alias. For this reason, it is a best practice to always use AS when specifying aliases.That way, it is easier to spot such errors.3. Correct the query by adding a comma after the first column name. The corrected query should looklike this:SELECTcity, countryFROM Sales.Customers;


Lab: Writing Basic SELECT Statements L4-23Exercise 4: Using a Simple CASE Expression Task 1: Write a SELECT statement1. In Solution Explorer, double-click the query 81 - Lab Exercise 4.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTp.categoryid, p.productnameFROM Production.Products AS p;4. Highlight the written query and click Execute. Task 2: Write a SELECT statement that uses a CASE expression1. In the query pane, type the following query after the task 2 description:SELECTp.categoryid, p.productname,CASEWHEN p.categoryid = 1 THEN 'Beverages'WHEN p.categoryid = 2 THEN 'Condiments'WHEN p.categoryid = 3 THEN 'Confections'WHEN p.categoryid = 4 THEN 'Dairy Products'WHEN p.categoryid = 5 THEN 'Grains/Cereals'WHEN p.categoryid = 6 THEN 'Meat/Poultry'WHEN p.categoryid = 7 THEN 'Produce'WHEN p.categoryid = 8 THEN 'Seafood'ELSE 'Other'END AS categorynameFROM Production.Products AS p;This query uses a CASE expression to add a new column. Note that when you have a dynamic list ofpossible values, you usually store them in a separate table. However, for this example, a static list ofvalues is being supplied.2. Highlight the written query and click Execute.


L4-24 Module 4: Writing SELECT Queries Task 3: Write a SELECT statement that uses a CASE expression to differentiatecampaign-focused products1. Highlight the previous query. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 3 description. On the toolbar, click Edit and thenPaste. You have now copied the previous query to the same query window after the task 3description.3. Add a new column using an additional CASE expression. Your query should look like this:SELECTp.categoryid, p.productname,CASEWHEN p.categoryid = 1 THEN 'Beverages'WHEN p.categoryid = 2 THEN 'Condiments'WHEN p.categoryid = 3 THEN 'Confections'WHEN p.categoryid = 4 THEN 'Dairy Products'WHEN p.categoryid = 5 THEN 'Grains/Cereals'WHEN p.categoryid = 6 THEN 'Meat/Poultry'WHEN p.categoryid = 7 THEN 'Produce'WHEN p.categoryid = 8 THEN 'Seafood'ELSE 'Other'END AS categoryname,CASEWHEN p.categoryid IN (1, 7, 8) THEN 'Campaign Products'ELSE 'Non-Campaign Products'END AS iscampaignFROM Production.Products AS p;4. Highlight the written query and click Execute.5. In the result, observe that the first CASE expression uses the simple form whereas the second uses thesearched form.


L5-25Module 5: <strong>Querying</strong> Multiple TablesLab: <strong>Querying</strong> Multiple TablesLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If the user is not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L5-26 Module 5: <strong>Querying</strong> Multiple Tables11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: <strong>Querying</strong> Multiple Tables L5-27Exercise 1: Writing Queries That Use Inner Joins Task 1: Write a SELECT statement that uses an inner join1. On the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_05_PRJ\10774A_05_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If you are using <strong>SQL</strong> Azure you will get an error, because theUSE statement is not supported and you must manually set the database context using the AvailableDatabases box.5. In the query pane, type the following query after the task 1 description:SELECTp.productname, c.categorynameFROM Production.Products AS pINNER JOIN Production.Categories AS c ON p.categoryid = c.categoryid;6. Highlight the written query and click Execute.7. Observe the result and answer these questions:• Which column did you specify as a predicate in the ON clause of the join? Why?In this query, the categoryid column is the predicate. By intuition, most people would say that itis the predicate because this column exists in both input tables. By the way, using the same namefor columns that contain the same data but in different tables is a good practice in datamodeling. Another possibility is to check for referential integrity trough primary and foreign keyinformation using <strong>SQL</strong> Server Management Studio. If there are no primary or foreign keyconstraints, you will have to acquire information about the data model from the developer.• Let us say that there is a new row in the Production.Categories table and this new productcategory does not have any products associated with it in the Production.Products table. Wouldthis row be included in the result of the SELECT statement written under the task 1 description?No, because an inner join retrieves only the matching rows based on the predicate from bothinput tables. Since the new value for the categoryid is not present in the categoryid column in theProduction.Products table, there would be no matching rows in the result of the SELECTstatement.


L5-28 Module 5: <strong>Querying</strong> Multiple TablesExercise 2: Writing Queries That Use Multiple-Table Inner Joins Task 1: Execute the T-<strong>SQL</strong> statement1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. Highlight the written query under the task 1 description and click Execute.4. Observe that you get the error message:Ambiguous column name 'custid'.This error occurred because the custid column appears in both tables and you have to specify fromwhich table you would like to retrieve the column values. Task 2: Apply the needed changes and execute the T-<strong>SQL</strong> statement1. Add the column prefix “Customers” to the existing query so that it looks like this:SELECTCustomers.custid, contactname, orderidFROM Sales.CustomersINNER JOIN Sales.Orders ON Customers.custid = Orders.custid;2. Highlight the modified query and click Execute. Task 3: Change the table aliases1. Highlight the previous query. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 3 description. On the toolbar, click Edit and thenPaste. You have now copied the previous query to the same query window after the task 3description.3. Modify the T-<strong>SQL</strong> statement to use table aliases. Your query should look like this:SELECTc.custid, c.contactname, o.orderidFROM Sales.Customers AS cINNER JOIN Sales.Orders AS o ON c.custid = o.custid;4. Modify the T-<strong>SQL</strong> statement to include a full source table name as the column prefix. Your queryshould now look like this:SELECTCustomers.custid, Customers.contactname, Orders.orderidFROM Sales.Customers AS cINNER JOIN Sales.Orders AS o ON c.custid = o.custid;5. Highlight the written query and click Execute.


Lab: <strong>Querying</strong> Multiple Tables L5-296. Observe that you get the error messages:Msg 4104, Level 16, State 1, Line 2The multi-part identifier "Customers.custid" could not be bound.Msg 4104, Level 16, State 1, Line 2The multi-part identifier "Customers.contactname" could not be bound.Msg 4104, Level 16, State 1, Line 2The multi-part identifier "Orders.orderid" could not be bound.You received these error messages because the full source table name you are referencing as acolumn prefix no longer exists, as you are using a different table alias. Remember that the SELECTclause is evaluated after the FROM clause, so you have to use the table aliases when specifyingcolumns in the SELECT clause.7. Modify the SELECT statement so that it uses the correct table aliases. Your query should look like this:SELECTc.custid, c.contactname, o.orderidFROM Sales.Customers AS cINNER JOIN Sales.Orders AS o ON c.custid = o.custid; Task 4: Add an additional table and columns1. In the query pane, type the following query after the task 4 description:SELECTc.custid, c.contactname, o.orderid, d.productid, d.qty, d.unitpriceFROM Sales.Customers AS cINNER JOIN Sales.Orders AS o ON c.custid = o.custidINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderid;2. Highlight the written query and click Execute.3. Observe the result. Remember that when you have a multiple-table inner join, the logical queryprocessing is different from the physical implementation. In this case, it means that you cannotguarantee the order in which the <strong>SQL</strong> Server optimizer will process the tables. For example, youcannot guarantee that the Sales.Customers table will be joined first with the Sales.Orders table andthen with the Sales.OrderDetails table.


L5-30 Module 5: <strong>Querying</strong> Multiple TablesExercise 3: Writing Queries That Use Self-Joins Task 1: Write a basic SELECT statement1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTe.empid, e.lastname, e.firstname, e.title, e.mgridFROM HR.Employees AS e;4. Highlight the written query and click Execute.5. Observe that the query retrieved nine rows. Task 2: Write a SELECT statement that uses a self-join1. Highlight the previous query. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 2 description. On the toolbar, click Edit and thenPaste. You have now copied the previous query to the same query window after the task 2description.3. Modify the query by adding a self-join to get information about the managers. The query should looklike this:SELECTe.empid, e.lastname, e.firstname, e.title, e.mgrid,m.lastname AS mgrlastname, m.firstname AS mgrfirstnameFROM HR.Employees AS eINNER JOIN HR.Employees AS m ON e.mgrid = m.empid;4. Highlight the written query and click Execute.5. Observe that the query retrieved eight rows and answer these questions:• Is it mandatory to use table aliases when writing a statement with a self-join? Can you use a fullsource table name as an alias?You must use table aliases. You cannot use the full source table name as an alias whenreferencing both input tables. Eventually, you could use a full source table name as an alias forone input table and some other alias for the second input table.• Why did you get fewer rows in the result from the T-<strong>SQL</strong> statement under the task 2 descriptioncompared to result from the T-<strong>SQL</strong> statement under the task 1 description?In task 2’s T-<strong>SQL</strong> statement, the inner join used an ON clause based on manager information(column mgrid). The employee who is the CEO has a missing value in the mgrid column. Thus,this row is not included in the result.


Lab: <strong>Querying</strong> Multiple Tables L5-31Exercise 4: Writing Queries That Use Outer Joins Task 1: Write a SELECT statement that uses an outer join1. In Solution Explorer, double-click the query 81 - Lab Exercise 4.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTc.custid, c.contactname, o.orderidFROM Sales.Customers AS cLEFT OUTER JOIN Sales.Orders AS o ON c.custid = o.custid;4. Highlight the written query and click Execute.5. Inspect the result. Notice that the custid 22 and custid 57 rows have a missing value in the orderidcolumn. This is because there are no rows in the Sales.Orders table for these two values of the custidcolumn. In business terms, this means that there are currently no orders for these two customers.


L5-32 Module 5: <strong>Querying</strong> Multiple TablesExercise 5: Writing Queries That Use Cross Joins Task 1: Execute the T-<strong>SQL</strong> statement1. In Solution Explorer, double-click the query 91 - Lab Exercise 5.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. Highlight the T-<strong>SQL</strong> code under the task 1 description and click Execute. Do not worry if you do notunderstand the provided T-<strong>SQL</strong> code, as it is used here to provide a more realistic example for a crossjoin in the next task. Task 2: Write a SELECT statement that uses a cross join1. In the query pane, type the following query after task 2 description:SELECTe.empid, e.firstname, e.lastname, c.calendardateFROM HR.Employees AS eCROSS JOIN HR.Calendar AS c;2. Highlight the written query and click Execute.3. Observe that the query retrieved 3285 rows and that there are 9 rows in the HR.Employees table.Because a cross join produces a Cartesian product of both inputs, it means that there are 365 (3285/9)rows in the HR.Calendar table. Task 3: Drop the HR.Calendar table• Highlight the written query under the task 3 description and click Execute.


L6-33Module 6: Sorting and Filtering DataLab: Filtering and Sorting DataLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.11. In the Connect to Server window, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.


L6-34 Module 6: Sorting and Filtering Data12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Filtering and Sorting Data L6-35Exercise 1: Writing Queries That Filter Data Using a WHERE Clause Task 1: Write a SELECT statement that uses a WHERE clause1. On the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_06_PRJ\10774A_06_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If you are using <strong>SQL</strong> Azure you will get an error, because theUSE statement is not supported and you must manually set the database context using the AvailableDatabases box.5. In the query pane, type the following query after the task 1 description:SELECTcustid, companyname, contactname, address, city, country, phoneFROM Sales.CustomersWHEREcountry = N'Brazil';Notice the use of the N prefix for the character literal. This prefix is used because the country columnis a Unicode data type. When expressing a Unicode character literal, you need to specify the characterN (for National) as a prefix. You will learn more about data types in the next module.6. Highlight the written query and click Execute. Task 2: Write a SELECT statement that uses an IN predicate in the WHERE clause1. In the query pane, type the following query after the task 2 description:SELECTcustid, companyname, contactname, address, city, country, phoneFROM Sales.CustomersWHEREcountry IN (N'Brazil', N'UK', N'USA');2. Highlight the written query and click Execute. Task 3: Write a SELECT statement that uses a LIKE predicate in the WHERE clause1. In the query pane, type the following query after the task 3 description:SELECTcustid, companyname, contactname, address, city, country, phoneFROM Sales.CustomersWHEREcontactname LIKE N'A%';Remember that the percent sign (%) wildcard represents a string of any size (including an emptystring), whereas the underscore (_) wildcard represents a single character.2. Highlight the written query and click Execute.


L6-36 Module 6: Sorting and Filtering Data Task 4: Observe the T-<strong>SQL</strong> statement provided by the IT department1. Highlight the T-<strong>SQL</strong> statement provided under the task 4 description and click Execute.2. Highlight the provided T-<strong>SQL</strong> statement. On the toolbar, click Edit and then Copy.3. In the query window, click the line after the task 4 description. On the toolbar, click Edit and thenPaste. You have now copied the previous query to the same query window after the task 4description.4. Modify the query so that it looks like this:SELECTc.custid, c.companyname, o.orderidFROM Sales.Customers AS cLEFT OUTER JOIN Sales.Orders AS o ON c.custid = o.custidWHEREc.city = N'Paris';5. Highlight the modified query and click Execute.6. Observe the result. Is it the same as the result of the first <strong>SQL</strong> statement? The result is not the same.When you specify the predicate in the ON clause, the left outer join preserves all the rows from theleft table (Sales.Customers) and adds only the matching rows from the right table (Sales.Orders) basedon the predicate in the ON clause. This means that all the customers will show up in the output, butonly the customers from Paris will have matching orders. When you specify the predicate in theWHERE clause, the query will filter only the customers from Paris. So, be aware that when you use anouter join, the result of a query in which the predicate is specified in the ON clause can differ fromthe result of a query in which the predicate is specified in the WHERE clause. (When using an innerjoin, the results are always the same.) This is because the ON predicate is a matching predicate—itdefines which rows from the nonpreserved side to match to the rows from the preserved side. TheWHERE predicate is a filtering predicate—if a row from either side doesn’t satisfy the WHEREpredicate, the row is filtered out.


Lab: Filtering and Sorting Data L6-37 Task 5: Write a SELECT statement to retrieve those customers without orders1. In the query pane, type the following query after the task 5 description:SELECTc.custid, c.companynameFROM Sales.Customers AS cLEFT OUTER JOIN Sales.Orders AS o ON c.custid = o.custidWHERE o.custid IS NULL;It is important to note that when you are looking for a NULL, you should use the IS NULL operatorand not the equality operator. The equality operator will always return UNKNOWN when youcompare something to a NULL. It will even return UNKNOWN when you compare two NULLs.The choice of which attribute to filter from the nonpreserved side of the join is also important. Youshould choose an attribute that can only have a NULL when the row is an outer row (e.g., a NULLoriginating from the base table). For this purpose, three cases are safe to consider:• A primary key column. A primary key column cannot be NULL. Therefore, a NULL in such acolumn can only mean that the row is an outer row.• A join column. If a row has a NULL in the join column, that row is filtered out by the secondphase of the join. So, a NULL in such a column can only mean that it is an outer row.• A column defined as NOT NULL. A NULL in a column that is defined as NOT NULL can only meanthat the row is an outer row.2. Highlight the written query and click Execute.


L6-38 Module 6: Sorting and Filtering DataExercise 2: Writing Queries That Sort Data Using an ORDER BY Clause Task 1: Write a SELECT statement that uses an ORDER BY clause1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTc.custid, c.contactname, o.orderid, o.orderdateFROM Sales.Customers AS cINNER JOIN Sales.Orders AS o ON c.custid = o.custidWHEREo.orderdate >= '20080401'ORDER BYo.orderdate DESC, c.custid ASC;Notice the date filter. It uses a literal (constant) of a date. <strong>SQL</strong> Server recognizes the literal '20080401'as a character string literal and not as a date and time literal, but because the expression involves twooperands of different types, one operand needs to be implicitly converted to the other’s type. In thisexample, the character string literal is converted to the column’s data type (DATETIME) becausecharacter strings are considered lower in terms of data type precedence with respect to date and timedata types.Also notice that the character string literal follows the format 'yyyymmdd'. Using this format is a bestpractice because <strong>SQL</strong> Server knows how to convert it to the correct date, regardless of the languagesettings.4. Highlight the written query and click Execute. Task 2: Apply the needed changes and execute the T-<strong>SQL</strong> statement1. Highlight the written query under the task 2 description and click Execute.2. Observe the error message:Invalid column name 'mgrlastname'.3. This error occurred because the WHERE clause is evaluated before the SELECT clause and, at thattime, the column did not have an alias. To fix this problem, you must use the source column namewith the appropriate table alias. Modify the T-<strong>SQL</strong> statement to look like this:SELECTe.empid, e.lastname, e.firstname, e.title, e.mgrid,m.lastname AS mgrlastname, m.firstname AS mgrfirstnameFROM HR.Employees AS eINNER JOIN HR.Employees AS m ON e.mgrid = m.empidWHEREm.lastname = N'Buck';4. Highlight the written query and click Execute.


Lab: Filtering and Sorting Data L6-39 Task 3: Order the result by the firstname column1. Highlight the previous query. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 3 description. On the toolbar, click Edit and thenPaste. You have now copied the previous query to the same query window after the task 3description.3. Modify the T-<strong>SQL</strong> statement to include an ORDER BY clause that uses the source column name ofm.firstname. Your query should look like this:SELECTe.empid, e.lastname, e.firstname, e.title, e.mgrid,m.lastname AS mgrlastname, m.firstname AS mgrfirstnameFROM HR.Employees AS eINNER JOIN HR.Employees AS m ON e.mgrid = m.empidORDER BYm.firstname;4. Highlight the written query and click Execute.5. Modify the ORDER BY clause so that it uses the alias for the same column (mgrfirstname). Your queryshould look like this:SELECTe.empid, e.lastname, e.firstname, e.title, e.mgrid,m.lastname AS mgrlastname, m.firstname AS mgrfirstnameFROM HR.Employees AS eINNER JOIN HR.Employees AS m ON e.mgrid = m.empidORDER BYmgrfirstname;6. Highlight the written query and click Execute.7. Observe the result. Why were you able to use a source column name or an alias column name? Youcan use either one because the ORDER BY clause is evaluated after the SELECT clause and the alias forthe column name is known.


L6-40 Module 6: Sorting and Filtering DataExercise 3: Writing Queries That Filter Data Using the TOP Clause Task 1: Write a SELECT statement to retrieve last 20 orders1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECT TOP (20)orderid, orderdateFROM Sales.OrdersORDER BY orderdate DESC;4. Highlight the written query and click Execute. Task 2: Use the OFFSET-FETCH clause to implement the same task1. In the query pane, type the following query after the task 2 description:SELECTorderid, orderdateFROM Sales.OrdersORDER BY orderdate DESCOFFSET 0 ROWS FETCH FIRST 20 ROWS ONLY;Remember that the OFFSET-FETCH clause is a new functionality in <strong>SQL</strong> Server <strong>2012</strong>. Unlike the TOPclause, the OFFSET-FETCH clause must be used with the ORDER BY clause.2. Highlight the written query and click Execute. Task 3: Write a SELECT statement to retrieve the most expensive products1. In the query pane, type the following query after the task 3 description:SELECT TOP (10) PERCENTproductname, unitpriceFROM Production.ProductsORDER BY unitprice DESC;Implementing this task with the OFFSET-FETCH clause is possible. However, it is not easy because,unlike TOP, OFFSET-FETCH does not support a PERCENT option.2. Highlight the written query and click Execute.


Lab: Filtering and Sorting Data L6-41Exercise 4: Writing Queries That Filter Data Using the OFFSET-FETCHClause Task 1: Use the OFFSET-FETCH clause to fetch the first 20 rows1. In Solution Explorer, double-click the query 81 - Lab Exercise 4.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTcustid, orderid, orderdateFROM Sales.OrdersORDER BY orderdate, orderidOFFSET 0 ROWS FETCH FIRST 20 ROWS ONLY;4. Highlight the written query and click Execute. Task 2: Use the OFFSET-FETCH clause to skip the first 20 rows1. In the query pane, type the following query after the task 2 description:SELECTcustid, orderid, orderdateFROM Sales.OrdersORDER BY orderdate, orderidOFFSET 20 ROWS FETCH NEXT 20 ROWS ONLY;2. Highlight the written query and click Execute. Task 3: Write a generic form of the OFFSET-FETCH clause for paging• Solution: OFFSET (@pagenum - 1) * @pagesize ROWS FETCH NEXT @pagesize ROWS ONLY.


L6-42 Module 6: Sorting and Filtering Data


L7-43Module 7: Working with <strong>SQL</strong> Server <strong>2012</strong> Data TypesLab: Working with <strong>SQL</strong> Server Data TypesLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L7-44 Module 7: Working with <strong>SQL</strong> Server <strong>2012</strong> Data Types11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Working with <strong>SQL</strong> Server Data Types L7-45Exercise 1: Writing Queries That Return Date and Time Data Task 1: Write a SELECT statement to retrieve the current date and time1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_07_PRJ\10774A_07_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If you are using <strong>SQL</strong> Azure you will get an error, because theUSE statement is not supported and you must manually set the database context using the AvailableDatabases box.5. In the query pane, type the following query after the task 1 description:SELECTCURRENT_TIMESTAMP AS currentdatetime,CAST(CURRENT_TIMESTAMP AS DATE) AS currentdate,CAST(CURRENT_TIMESTAMP AS TIME) AS currenttime,YEAR(CURRENT_TIMESTAMP) AS currentyear,MONTH(CURRENT_TIMESTAMP) AS currentmonth,DAY(CURRENT_TIMESTAMP) AS currentday,DATEPART(week, CURRENT_TIMESTAMP) AS currentweeknumber,DATENAME(month, CURRENT_TIMESTAMP) AS currentmonthname;This query uses the CURRENT_TIMESTAMP function to return the current date and time. You can alsouse the SYSDATETIME function to get a more precise time element compared to theCURRENT_TIMESTAMP function.Note that you cannot use the alias currentdatetime as the source in the second column calculationbecause <strong>SQL</strong> Server supports a concept called all-at-once operations. This means that all expressionsthat appear in the same logical query processing phase are evaluated as if they occurred at the samepoint in time. This concept explains why, for example, you cannot refer to column aliases assigned inthe SELECT clause within the same SELECT clause, even if it seems intuitive that you should be able to.6. Highlight the written query and click Execute. Task 2: Write a SELECT statement to return the data type date1. In the query pane, type the following queries after the task 2 description:SELECT DATEFROMPARTS(2011, 12, 11) AS somedate;SELECT CAST('20111211' AS DATE) AS somedate;SELECT CONVERT(DATE, '12/11/2011', 101) AS somedate;The first query uses <strong>SQL</strong> Server <strong>2012</strong>’s new DATEFROMPARTS function.2. Highlight the written queries and click Execute.


L7-46 Module 7: Working with <strong>SQL</strong> Server <strong>2012</strong> Data Types Task 3: Write a SELECT statement that uses different date and time functions1. In the query pane, type the following query after the task 3 description:SELECTDATEADD(month, 3, CURRENT_TIMESTAMP) AS threemonths,DATEDIFF(day, CURRENT_TIMESTAMP, DATEADD(month, 3, CURRENT_TIMESTAMP)) ASdiffdays,DATEDIFF(week, '19920404', '20110916') AS diffweeks,DATEADD(day, -DAY(CURRENT_TIMESTAMP) + 1, CURRENT_TIMESTAMP) AS firstday;2. Highlight the written query and click Execute. Task 4: Observe the table provided by the IT department1. Highlight the written query under the task 4 description and click Execute.2. In the query pane, type the following queries after the task 4 description:SELECTisitdate,CASE WHEN ISDATE(isitdate) = 1 THEN CONVERT(DATE, isitdate) ELSE NULL END ASconverteddateFROM Sales.Somedates;-- Uses the new TRY_CONVERT function in <strong>SQL</strong> Server <strong>2012</strong>SELECTisitdate,TRY_CONVERT(DATE, isitdate) AS converteddateFROM Sales.Somedates;The second query uses the TRY_CONVERT function, which is new in <strong>SQL</strong> Server <strong>2012</strong>. This functionreturns a value casted to the specified data type if the casting succeeds; otherwise, it returns NULL. Donot worry if you do not recognize the type conversion functions. They will be covered in the nextmodule.3. Highlight the written queries and click Execute.4. Observe the result and answer these questions:• What is the difference between the SYSDATETIME and CURRENT_TIMESTAMP functions?There are two main differences. First, the SYSDATETIME function provides a more precise timeelement compared to the CURRENT_TIMESTAMP function. Second, the SYSDATETIME functionreturns the data type datetime2(7), whereas the CURRENT_TIMESTAMP returns the data typedatetime.• What is a language-neutral format for the data type date?You can use the format 'YYYYMMDD' or 'YYYY-MM-DD'.


Lab: Working with <strong>SQL</strong> Server Data Types L7-47Exercise 2: Writing Queries That Use Date and Time Functions Task 1: Write a SELECT statement to retrieve all distinct customers1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECT DISTINCTcustidFROM Sales.OrdersWHEREYEAR(orderdate) = 2008AND MONTH(orderdate) = 2;4. Highlight the written query and click Execute.5. Note that you could also write a query that uses a range format, which would better utilize indexing.The query would then look like this:SELECT DISTINCTcustidFROM Sales.OrdersWHEREorderdate >= '20080201'AND orderdate < '20080301'; Task 2: Write a SELECT statement to calculate the first and last day of the month1. In the query pane, type the following query after the task 2 description:SELECTCURRENT_TIMESTAMP AS currentdate,DATEADD (day, 1, EOMONTH(CURRENT_TIMESTAMP, -1)) AS firstofmonth,EOMONTH(CURRENT_TIMESTAMP) AS endofmonth;This query uses the EOMONTH function, which is new in <strong>SQL</strong> Server <strong>2012</strong>.2. Highlight the written query and click Execute. Task 3: Write a SELECT statement to retrieve the orders placed in the last five days ofthe ordered month1. In the query pane, type the following query after the task 3 description:SELECTorderid, custid, orderdateFROM Sales.OrdersWHEREDATEDIFF(day,orderdate,EOMONTH(orderdate)) < 5;2. Highlight the written query and click Execute.


L7-48 Module 7: Working with <strong>SQL</strong> Server <strong>2012</strong> Data Types Task 4: Write a SELECT statement to retrieve all distinct products sold in the first 10weeks of the year 20071. In the query pane, type the following query after the task 4 description:SELECT DISTINCTd.productidFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidWHEREDATEPART(week, orderdate)


Lab: Working with <strong>SQL</strong> Server Data Types L7-49Exercise 3: Writing Queries That Return Character Data Task 1: Write a SELECT statement to concatenate two columns1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTcontactname + N' (city: ' + city + N')' AS contactwithcityFROM Sales.Customers;4. Highlight the written query and click Execute. Task 2: Add an additional column and treat NULL as an empty string1. In the query pane, type the following query after the task 2 description:SELECTcontactname + N' (city: ' + city + N', region: ' + COALESCE(region, '') + N')' ASfullcontactFROM Sales.Customers;This query uses the COALESCE function to replace a NULL with an empty string. The next module willinclude more examples of how to handle a NULL.2. Highlight the written query and click Execute.3. Note that you can also use <strong>SQL</strong> Server <strong>2012</strong>’s new CONCAT function to concatenate strings. It alsoreplaces a NULL with an empty string. The query using the CONCAT function would look like this:SELECTCONCAT(contactname, N' (city: ', city, N', region: ', region, N')') ASfullcontactFROM Sales.Customers; Task 3: Write a SELECT statement to retrieve all customers based on the firstcharacter in the contact name1. In the query pane, type the following query after the task 3 description:SELECT contactname, contacttitleFROM Sales.CustomersWHERE contactname LIKE N'[A-G]%'ORDER BY contactname;2. Highlight the written query and click Execute.


L7-50 Module 7: Working with <strong>SQL</strong> Server <strong>2012</strong> Data TypesExercise 4: Writing Queries That Use Character Functions Task 1: Write a SELECT statement that uses the SUBSTRING function1. In Solution Explorer, double-click the query 81 - Lab Exercise 4.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTcontactname,SUBSTRING(contactname, 0, CHARINDEX(N',', contactname)) AS lastnameFROM Sales.Customers;4. Highlight the written query and click Execute. Task 2: Extend the SUBSTRING function to retrieve the first name1. In the query pane, type the following query after the task 2 description:SELECTREPLACE(contactname, ',', '') AS newcontactname,SUBSTRING(contactname, CHARINDEX(N',', contactname)+1, LEN(contactname)-CHARINDEX(N',', contactname)+1) AS firstnameFROM Sales.Customers;2. Highlight the written query and click Execute. Task 3: Write a SELECT statement to change the customer IDs1. In the query pane, type the following query after the task 3 description:SELECTcustid,N'C' + RIGHT(REPLICATE('0', 5) + CAST(custid AS VARCHAR(5)), 5) AS custnewidFROM Sales.Customers;2. Highlight the written query and click Execute.3. Note that you can also use <strong>SQL</strong> Server <strong>2012</strong>’s new FORMAT function. The query would then looklike this:SELECTFORMAT(custid, N'\C00000')FROM Sales.Customers;


Lab: Working with <strong>SQL</strong> Server Data Types L7-51 Task 4 (challenge): Write a SELECT statement to return the number of characteroccurrences1. In the query pane, type the following query after the task 4 description:SELECTcontactname,LEN(contactname) - LEN(REPLACE(contactname, 'a', '')) AS numberofaFROM Sales.CustomersORDER BY numberofa DESC;This elegant solution first returns the number of characters in the contact name and then subtractsthe number of characters in the contact name without the character “a”. The result is stored in a newcolumn named numberofa.2. Highlight the written query and click Execute.


L7-52 Module 7: Working with <strong>SQL</strong> Server <strong>2012</strong> Data Types


L8-53Module 8: Using Built-In FunctionsLab: Using Built-In FunctionsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L8-54 Module 8: Using Built-In Functions11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Using Built-In Functions L8-55Exercise 1: Writing Queries That Use Conversion Functions Task 1: Write a SELECT statement that uses the CAST or CONVERT function1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_08_PRJ\10774A_08_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If you are using <strong>SQL</strong> Azure you will get an error, because theUSE statement is not supported and you must manually set the database context using the AvailableDatabases box.5. In the query pane, type the following query after the task 1 description:SELECT N'The unit price for the ' + productname + N' is ' + CAST(unitprice ASNVARCHAR(10)) + N' $.' AS productdescFROM Production.Products;This query uses the CAST function rather than the CONVERT function. It is better to use the CASTfunction because it is an ANSI <strong>SQL</strong> standard. You should use the CONVERT function only when youneed to apply a specific style during a conversion.6. Highlight the written query and click Execute. Task 2: Write a SELECT statement to filter rows based on specific date information1. In the query pane, type the following query after the task 2 description:SELECT orderid, orderdate, shippeddate, COALESCE(shipregion, 'No region') ASshipregionFROM Sales.OrdersWHEREorderdate >= CONVERT(DATETIME, '4/1/2007', 101)AND orderdate DATEADD(DAY, 30, orderdate);2. Highlight the written query and click Execute.3. Note that you could also write a solution using the new PARSE function. The query would looklike this:SELECT orderid, orderdate, shippeddate, COALESCE(shipregion, 'No region') ASshipregionFROM Sales.OrdersWHEREorderdate >= PARSE('4/1/2007' AS DATETIME USING 'en-US')AND orderdate DATEADD(DAY, 30, orderdate);


L8-56 Module 8: Using Built-In Functions Task 3: Write a SELECT statement to convert the phone number information to aninteger value1. In the query pane, type the following query after the task 3 description:SELECTCONVERT(INT, REPLACE(REPLACE(REPLACE(REPLACE(phone, N'-', N''), N'(', ''), N')',''), ' ', '')) AS phonenoasintFROM Sales.Customers;This query is trying to use the CONVERT function to convert phone numbers that include characterssuch as hyphens and parentheses into an integer value.2. Highlight the written query and click Execute.3. Observe the error message:Conversion failed when converting the nvarchar value '67.89.01.23' to data type int.Because you want to retrieve rows without conversion errors and have a NULL for those that producea conversion error, you can use the new TRY_CONVERT function.4. Modify the query to use the TRY_CONVERT function. The query should look like this:SELECTTRY_CONVERT(INT, REPLACE(REPLACE(REPLACE(REPLACE(phone, N'-', N''), N'(', ''),N')', ''), ' ', '')) AS phonenoasintFROM Sales.Customers;5. Highlight the written query and click Execute. Observe the result. The rows that could not beconverted have a NULL.


Lab: Using Built-In Functions L8-57Exercise 2: Writing Queries That Use Logical Functions Task 1: Write a SELECT statement to mark specific customers based on their countryand contact title1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTIIF(country = N'Mexico' AND contacttitle = N'Owner', N'Target group', N'Other') ASsegmentgroup, custid, contactnameFROM Sales.Customers;The IIF function is new in <strong>SQL</strong> Server <strong>2012</strong>. It was added mainly to support migrations from MicrosoftAccess to <strong>SQL</strong> Server. You can always use a CASE expression to achieve the same result.4. Highlight the written query and click Execute. Task 2: Modify the <strong>SQL</strong> statement to mark different customers1. In the query pane, type the following query after the task 2 description:SELECTIIF(contacttitle = N'Owner' OR region IS NOT NULL, N'Target group', N'Other') ASsegmentgroup, custid, contactnameFROM Sales.Customers;2. Highlight the written query and click Execute. Task 3: Create four groups of customers1. In the query pane, type the following query after the task 3 description:SELECT CHOOSE(custid % 4 + 1, N'Group One', N'Group Two', N'Group Three', N'GroupFour') AS segmentgroup, custid, contactnameFROM Sales.Customers;2. Highlight the written query and click Execute.


L8-58 Module 8: Using Built-In FunctionsExercise 3: Writing Queries That Test for Nullability Task 1: Write a SELECT statement to retrieve the customer fax information1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECT contactname, COALESCE(fax, N'No information') AS faxinformationFROM Sales.Customers;This query uses the COALESCE function to retrieve customers’ fax information.4. Highlight the written query and click Execute.5. In the query pane, type the following query after the previous query:SELECT contactname, ISNULL(fax, N'No information') AS faxinformationFROM Sales.Customers;This query uses the ISNULL function. What is the difference between the ISNULL and COALESCEfunctions? COALESCE is a standard ANSI <strong>SQL</strong> function and ISNULL is not. So, you should use theCOALESCE function.6. Highlight the written query and click Execute. Task 2: Write a filter for a variable that could be a NULL1. Highlight the query provided under the task 2 description and click Execute.2. Highlight the previous query. On the toolbar, click Edit and then Copy.3. In the query window, click the line after the task 2 description. On the toolbar, click Edit and thenPaste. You have now copied the previous query to the same query window after the task 2description.4. Modify the query so that it looks like this:DECLARE @region AS NVARCHAR(30) = NULL;SELECTcustid, regionFROM Sales.CustomersWHERE region = @region OR (region IS NULL AND @region IS NULL);5. Highlight the modified query and click Execute.6. Test the modified query by setting the @region parameter to N'WA'. The T-<strong>SQL</strong> expression shouldlook like this:DECLARE @region AS NVARCHAR(30) = N'WA';SELECTcustid, regionFROM Sales.CustomersWHERE region = @region OR (region IS NULL AND @region IS NULL);7. Highlight the written query and click Execute.


Lab: Using Built-In Functions L8-59 Task 3: Write a SELECT statement to return all the customers that do not have atwo-character abbreviation for the region1. In the query pane, type the following query after the task 3 description:SELECT custid, contactname, city, regionFROM Sales.CustomersWHEREregion IS NULLOR LEN(region) 2;2. Highlight the written query and click Execute.


L8-60 Module 8: Using Built-In Functions


L9-61Module 9: Grouping and Aggregating DataLab: Grouping and Aggregating DataLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L9-62 Module 9: Grouping and Aggregating Data11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click Login tab, select <strong>SQL</strong> Server Authentication in the Authenticationlist, type your login name in the Login text box and the password in the Password text box, andclick Connect.


Lab: Grouping and Aggregating Data L9-63Exercise 1: Writing Queries That Use the GROUP BY Clause Task 1: Write a SELECT statement to retrieve different groups of customers1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_09_PRJ\10774A_09_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If you are using <strong>SQL</strong> Azure you will get an error, because theUSE statement is not supported and you must manually set the database context using the AvailableDatabases box.5. In the query pane, type the following query after the task 1 description:SELECTo.custid, c.contactnameFROM Sales.Orders AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidWHERE o.empid = 5GROUP BY o.custid, c.contactname;6. Highlight the written query and click Execute. Task 2: Add an additional column from the Sales.Customers table1. Highlight the previous query. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 2 description. On the toolbar, click Edit andthen Paste.3. Modify the T-<strong>SQL</strong> statement so that it adds an additional column. Your query should look like this:SELECTo.custid, c.contactname, c.cityFROM Sales.Orders AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidWHERE o.empid = 5GROUP BY o.custid, c.contactname;4. Highlight the written query and click Execute.5. Observe the error message:Column 'Sales.Customers.city' is invalid in the select list because it is not contained in either anaggregate function or the GROUP BY clause.Why did the query fail? In a grouped query, you will get an error if you refer to an attribute that isnot in the GROUP BY list (such as the city column) or not an input to an aggregate function in anyclause that is processed after the GROUP BY clause.


L9-64 Module 9: Grouping and Aggregating Data6. Modify the <strong>SQL</strong> statement to include the city column in the GROUP BY clause. Your query should looklike this:SELECTo.custid, c.contactname, c.cityFROM Sales.Orders AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidWHERE o.empid = 5GROUP BY o.custid, c.contactname, c.city;7. Highlight the written query and click Execute. Task 3: Write a SELECT statement to retrieve the customers with orders for each year1. In the query pane, type the following query after the task 3 description:SELECTcustid, YEAR(orderdate) AS orderyearFROM Sales.OrdersWHERE empid = 5GROUP BY custid, YEAR(orderdate)ORDER BY custid, orderyear;2. Highlight the written query and click Execute. Task 4: Write a SELECT statement to retrieve groups of product categories sold in aspecific year1. In the query pane, type the following query after the task 4 description:SELECTc.categoryid, c.categorynameFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidINNER JOIN Production.Products AS p ON p.productid = d.productidINNER JOIN Production.Categories AS c ON c.categoryid = p.categoryidWHERE orderdate >= '20080101' AND orderdate < '20090101'GROUP BY c.categoryid, c.categoryname;2. Highlight the written query and click Execute.Important note regarding the use of the DISTINCT clauseIn all the tasks in Exercise 1, you could use the DISTINCT clause in the SELECT clause as an alternative tousing a grouped query. This is possible because aggregate functions are not being requested.


Lab: Grouping and Aggregating Data L9-65Exercise 2: Writing Queries That Use Aggregate Functions Task 1: Write a SELECT statement to retrieve the total sales amount per order1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTo.orderid, o.orderdate, SUM(d.qty * d.unitprice) AS salesamountFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY o.orderid, o.orderdateORDER BY salesamount DESC;4. Highlight the written query and click Execute. Task 2: Add additional columns1. Highlight the previous query. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 2 description. On the toolbar, click Edit andthen Paste.3. Modify the T-<strong>SQL</strong> statement so that it adds additional columns. Your query should look like this:SELECTo.orderid, o.orderdate,SUM(d.qty * d.unitprice) AS salesamount,COUNT(*) AS noofoderlines,AVG(d.qty * d.unitprice) AS avgsalesamountperorderlineFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY o.orderid, o.orderdateORDER BY salesamount DESC;4. Highlight the written query and click Execute. Task 3: Write a SELECT statement to retrieve the sales amount value per month1. In the query pane, type the following query after the task 3 description:SELECTYEAR(orderdate) * 100 + MONTH(orderdate) AS yearmonthno,SUM(d.qty * d.unitprice) AS saleamountpermonthFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY YEAR(orderdate), MONTH(orderdate)ORDER BY yearmonthno;2. Highlight the written query and click Execute.


L9-66 Module 9: Grouping and Aggregating Data Task 4: Write a SELECT statement to list all customers, with the total sales amountand number of order lines added1. In the query pane, type the following query after the task 4 description:SELECTc.custid, c.contactname,SUM(d.qty * d.unitprice) AS totalsalesamount,MAX(d.qty * d.unitprice) AS maxsalesamountperorderline,COUNT(*) AS numberofrows,COUNT(o.orderid) AS numberoforderlinesFROM Sales.Customers AS cLEFT OUTER JOIN Sales.Orders AS o ON o.custid = c.custidLEFT OUTER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY c.custid, c.contactnameORDER BY totalsalesamount;2. Highlight the written query and click Execute.3. Observe the result. Notice that the values in the numberofrows and numberoforderlines columns aredifferent. Why? All aggregate functions ignore NULLs except COUNT(*), which is why you receivedthe value 1 for the numberofrows column. When you used the orderid column in the COUNTfunction, you received the value 0 because the orderid is NULL for customers without an order.


Lab: Grouping and Aggregating Data L9-67Exercise 3: Writing Queries That Use Distinct Aggregate Functions Task 1: Modify a SELECT statement to retrieve the number of customers1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. Highlight the provided T-<strong>SQL</strong> statement and click Execute.4. Observe the result. Notice that the number of orders is the same as the number of customers. Why?You are using the aggregate COUNT function on the orderid and custid columns and since everyorder has a customer, the COUNT function returns the same value. It does not matter if there aremultiple orders for the same customer because you are not using a DISTINCT clause inside theaggregate function. If you want to get the correct number of distinct customers, you have to modifythe provided T-<strong>SQL</strong> statement to include a DISTINCT clause.5. Modify the provided T-<strong>SQL</strong> statement to include a DISTINCT clause. The query should look like this:SELECTYEAR(orderdate) AS orderyear,COUNT(orderid) AS nooforders,COUNT(DISTINCT custid) AS noofcustomersFROM Sales.OrdersGROUP BY YEAR(orderdate);6. Highlight the written query and click Execute. Task 2: Write a SELECT statement to analyze segments of customers1. In the query pane, type the following query after the task 2 description:SELECTSUBSTRING(c.contactname,1,1) AS firstletter,COUNT(DISTINCT c.custid) AS noofcustomers,COUNT(o.orderid) AS noofordersFROM Sales.Customers AS cLEFT OUTER JOIN Sales.Orders AS o ON o.custid = c.custidGROUP BY SUBSTRING(c.contactname,1,1)ORDER BY firstletter;2. Highlight the written query and click Execute. Task 3: Write a SELECT statement to retrieve additional sales statistics1. In the query pane, type the following query after the task 3 description:SELECTc.categoryid, c.categoryname,SUM(d.qty * d.unitprice) AS totalsalesamount,COUNT(DISTINCT o.orderid) AS nooforders,SUM(d.qty * d.unitprice) / COUNT(DISTINCT o.orderid) AS avgsalesamountperorderFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidINNER JOIN Production.Products AS p ON p.productid = d.productidINNER JOIN Production.Categories AS c ON c.categoryid = p.categoryidWHERE orderdate >= '20080101' AND orderdate < '20090101'GROUP BY c.categoryid, c.categoryname;2. Highlight the written query and click Execute.


L9-68 Module 9: Grouping and Aggregating DataExercise 4: Writing Queries That Filter Groups with the HAVING Clause Task 1: Write a SELECT statement to retrieve the top 10 customers1. In Solution Explorer, double-click the query 81 - Lab Exercise 4.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECT TOP (10)o.custid,SUM(d.qty * d.unitprice) AS totalsalesamountFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY o.custidHAVING SUM(d.qty * d.unitprice) > 10000ORDER BY totalsalesamount DESC;4. Highlight the written query and click Execute. Task 2: Write a SELECT statement to retrieve specific orders1. In the query pane, type the following query after the task 2 description:SELECTo.orderid,o.empid,SUM(d.qty * d.unitprice) as totalsalesamountFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidWHERE o.orderdate >= '20080101' AND o.orderdate < '20090101'GROUP BY o.orderid, o.empid;2. Highlight the written query and click Execute. Task 3: Apply additional filtering1. Highlight the previous query. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 3 description. On the toolbar, click Edit and thenPaste.3. Modify the T-<strong>SQL</strong> statement to apply additional filtering. Your query should look like this:SELECTo.orderid,o.empid,SUM(d.qty * d.unitprice) as totalsalesamountFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidWHERE o.orderdate >= '20080101' AND o.orderdate < '20090101'GROUP BY o.orderid, o.empidHAVING SUM(d.qty * d.unitprice) >= 10000;4. Highlight the written query and click Execute.


Lab: Grouping and Aggregating Data L9-695. Modify the T-<strong>SQL</strong> statement to include an additional filter to retrieve only orders handled by theemployee whose ID is 3. Your query should look like this:SELECTo.orderid,o.empid,SUM(d.qty * d.unitprice) as totalsalesamountFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidWHEREo.orderdate >= '20080101' AND o.orderdate = 10000;In this query, the predicate logic is applied in the WHERE clause. You could also write the predicatelogic inside the HAVING clause. Which do you think is better? Unlike with orderdate filtering, withempid filtering, the result is going to be correct either way because you are filtering by an elementthat appears in the GROUP BY list. Conceptually, it seems more intuitive to filter as early as possible.Thus, this query applies the filtering in the WHERE clause because it will be logically applied beforethe GROUP BY clause. Do not forget, though, that the actual processing in the <strong>SQL</strong> Server enginecould be different.6. Highlight the written query and click Execute. Task 4: Retrieve the customers with more than 25 orders1. In the query pane, type the following query after the task 4 description:SELECTo.custid,MAX(orderdate) AS lastorderdate,SUM(d.qty * d.unitprice) AS totalsalesamountFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY o.custidHAVING COUNT(DISTINCT o.orderid) > 25;2. Highlight the written query and click Execute.


L9-70 Module 9: Grouping and Aggregating Data


L10-71Module 10: Using SubqueriesLab: Using SubqueriesLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L10-72 Module 10: Using Subqueries11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Using Subqueries L10-73Exercise 1: Writing Queries That Use Self-Contained Subqueries Task 1: Write a SELECT statement to retrieve the last order date1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_10_PRJ\10774A_10_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If you are using <strong>SQL</strong> Azure you will get an error, because theUSE statement is not supported and you must manually set the database context using the AvailableDatabases box.5. In the query pane, type the following query after the task 1 description:SELECT MAX(orderdate) AS lastorderdateFROM Sales.Orders;6. Highlight the written query and click Execute. Task 2: Write a SELECT statement to retrieve all orders placed on the last order date1. In the query pane, type the following query after the task 2 description:SELECTorderid, orderdate, empid, custidFROM Sales.OrdersWHEREorderdate = (SELECT MAX(orderdate) FROM Sales.Orders);2. Highlight the written query and click Execute. Task 3: Observe the T-<strong>SQL</strong> statement provided by the IT department1. Highlight the provided T-<strong>SQL</strong> statement under the task 3 description and click Execute.2. Modify the query to filter customers whose contact name starts with the letter B. Your query shouldlook like this:SELECTorderid, orderdate, empid, custidFROM Sales.OrdersWHEREcustid =(SELECT custidFROM Sales.CustomersWHERE contactname LIKE N'B%');


L10-74 Module 10: Using Subqueries3. Highlight the written query and click Execute.4. Observe the error message:Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, = or when the subquery is used as an expression.Why did the query fail? It failed because the subquery returned more than one row. To fix thisproblem, you have to replace the = operator with an IN operator.5. Modify the query so that it uses the IN operator. Your query should look like this:SELECTorderid, orderdate, empid, custidFROM Sales.OrdersWHEREcustid IN(SELECT custidFROM Sales.CustomersWHERE contactname LIKE N'B%');6. Highlight the written query and click Execute. Task 4: Write a SELECT statement to analyze each order’s sales as a percentage of thetotal sales amount1. In the query pane, type the following query after the task 4 description:SELECTo.orderid,SUM(d.qty * d.unitprice) AS totalsalesamount,SUM(d.qty * d.unitprice) /(SELECT SUM(d.qty * d.unitprice)FROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidWHERE o.orderdate >= '20080501' AND orderdate < '20080601') * 100. AS salespctoftotalFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidWHERE o.orderdate >= '20080501' AND orderdate < '20080601'GROUP BY o.orderid;2. Highlight the written query and click Execute.


Lab: Using Subqueries L10-75Exercise 2: Writing Queries That Use Scalar and Multi-Valued Subqueries Task 1: Write a SELECT statement to retrieve specific products1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTproductid, productnameFROM Production.ProductsWHEREproductid IN(SELECT productidFROM Sales.OrderDetailsWHERE qty > 100);4. Highlight the written query and click Execute. Task 2: Write a SELECT statement to retrieve those customers without orders1. In the query pane, type the following query after the task 2 description:SELECTcustid, contactnameFROM Sales.CustomersWHERE custid NOT IN(SELECT custidFROM Sales.Orders);2. Highlight the written query and click Execute.3. Observe the result. Notice that there are two customers without an order. Task 3: Add a row and rerun the query that retrieves those customers without orders1. Highlight the provided T-<strong>SQL</strong> statement under the task 3 description and click Execute. This codeinserts an additional row that has a NULL in the custid column of the Sales.Orders table.2. Highlight the query in task 2. On the toolbar, click Edit and then Copy.3. In the query window, click the line after the provided T-<strong>SQL</strong> statement. On the toolbar, click Edit andthen Paste.4. Highlight the written query and click Execute.


L10-76 Module 10: Using Subqueries5. Notice that you have an empty result despite getting two rows in the result when you first ran thequery in task 2. Why did you get an empty result this time? There is an issue with the NULL in the newrow you added because the custid column is the only column that is part of the subquery. The INoperator supports three-valued logic (TRUE, FALSE, UNKNOWN). Before you apply the NOT operator,the logical meaning of UNKNOWN is that you can’t tell for sure whether the customer ID appears inthe set, because the NULL could represent that customer ID as well as anything else. As a moretangible example, consider the expression 22 NOT IN (1, 2, NULL). If you evaluate each individualexpression in the parentheses to its truth value, you will get NOT (FALSE OR FALSE OR UNKNOWN),which translates to NOT UNKNOWN, which evaluates to UNKNOWN. The tricky part is that negatingUNKNOWN with the NOT operator still yields UNKNOWN, and UNKNOWN is filtered out in a queryfilter. In short, when you use the NOT IN predicate against a subquery that returns at least one NULL,the outer query always returns an empty set.6. To solve this problem, modify the T-<strong>SQL</strong> statement so that the subquery does not return NULLs. Yourquery should look like this:SELECTcustid, contactnameFROM Sales.CustomersWHERE custid NOT IN(SELECT custidFROM Sales.OrdersWHERE custid IS NOT NULL);7. Highlight the modified query and click Execute.


Lab: Using Subqueries L10-77Exercise 3: Writing Queries That Use Correlated Subqueries and an EXISTSPredicate Task 1: Write a SELECT statement to retrieve the last order date for each customer1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTc.custid, c.contactname,(SELECT MAX(o.orderdate)FROM Sales.Orders AS oWHERE o.custid = c.custid) AS lastorderdateFROM Sales.Customers AS c;4. Highlight the written query and click Execute. Task 2: Write a SELECT statement that uses the EXISTS predicate to retrieve thosecustomers without orders1. In the query pane, type the following query after the task 2 description:SELECT c.custid, c.contactnameFROM Sales.Customers AS cWHERENOT EXISTS (SELECT * FROM Sales.Orders AS o WHERE o.custid = c.custid);2. Highlight the written query and click Execute.3. Notice that you got the same result as the modified query in exercise 2 task 3, but without a filter toexclude NULLs. Why didn’t you need to explicitly filter out NULLs? The EXISTS predicate uses twovaluedlogic (TRUE, FALSE) and checks only if the rows specified in the correlated subquery exists.Another benefit of using the EXISTS predicate is better performance. The <strong>SQL</strong> Server engine knowsthat it is enough to determine whether the subquery returns at least one row or none, so it doesn’tneed to process all qualifying rows. Task 3: Write a SELECT statement to retrieve customers that bought expensiveproducts1. In the query pane, type the following query after the task 3 description:SELECT c.custid, c.contactnameFROM Sales.Customers AS cWHEREEXISTS (SELECT *FROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidWHERE o.custid = c.custidAND d.unitprice > 100.AND o.orderdate >= '20080401');2. Highlight the written query and click Execute.


L10-78 Module 10: Using Subqueries Task 4 (challenge): Write a SELECT statement to display the total sales amount andthe running total sales amount for each order year1. In the query pane, type the following query after the task 4 description:SELECTYEAR(o.orderdate) as orderyear,SUM(d.qty * d.unitprice) AS totalsales,(SELECT SUM(d2.qty * d2.unitprice)FROM Sales.Orders AS o2INNER JOIN Sales.OrderDetails AS d2 ON d2.orderid = o2.orderidWHERE YEAR(o2.orderdate)


L11-79Module 11: Using Table ExpressionsLab: Using Table ExpressionsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L11-80 Module 11: Using Table Expressions11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Using Table Expressions L11-81Exercise 1: Writing Queries That Use Views Task 1: Write a SELECT statement to retrieve all products for a specific category1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_11_PRJ\10774A_11_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If you are using <strong>SQL</strong> Azure you will get an error, because theUSE statement is not supported and you must manually set the database context using the AvailableDatabases box.5. In the query pane, type the following query after the task 1 description:SELECTproductid, productname, supplierid, unitprice, discontinuedFROM Production.ProductsWHERE categoryid = 1;6. Highlight the written query and click Execute.7. Modify the query to include the provided CREATE VIEW statement. The query should look like this:CREATE VIEW Production.ProductsBeverages ASSELECTproductid, productname, supplierid, unitprice, discontinuedFROM Production.ProductsWHERE categoryid = 1;8. Highlight the modified query and click Execute. Task 2: Write a SELECT statement against the created view1. In the query pane, type the following query after the task 2 description:SELECTproductid, productnameFROM Production.ProductsBeveragesWHERE supplierid = 1;2. Highlight the written query and click Execute.


L11-82 Module 11: Using Table Expressions Task 3: Try to use an ORDER BY clause in the created view1. Highlight the provided T-<strong>SQL</strong> statement under the task 3 description and click Execute.2. Observe the error message:Results: The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, andcommon table expressions, unless TOP, OFFSET or FOR XML is also specified.Why did the query fail? It failed because the view is supposed to represent a relation, and a relationhas no order. You can only use the ORDER BY clause in the view if you specify the TOP, OFFSET, orFOR XML option. The reason you can use ORDER BY in special cases is that it serves a meaning otherthan presentation ordering to these special cases.3. Modify the previous T-<strong>SQL</strong> statement by including the TOP (100) PERCENT option. The query shouldlook like this:ALTER VIEW Production.ProductsBeverages ASSELECT TOP(100) PERCENTproductid, productname, supplierid, unitprice, discontinuedFROM Production.ProductsWHERE categoryid = 1ORDER BY productname;4. Highlight the written query and click Execute.5. Observe the result. If you now write a query against the Production.ProductsBeverages view, will it beguaranteed that the retrieved rows will be sorted by productname? If you do not specify the ORDERBY clause in the T-<strong>SQL</strong> statement against the view, there is no guarantee that the retrieved rows willbe sorted. It is important to remember that any order of the rows in the output is considered valid,and no specific order is guaranteed. Therefore, when querying a table expression, you should notassume any order unless you specify an ORDER BY clause in the outer query. Task 4: Add a calculated column to the view1. Highlight the provided T-<strong>SQL</strong> statement under the task 4 description and click Execute.2. Observe the error message:Results: Create View or Function failed because no column name was specified for column 6.Why did the query fail? It failed because each column must have a unique name. In the providedT-<strong>SQL</strong> statement, the last column does not have a name.3. Modify the T-<strong>SQL</strong> statement to include the column name pricetype. The query should look like this:ALTER VIEW Production.ProductsBeverages ASSELECTproductid, productname, supplierid, unitprice, discontinued,CASE WHEN unitprice > 100. THEN N'high' ELSE N'normal' END AS pricetypeFROM Production.ProductsWHERE categoryid = 1;4. Highlight the written query and click Execute. Task 5: Remove the Production.ProductsBeverages view• Highlight the provided T-<strong>SQL</strong> statement under the task 5 description and click Execute.


Lab: Using Table Expressions L11-83Exercise 2: Writing Queries That Use Derived Tables Task 1: Write a SELECT statement against a derived table1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTp.productid, p.productnameFROM(SELECTproductid, productname, supplierid, unitprice, discontinued,CASE WHEN unitprice > 100. THEN N'high' ELSE N'normal' END AS pricetypeFROM Production.ProductsWHERE categoryid = 1) AS pWHERE p.pricetype = N'high';4. Highlight the written query and click Execute. Task 2: Write a SELECT statement to calculate the total and average sales amount1. In the query pane, type the following query after the task 2 description:SELECTc.custid,SUM(c.totalsalesamountperorder) AS totalsalesamount,AVG(c.totalsalesamountperorder) AS avgsalesamountFROM(SELECTo.custid, o.orderid, SUM(d.unitprice * d.qty) AS totalsalesamountperorderFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails d ON d.orderid = o.orderidGROUP BY o.custid, o.orderid) AS cGROUP BY c.custid;2. Highlight the written query and click Execute.


L11-84 Module 11: Using Table Expressions Task 3 (challenge): Write a SELECT statement to retrieve the sales growth percentage1. In the query pane, type the following query after the task 3 description:SELECTcy.orderyear,cy.totalsalesamount AS curtotalsales,py.totalsalesamount AS prevtotalsales,(cy.totalsalesamount - py.totalsalesamount) / py.totalsalesamount * 100. ASpercentgrowthFROM(SELECTYEAR(orderdate) AS orderyear, SUM(val) AS totalsalesamountFROM Sales.OrderValuesGROUP BY YEAR(orderdate)) AS cyLEFT OUTER JOIN(SELECTYEAR(orderdate) AS orderyear, SUM(val) AS totalsalesamountFROM Sales.OrderValuesGROUP BY YEAR(orderdate)) AS py ON cy.orderyear = py.orderyear + 1ORDER BY cy.orderyear;2. Highlight the written query and click Execute.


Lab: Using Table Expressions L11-85Exercise 3: Writing Queries That Use Common Table Expressions (CTEs) Task 1: Write a SELECT statement that uses a CTE1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:WITH ProductsBeverages AS(SELECTproductid, productname, supplierid, unitprice, discontinued,CASE WHEN unitprice > 100. THEN N'high' ELSE N'normal' END AS pricetypeFROM Production.ProductsWHERE categoryid = 1)SELECTproductid, productnameFROM ProductsBeveragesWHERE pricetype = N'high';4. Highlight the written query and click Execute. Task 2: Write a SELECT statement to retrieve the total sales amount for each customer1. In the query pane, type the following query after the task 2 description:WITH c2008 (custid, salesamt2008) AS(SELECTcustid, SUM(val)FROM Sales.OrderValuesWHERE YEAR(orderdate) = 2008GROUP BY custid)SELECTc.custid, c.contactname, c2008.salesamt2008FROM Sales.Customers AS cLEFT OUTER JOIN c2008 ON c.custid = c2008.custid;2. Highlight the written query and click Execute.


L11-86 Module 11: Using Table Expressions Task 3 (challenge): Write a SELECT statement to compare the total sales amount foreach customer over the previous year1. In the query pane, type the following query after the task 3 description:WITH c2008 (custid, salesamt2008) AS(SELECTcustid, SUM(val)FROM Sales.OrderValuesWHERE YEAR(orderdate) = 2008GROUP BY custid),c2007 (custid, salesamt2007) AS(SELECTcustid, SUM(val)FROM Sales.OrderValuesWHERE YEAR(orderdate) = 2007GROUP BY custid)SELECTc.custid, c.contactname,c2008.salesamt2008,c2007.salesamt2007,COALESCE((c2008.salesamt2008 - c2007.salesamt2007) / c2007.salesamt2007 * 100., 0)AS percentgrowthFROM Sales.Customers AS cLEFT OUTER JOIN c2008 ON c.custid = c2008.custidLEFT OUTER JOIN c2007 ON c.custid = c2007.custidORDER BY percentgrowth DESC;2. Highlight the written query and click Execute.


Lab: Using Table Expressions L11-87Exercise 4: Writing Queries That Use Inline Table-Valued Functions Task 1: Write a SELECT statement to retrieve the total sales amount for each customer1. In Solution Explorer, double-click the query 81 - Lab Exercise 4.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTcustid, SUM(val) AS totalsalesamountFROM Sales.OrderValuesWHERE YEAR(orderdate) = 2007GROUP BY custid;4. Highlight the written query and click Execute.5. Create an inline table-valued function using the provided code. Add the previous query, putting itafter the function’s RETURN clause. In the query, replace the order date of 2007 with the function’sinput parameter @orderyear. The resulting T-<strong>SQL</strong> statement should look like this:CREATE FUNCTION dbo.fnGetSalesByCustomer(@orderyear AS INT) RETURNS TABLEASRETURNSELECTcustid, SUM(val) AS totalsalesamountFROM Sales.OrderValuesWHERE YEAR(orderdate) = @orderyearGROUP BY custid;This T-<strong>SQL</strong> statement will create an inline table-valued function named dbo.fnGetSalesByCustomer.6. Highlight the written T-<strong>SQL</strong> statement and click Execute. Task 2: Write a SELECT statement against the inline table-valued function1. In the query pane, type the following query after the task 2 description:SELECTcustid, totalsalesamountFROM dbo.fnGetSalesByCustomer(2007);2. Highlight the written query and click Execute.


L11-88 Module 11: Using Table Expressions Task 3: Write a SELECT statement to retrieve the top three products based on thetotal sales value for a specified customer1. In the query pane, type the following query after the task 3 description:SELECT TOP(3)d.productid,MAX(p.productname) AS productname,SUM(d.qty * d.unitprice) AS totalsalesamountFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidINNER JOIN Production.Products AS p ON p.productid = d.productidWHERE custid = 1GROUP BY d.productidORDER BY totalsalesamount DESC;2. Highlight the written query and click Execute.3. Create an inline table-valued function using the provided code. Add the previous query, putting itafter the function’s RETURN clause. In the query, replace the constant custid value of 1 with thefunction’s input parameter @custid. The resulting T-<strong>SQL</strong> statement should look like this:CREATE FUNCTION dbo.fnGetTop3ProductsForCustomer(@custid AS INT) RETURNS TABLEASRETURNSELECT TOP(3)d.productid,MAX(p.productname) AS productname,SUM(d.qty * d.unitprice) AS totalsalesamountFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidINNER JOIN Production.Products AS p ON p.productid = d.productidWHERE custid = @custidGROUP BY d.productidORDER BY totalsalesamount DESC;4. To test the inline table-valued function, add the following query after the CREATE FUNCTIONstatement:SELECTp.productid,p.productname,p.totalsalesamountFROM dbo.fnGetTop3ProductsForCustomer(1) AS p;5. Highlight the CREATE FUNCTION statement and the written query, and click Execute.


Lab: Using Table Expressions L11-89 Task 4 (challenge): Write a SELECT statement to compare the total sales amount foreach customer over the previous year using inline table-valued functions1. In the query pane, type the following query after the task 4 description:SELECTc.custid, c.contactname,c2008.totalsalesamount AS salesamt2008,c2007.totalsalesamount AS salesamt2007,COALESCE((c2008.totalsalesamount - c2007.totalsalesamount) /c2007.totalsalesamount * 100., 0) AS percentgrowthFROM Sales.Customers AS cLEFT OUTER JOIN dbo.fnGetSalesByCustomer(2007) AS c2007 ON c.custid = c2007.custidLEFT OUTER JOIN dbo.fnGetSalesByCustomer(2008) AS c2008 ON c.custid = c2008.custid;2. Highlight the written query and click Execute. Task 5: Remove the created inline table-valued functions• Highlight the provided T-<strong>SQL</strong> statement under the task 5 description and click Execute.


L11-90 Module 11: Using Table Expressions


L12-91Module 12: Using Set OperatorsLab: Using Set OperatorsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L12-92 Module 12: Using Set Operators11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Using Set Operators L12-93Exercise 1: Writing Queries That Use the UNION Set Operator and UNIONALL Multi-Set Operator Task 1: Write a SELECT statement to retrieve specific products1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_12_PRJ\10774A_12_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If you are using <strong>SQL</strong> Azure you will get an error, because theUSE statement is not supported and you must manually set the database context using the AvailableDatabases box.5. In the query pane, type the following query after the task 1 description:SELECTproductid, productnameFROM Production.ProductsWHERE categoryid = 4;6. Highlight the written query and click Execute. Observe that the query retrieved 10 rows. Task 2: Write a SELECT statement to retrieve all products with more than $50,000total sales amount1. In the query pane, type the following query after the task 2 description:SELECTd.productid, p.productnameFROM Sales.OrderDetails dINNER JOIN Production.Products p ON p.productid = d.productidGROUP BY d.productid, p.productnameHAVING SUM(d.qty * d.unitprice) > 50000;2. Highlight the written query and click Execute. Observe that the query retrieved four rows. Task 3: Merge the results from task 1 and task 21. In the query pane, type the following query after the task 3 description:SELECTproductid, productnameFROM Production.ProductsWHERE categoryid = 4UNIONSELECTd.productid, p.productnameFROM Sales.OrderDetails dINNER JOIN Production.Products p ON p.productid = d.productidGROUP BY d.productid, p.productnameHAVING SUM(d.qty * d.unitprice) > 50000;2. Highlight the written query and click Execute.


L12-94 Module 12: Using Set Operators3. Observe the result. What is the total number of rows in the result? If you compare this number withan aggregate value of the number of rows from task 1 and task 2, is there any difference? The totalnumber of rows retrieved by the query is 12. This is 2 rows less than the aggregate value of rows fromthe query in task 1 (10 rows) and task 2 (4 rows).4. Highlight the previous query. On the toolbar, click Edit and then Copy.5. In the query window, click the line after the written T-<strong>SQL</strong> statement. On the toolbar, click Edit andthen Paste.6. Modify the T-<strong>SQL</strong> statement by replacing the UNION operator with the UNION ALL operator. Thequery should look like this:SELECTproductid, productnameFROM Production.ProductsWHERE categoryid = 4UNION ALLSELECTd.productid, p.productnameFROM Sales.OrderDetails dINNER JOIN Production.Products p ON p.productid = d.productidGROUP BY d.productid, p.productnameHAVING SUM(d.qty * d.unitprice) > 50000;7. Highlight the modified query and click Execute.8. Observe the result. What is the total number of rows in the result? What is the difference between theUNION and UNION ALL operators? The total number of rows retrieved by the query is 14. It is thesame as the aggregate value of rows from the queries in task 1 and task 2. This is because UNION ALLis a multi-set operator that returns all rows that appear in any of the inputs, without really comparingrows and without eliminating duplicates. The UNION set operator removes the duplicate rows andthe result consists of only distinct rows.So, when should you use UNION ALL and when should you use UNION when unifying two inputs? If apotential exists for duplicates and you need to return the duplicates, use UNION ALL. If a potentialexists for duplicates but you need to return distinct rows, use UNION. If no potential exists forduplicates when unifying the two inputs, UNION and UNION ALL are logically equivalent. However, insuch a case, using UNION ALL is recommended because it removes the overhead of <strong>SQL</strong> Serverchecking for duplicates.


Lab: Using Set Operators L12-95 Task 4: Write a SELECT statement to retrieve the top 10 customers by sales amountfor January 2008 and February 20081. In the query pane, type the following query after the task 4 description:SELECTc1.custid, c1.contactnameFROM(SELECT TOP (10)o.custid, c.contactnameFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidWHERE o.orderdate >= '20080101' AND o.orderdate < '20080201'GROUP BY o.custid, c.contactnameORDER BY SUM(o.val) DESC) AS c1UNIONSELECT c2.custid, c2.contactnameFROM(SELECT TOP (10)o.custid, c.contactnameFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidWHERE o.orderdate >= '20080201' AND o.orderdate < '20080301'GROUP BY o.custid, c.contactnameORDER BY SUM(o.val) DESC) AS c2;2. Highlight the written query and click Execute.


L12-96 Module 12: Using Set OperatorsExercise 2: Writing Queries That Use the CROSS APPLY and OUTER APPLYOperators Task 1: Write a SELECT statement that uses the CROSS APPLY operator to retrieve thelast two orders for each product1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTp.productid, p.productname, o.orderidFROM Production.Products AS pCROSS APPLY(SELECT TOP(2)d.orderidFROM Sales.OrderDetails AS dWHERE d.productid = p.productidORDER BY d.orderid DESC) oORDER BY p.productid;4. Highlight the written query and click Execute. Task 2: Write a SELECT statement that uses the CROSS APPLY operator to retrieve thetop three products based on sales revenue for each customer1. Highlight the provided T-<strong>SQL</strong> code after the task 2 description and click Execute.2. In the query pane, type the following query after the provided T-<strong>SQL</strong> code:SELECTc.custid, c.contactname, p.productid, p.productname, p.totalsalesamountFROM Sales.Customers AS cCROSS APPLY dbo.fnGetTop3ProductsForCustomer (c.custid) AS pORDER BY c.custid;Tip You can make the inline table-valued function (dbo.fnGetTop3ProductsForCustomer)more flexible by making the number of top rows to return an argument instead of fixing thenumber to three in the function’s code.3. Highlight the written query and click Execute. The query retrieved 265 rows. Task 3: Use the OUTER APPLY operator1. Highlight the previous query in task 2. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 3 description. On the toolbar, click Edit andthen Paste.


Lab: Using Set Operators L12-973. Modify the T-<strong>SQL</strong> statement by replacing the CROSS APPLY operator with the OUTER APPLYoperator. The query should look like this:SELECTc.custid, c.contactname, p.productid, p.productname, p.totalsalesamountFROM Sales.Customers AS cOUTER APPLY dbo.fnGetTop3ProductsForCustomer (c.custid) AS pORDER BY c.custid;4. Highlight the modified query and click Execute.5. Notice that the query retrieved 267 rows, which is two more rows than the previous query. If youobserve the result, you will notice two rows with NULL in the columns from the inline table-valuedfunction. Task 4: Analyze the OUTER APPLY operator1. Highlight the previous query in task 3. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 4 description. On the toolbar, click Edit andthen Paste.3. Modify the T-<strong>SQL</strong> statement to filter only rows that have the productid NULL. The query should looklike this:SELECTc.custid, c.contactname, p.productid, p.productname, p.totalsalesamountFROM Sales.Customers AS cOUTER APPLY dbo.fnGetTop3ProductsForCustomer (c.custid) AS pWHERE p.productid IS NULL;4. Highlight the modified query and click Execute.5. Observe the result. What is the difference between the CROSS APPLY and OUTER APPLY operators?The CROSS APPLY operator implements one logical query processing phase - it applies the right tableexpression to each row from the left table, and produces a result table with the unified result sets. Incontrast, the OUTER APPLY operator returns all rows from the left table expression, even when theright table expression returns an empty set. The OUTER APPLY operator adds a second logical phasein which it:• Identifies rows from the left side for which the right table expression returns an empty set.• Adds those rows to the result table as outer rows with NULLs in the right side’s attributes asplaceholders.In a sense, this phase is similar to the phase that adds outer rows in a left outer join. Task 5: Remove the created inline table-valued function• Highlight the provided T-<strong>SQL</strong> statement after task 5 description and click Execute.


L12-98 Module 12: Using Set OperatorsExercise 3: Writing Queries That Use the EXCEPT and INTERSECT Operators Task 1: Write a SELECT statement to return all customers that bought more than 20distinct products1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTo.custidFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY o.custidHAVING COUNT(DISTINCT d.productid) > 20;4. Highlight the written query and click Execute. Task 2: Write a SELECT statement to retrieve all customers from the USA, exceptthose that bought more than 20 distinct products1. In the query pane, type the following query after the task 2 description:SELECTcustidFROM Sales.CustomersWHERE country = 'USA'EXCEPTSELECTo.custidFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY o.custidHAVING COUNT(DISTINCT d.productid) > 20;2. Highlight the written query and click Execute. Task 3: Write a SELECT statement to retrieve customers that spent more than $10,0001. In the query pane, type the following query after the task 3 description:SELECTo.custidFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY o.custidHAVING SUM(d.qty * d.unitprice) > 10000;2. Highlight the written query and click Execute.


Lab: Using Set Operators L12-99 Task 4: Write a SELECT statement that uses the EXCEPT and INTERSECT operators1. Highlight the query from task 2. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 4 description. On the toolbar, click Edit andthen Paste.3. Modify the first SELECT statement so that it selects all customers and not just those from the USA andinclude the INTERSECT operator and adding the query from task 3. The query should look like this:SELECTc.custidFROM Sales.Customers AS cEXCEPTSELECTo.custidFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY o.custidHAVING COUNT(DISTINCT d.productid) > 20INTERSECTSELECTo.custidFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY o.custidHAVING SUM(d.qty * d.unitprice) > 10000;4. Highlight the modified query and click Execute.5. Observe that the total number of rows is 59. Can you explain in business terms which customers arepart of the result? Because the INTERSECT operator is evaluated before the EXCEPT operator, theresult consists of all customers, except those that bought more than 20 different products and spentmore than $10,000.


L12-100 Module 12: Using Set Operators Task 5: Change the operator precedence1. Highlight the previous query in task 4. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 5 description. On the toolbar, click Edit andthen Paste.3. Modify the T-<strong>SQL</strong> statement by adding a set of parentheses around the first two SELECT statements.The query should look like this:(SELECTc.custidFROM Sales.Customers AS cEXCEPTSELECTo.custidFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY o.custidHAVING COUNT(DISTINCT d.productid) > 20)INTERSECTSELECTo.custidFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON d.orderid = o.orderidGROUP BY o.custidHAVING SUM(d.qty * d.unitprice) > 10000;4. Highlight the provided T-<strong>SQL</strong> statement and click Execute.5. Observe that the total number of rows is nine. Is that result different from the result of the query intask 4? Yes, because when you added the parentheses, the <strong>SQL</strong> Server engine first evaluated theEXCEPT operation and then the INTERSECT operation. In business terms, this query retrieved allcustomers that did not buy more than 20 distinct products and that spent more than $10,000.What is the precedence among the set operators? <strong>SQL</strong> defines the following precedence among theset operations: INTERSECT precedes UNION and EXCEPT, while UNION and EXCEPT are consideredequal. In a query that contains multiple set operations, first INTERSECT operations are evaluated, andthen operations with the same precedence are evaluated based on appearance order. Remember thatset operations in parentheses precede all.


L13-101Module 13: Using Window Ranking, Offset and AggregateFunctionsLab: Using Window Ranking, Offset andAggregate FunctionsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L13-102 Module 13: Using Window Ranking, Offset and Aggregate Functions11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Using Window Ranking, Offset and Aggregate Functions L13-103Exercise 1: Writing Queries That Use Ranking Functions Task 1: Write a SELECT statement that uses the ROW_NUMBER function to create acalculated column1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_13_PRJ\10774A_13_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If you are using <strong>SQL</strong> Azure you will get an error, because theUSE statement is not supported and you must manually set the database context using the AvailableDatabases box.5. In the query pane, type the following query after the task 1 description:SELECTorderid,orderdate,val,ROW_NUMBER() OVER (ORDER BY orderdate) AS rownoFROM Sales.OrderValues;6. Highlight the written query and click Execute. Task 2: Add an additional column using the RANK function1. Highlight the previous query. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 2 description. On the toolbar, click Edit andthen Paste.3. Modify the T-<strong>SQL</strong> statement by adding an additional calculated column. The query should looklike this:SELECTorderid,orderdate,val,ROW_NUMBER() OVER (ORDER BY orderdate) AS rowno,RANK() OVER (ORDER BY orderdate) AS ranknoFROM Sales.OrderValues;4. Highlight the written query and click Execute.5. Observe the results. What is the difference between the RANK and ROW_NUMBER functions? TheROW_NUMBER function provides unique sequential integer values within the partition. The RANKfunction assigns the same ranking value to rows with the same values in the specified sort columnswhen the ORDER BY list is not unique. Also, the RANK function skips the next number if there is a tiein the ranking value.


L13-104 Module 13: Using Window Ranking, Offset and Aggregate Functions Task 3: Write a SELECT statement to calculate a rank, partitioned by customer andordered by the order value1. In the query pane, type the following query after the task 3 description:SELECTorderid,orderdate,custid,val,RANK() OVER (PARTITION BY custid ORDER BY val DESC) AS orderranknoFROM Sales.OrderValues;2. Highlight the written query and click Execute. Task 4: Write a SELECT statement to rank orders, partitioned by customer and orderyear, and ordered by the order value1. In the query pane, type the following query after the task 4 description:SELECTcustid,val,YEAR(orderdate) as orderyear,RANK() OVER (PARTITION BY custid, YEAR(orderdate) ORDER BY val DESC) ASorderranknoFROM Sales.OrderValues;2. Highlight the written query and click Execute. Task 5: Filter only orders with the top two ranks1. Highlight the previous query. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 5 description. On the toolbar, click Edit andthen Paste.3. Modify the T-<strong>SQL</strong> statement to look like this:SELECTs.custid,s.orderyear,s.orderrankno,s.valFROM(SELECTcustid,val,YEAR(orderdate) as orderyear,RANK() OVER (PARTITION BY custid, YEAR(orderdate) ORDER BY val DESC) ASorderranknoFROM Sales.OrderValues) AS sWHERE s.orderrankno


Lab: Using Window Ranking, Offset and Aggregate Functions L13-105Exercise 2: Writing Queries That Use Offset Functions Task 1: Write a SELECT statement to retrieve the next row using a common tableexpression (CTE)1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:WITH OrderRows AS(SELECTorderid,orderdate,ROW_NUMBER() OVER (ORDER BY orderdate, orderid) AS rowno,valFROM Sales.OrderValues)SELECTo.orderid,o.orderdate,o.val,o2.val as prevval,o.val - o2.val as diffprevFROM OrderRows AS oLEFT OUTER JOIN OrderRows AS o2 ON o.rowno = o2.rowno + 1;4. Highlight the written query and click Execute. Task 2: Write a SELECT statement that uses the LAG function1. In the query pane, type the following query after the provided T-<strong>SQL</strong> code:SELECTorderid,orderdate,val,LAG(val) OVER (ORDER BY orderdate, orderid) AS prevval,val - LAG(val) OVER (ORDER BY orderdate, orderid) AS diffprevFROM Sales.OrderValues;2. Highlight the written query and click Execute.


L13-106 Module 13: Using Window Ranking, Offset and Aggregate Functions Task 3: Analyze the sales information for the year 20071. Highlight the provided T-<strong>SQL</strong> code after the task 3 description and click Execute.2. In the query pane, type the following query after the provided T-<strong>SQL</strong> code:WITH SalesMonth2007 AS(SELECTMONTH(orderdate) AS monthno,SUM(val) AS valFROM Sales.OrderValuesWHERE orderdate >= '20070101' AND orderdate < '20080101'GROUP BY MONTH(orderdate))SELECTmonthno,val,(LAG(val, 1, 0) OVER (ORDER BY monthno) + LAG(val, 2, 0) OVER (ORDER BY monthno) +LAG(val, 3, 0) OVER (ORDER BY monthno)) / 3 AS avglast3months,val - FIRST_VALUE(val) OVER (ORDER BY monthno ROWS UNBOUNDED PRECEDING) ASdiffjanuary,LEAD(val) OVER (ORDER BY monthno) AS nextvalFROM SalesMonth2007;3. Highlight the written query and click Execute.


Lab: Using Window Ranking, Offset and Aggregate Functions L13-107Exercise 3: Writing Queries That Use Window Aggregate Functions Task 1: Write a SELECT statement to display the contribution of each customer’sorder compared to that customer’s total purchase1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTcustid,orderid,orderdate,val,100. * val / SUM(val) OVER (PARTITION BY custid) AS percoftotalcustFROM Sales.OrderValuesORDER BY custid, percoftotalcust DESC;4. Highlight the written query and click Execute. Task 2: Add a column to display the running sales total1. Highlight the previous query. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 2 description. On the toolbar, click Edit andthen Paste.3. Modify the T-<strong>SQL</strong> statement by adding an additional calculated column. The query should looklike this:SELECTcustid,orderid,orderdate,val,100. * val / SUM(val) OVER (PARTITION BY custid) AS percoftotalcust,SUM(val) OVER (PARTITION BY custidORDER BY orderdate, orderidROWS BETWEEN UNBOUNDED PRECEDINGAND CURRENT ROW) AS runvalFROM Sales.OrderValues;4. Highlight the written query and click Execute.


L13-108 Module 13: Using Window Ranking, Offset and Aggregate Functions Task 3: Analyze the year-to-date sales amount and average sales amount for the lastthree months1. In the query pane, type the following query after the task 3 description:WITH SalesMonth2007 AS(SELECTMONTH(orderdate) AS monthno,SUM(val) AS valFROM Sales.OrderValuesWHERE orderdate >= '20070101' AND orderdate < '20080101'GROUP BY MONTH(orderdate))SELECTmonthno,val,AVG(val) OVER (ORDER BY monthno ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) ASavglast3months,SUM(val) OVER (ORDER BY monthno ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)AS ytdvalFROM SalesMonth2007;2. Highlight the written query and click Execute.


L14-109Module 14: Pivoting and Grouping SetsLab: Pivoting and Grouping SetsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. In the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L14-110 Module 14: Pivoting and Grouping Sets11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Pivoting and Grouping Sets L14-111Exercise 1: Writing Queries That Use the PIVOT Operator Task 1: Write a SELECT statement to retrieve the number of customers for a specificcustomer group1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_14_PRJ\10774A_14_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If you are using <strong>SQL</strong> Azure you will get an error, because theUSE statement is not supported and you must manually set the database context using the AvailableDatabases box.5. Highlight the following provided T-<strong>SQL</strong> code:CREATE VIEW Sales.CustGroups ASSELECTcustid,CHOOSE(custid % 3 + 1, N'A', N'B', N'C') AS custgroup,CountryFROM Sales.Customers;6. Click Execute. This code creates a view named Sales.CustGroups.7. In the query pane, type the following query after the provided T-<strong>SQL</strong> code:SELECTcustid,custgroup,countryFROM Sales.CustGroups;8. Highlight the written query and click Execute.9. Modify the written T-<strong>SQL</strong> code by applying the PIVOT operator. The query should look like this:SELECTcountry,p.A,p.B,p.CFROM Sales.CustGroupsPIVOT (COUNT(custid) FOR custgroup IN (A, B, C)) AS p;10. Highlight the written query and click Execute.


L14-112 Module 14: Pivoting and Grouping Sets Task 2: Specify the grouping element for the PIVOT operator1. Highlight the following provided T-<strong>SQL</strong> code:ALTER VIEW Sales.CustGroups ASSELECTcustid,CHOOSE(custid % 3 + 1, N'A', N'B', N'C') AS custgroup,country,city,contactnameFROM Sales.Customers;2. Click Execute. This code modifies the view by adding two additional columns.3. Highlight the last query in task 1. On the toolbar, click Edit and then Copy.4. In the query window, click the line after the provided T-<strong>SQL</strong> code. On the toolbar, click Edit and thenPaste. The query should look like this:SELECTcountry,p.A,p.B,p.CFROM Sales.CustGroupsPIVOT (COUNT(custid) FOR custgroup IN (A, B, C)) AS p;5. Highlight the copied query and click Execute.6. Observe the result. Is this result the same as the result from the query in task 1? The result is not thesame. More rows were returned after you modified the view.7. Modify the copied T-<strong>SQL</strong> statement to include additional columns from the view. The query shouldlook like this:SELECTcountry,city,contactname,p.A,p.B,p.CFROM Sales.CustGroupsPIVOT (COUNT(custid) FOR custgroup IN (A, B, C)) AS p;8. Highlight the written query and click Execute.9. Notice that you received the same result as the previous query. Why did you get the same number ofrows? The PIVOT operator assumes that all the columns except the aggregation element and thespreading element are part of the grouping columns.


Lab: Pivoting and Grouping Sets L14-113 Task 3: Use a common table expression (CTE) to specify the grouping element for thePIVOT operator1. In the query pane, type the following query after the task 3 description:WITH PivotCustGroups AS(SELECTcustid,country,custgroupFROM Sales.CustGroups)SELECTcountry,p.A,p.B,p.CFROM PivotCustGroupsPIVOT (COUNT(custid) FOR custgroup IN (A, B, C)) AS p;2. Highlight the written query and click Execute.3. Observe the result. Is it the same as the result of the last query in task 1? Can you explain why? Theresult is the same. In this task, the CTE has provided three possible columns to the PIVOT operator. Intask 1, the view also provided three columns to the PIVOT operator.4. Why do you think it is beneficial to use a CTE when using the PIVOT operator? When using the PIVOToperator, you cannot directly specify the grouping element since <strong>SQL</strong> Server automatically assumesthat all columns should be used as grouping elements, with the exception of the spreading andaggregation elements. With a CTE, you can specify the exact columns and therefore control whichcolumns to use for the grouping.


L14-114 Module 14: Pivoting and Grouping Sets Task 4: Write a SELECT statement to retrieve the total sales amount for each customerand product category1. In the query pane, type the following query after the task 4 description:WITH SalesByCategory AS(SELECTo.custid,d.qty * d.unitprice AS salesvalue,c.categorynameFROM Sales.Orders AS oINNER JOIN Sales.OrderDetails AS d ON o.orderid = d.orderidINNER JOIN Production.Products AS p ON p.productid = d.productidINNER JOIN Production.Categories AS c ON c.categoryid = p.categoryidWHERE o.orderdate >= '20080101' AND o.orderdate < '20090101')SELECTcustid,p.Beverages,p.Condiments,p.Confections,p.[Dairy Products],p.[Grains/Cereals],p.[Meat/Poultry],p.Produce,p.SeafoodFROM SalesByCategoryPIVOT (SUM(salesvalue) FOR categorynameIN (Beverages, Condiments, Confections, [Dairy Products], [Grains/Cereals],[Meat/Poultry], Produce, Seafood)) AS p;2. Highlight the written query and click Execute.


Lab: Pivoting and Grouping Sets L14-115Exercise 2: Writing Queries That Use the UNPIVOT Operator Task 1: Create and query the Sales.PivotCustGroups view1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. Highlight the following provided T-<strong>SQL</strong> code:CREATE VIEW Sales.PivotCustGroups ASWITH PivotCustGroups AS(SELECTcustid,country,custgroupFROM Sales.CustGroups)SELECTcountry,p.A,p.B,p.CFROM PivotCustGroupsPIVOT (COUNT(custid) FOR custgroup IN (A, B, C)) AS p;4. Click Execute. This code creates a view named Sales.PivotCustGroups.5. In the query pane, type the following query after the provided T-<strong>SQL</strong> code:SELECTcountry, A, B, CFROM Sales.PivotCustGroups;6. Highlight the written query and click Execute. Task 2: Write a SELECT statement to retrieve a row for each country andcustomer group1. In the query pane, type the following query after the T-<strong>SQL</strong> code:SELECTcustgroup,country,numberofcustomersFROM Sales.PivotCustGroupsUNPIVOT (numberofcustomers FOR custgroup IN (A, B, C)) AS p;2. Highlight the written query and click Execute. Task 3: Remove the created views• Highlight the provided T-<strong>SQL</strong> statement and click Execute.


L14-116 Module 14: Pivoting and Grouping SetsExercise 3: Writing Queries That Use the GROUPING SETS, CUBE, andROLLUP Subclauses Task 1: Write a SELECT statement that uses the GROUPING SETS subclause to returnthe number of customers for different grouping sets1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTcountry,city,COUNT(custid) AS noofcustomersFROM Sales.CustomersGROUP BYGROUPING SETS((country, city),(country),(city),());4. Highlight the written query and click Execute. Task 2: Write a SELECT statement that uses the CUBE subclause to retrieve groupingsets based on yearly, monthly, and daily sales values1. In the query pane, type the following query after the task 2 description:SELECTYEAR(orderdate) AS orderyear,MONTH(orderdate) AS ordermonth,DAY(orderdate) AS orderday,SUM(val) AS salesvalueFROM Sales.OrderValuesGROUP BYCUBE (YEAR(orderdate), MONTH(orderdate), DAY(orderdate));2. Highlight the written query and click Execute. Task 3: Write the same SELECT statement using the ROLLUP subclause1. In the query pane, type the following query after the task 3 description:SELECTYEAR(orderdate) AS orderyear,MONTH(orderdate) AS ordermonth,DAY(orderdate) AS orderday,SUM(val) AS salesvalueFROM Sales.OrderValuesGROUP BYROLLUP (YEAR(orderdate), MONTH(orderdate), DAY(orderdate));2. Highlight the written query and click Execute.


Lab: Pivoting and Grouping Sets L14-1173. Observe the result. What is the difference between the ROLLUP and CUBE subclauses of the GROUPBY clause? Like the CUBE subclause, the ROLLUP subclause provides an abbreviated way to definemultiple grouping sets. However, unlike CUBE, ROLLUP doesn’t produce all possible grouping setsthat can be defined based on the input members—it produces a subset of those. ROLLUP assumes ahierarchy among the input members and produces all grouping sets that make sense considering thehierarchy. In other words, while CUBE(a, b, c) produces all eight possible grouping sets out of thethree input members, ROLLUP(a, b, c) produces only four grouping sets, assuming the hierarchya>b>c. ROLLUP(a, b, c) is the equivalent of specifying GROUPING SETS( (a, b, c), (a, b), (a), () ).Which is the more appropriate subclause to use in this example? Since year, month, and day form ahierarchy, the ROLLUP clause is more suitable. There is probably not much interest in showingaggregates for a month irrespective of year, but the other way around is interesting. Task 4: Analyze the total sales value by year and month1. In the query pane, type the following query after the task 4 description:SELECTGROUPING_ID(YEAR(orderdate), MONTH(orderdate)) as groupid,YEAR(orderdate) AS orderyear,MONTH(orderdate) AS ordermonth,SUM(val) AS salesvalueFROM Sales.OrderValuesGROUP BYROLLUP (YEAR(orderdate), MONTH(orderdate))ORDER BY groupid, orderyear, ordermonth;2. Highlight the written query and click Execute.


L14-118 Module 14: Pivoting and Grouping Sets


L15-119Module 15: <strong>Querying</strong> <strong>SQL</strong> Server MetadataLab: <strong>Querying</strong> <strong>SQL</strong> Server MetadataLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L15-120 Module 15: <strong>Querying</strong> <strong>SQL</strong> Server Metadata11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: <strong>Querying</strong> <strong>SQL</strong> Server Metadata L15-121Exercise 1: <strong>Querying</strong> System Catalog Views Task 1: Write a SELECT statement to retrieve all databases1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_15_PRJ\10774A_15_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard).5. In the query pane, type the following query after the task 1 description:SELECT name, dbid, crdateFROM sys.sysdatabases;6. Highlight the written query and click Execute. Observe that the query retrieved 8 rows (note thatusing <strong>SQL</strong> Azure you can get a different result). Task 2: Write a SELECT statement to retrieve all user-defined tables in theT<strong>SQL</strong><strong>2012</strong> database1. In the query pane, type the following query after the task 2 description:SELECTobject_id, name, schema_id, type, type_desc, create_date, modify_dateFROM sys.objects;2. Highlight the written query and click Execute.3. Highlight the previous query. On the toolbar, click Edit and then Copy.4. In the query window, click the line after the written T-<strong>SQL</strong> statement. On the toolbar, click Edit andthen Paste.5. Modify the T-<strong>SQL</strong> statement to retrieve all distinct values for the columns type and type_desc. Thequery should look like this:SELECT DISTINCTtype, type_descFROM sys.objectsORDER BY type_desc;6. Highlight the written query and click Execute.7. Highlight the first query. On the toolbar, click Edit and then Copy.8. In the query window, click the line after the written T-<strong>SQL</strong> statement. On the toolbar, click Edit andthen Paste.


L15-122 Module 15: <strong>Querying</strong> <strong>SQL</strong> Server Metadata9. Modify the T-<strong>SQL</strong> statement to filter only user-defined tables. The query should look like this:SELECTobject_id, name, schema_id, type, type_desc, create_date, modify_dateFROM sys.objectsWHERE type = N'U';10. Highlight the written query and click Execute. Task 3: Use a different approach to retrieve all user-defined tables in theT<strong>SQL</strong><strong>2012</strong> database1. In the query pane, type the following query after the task 3 description:SELECTobject_id, name, SCHEMA_NAME(schema_id) AS schemaname, type, type_desc,create_date, modify_dateFROM sys.tables;2. Highlight the written query and click Execute.3. In the query pane, type the following query after the previous query:SELECTobject_id, name, SCHEMA_NAME(schema_id) AS schemaname, type, type_desc,create_date, modify_dateFROM sys.views;4. Highlight the written query and click Execute. Task 4: Write a SELECT statement to retrieve all columns from theSales.Customers table1. In the query pane, type the following query after the task 4 description:SELECTc.name AS columnname, c.column_id, c.system_type_id, c.max_length, c.precision,c.scale, c.collation_nameFROM sys.columns AS cWHERE object_id = OBJECT_ID('Sales.Customers')ORDER BY c.column_id;2. Highlight the written query and click Execute.


Lab: <strong>Querying</strong> <strong>SQL</strong> Server Metadata L15-123Exercise 2: <strong>Querying</strong> System Functions Task 1: Write a SELECT statement to retrieve the current database name1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTDB_ID() AS databaseid,DB_NAME(DB_ID()) AS databasename,USER_NAME() as currusername;4. Highlight the written query and click Execute. Task 2: Write a SELECT statement to retrieve the object name and schema name1. In the query pane, type the following query after the task 2 description:SELECTname,OBJECT_NAME(object_id) AS tablename,OBJECT_SCHEMA_NAME(object_id) AS schemanameFROM sys.columns;2. Highlight the written query and click Execute. Task 3: Write a SELECT statement to retrieve all the columns from the user-definedtables that contain the word “name” in the column name1. In the query pane, type the following query after the task 3 description:SELECTc.name AS columnname,OBJECT_NAME (c.object_id) AS tablename,OBJECT_SCHEMA_NAME(c.object_id) AS schemanameFROM sys.columns AS cWHEREc.name LIKE N'%name%'AND OBJECTPROPERTY(c.object_id, N'IsUserTable') = 1;2. Highlight the written query and click Execute. Task 4: Retrieve the view definition1. In the query pane, type the following query after the task 4 description:SELECT OBJECT_DEFINITION(OBJECT_ID(N'Sales.CustOrders'));2. Highlight the written query and click Execute.


L15-124 Module 15: <strong>Querying</strong> <strong>SQL</strong> Server MetadataExercise 3: <strong>Querying</strong> System Dynamic Management Views Task 1: Write a SELECT statement to return all current sessions1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following query after the task 1 description:SELECTsession_id, login_time, host_name, language, date_formatFROMsys.dm_exec_sessions;4. Highlight the written query and click Execute. Task 2: Execute the provided T-<strong>SQL</strong> statement1. Highlight the following T-<strong>SQL</strong> code under the task 2 description:SELECTcpu_count AS 'Logical CPU Count',hyperthread_ratio AS 'Hyperthread Ratio',cpu_count/hyperthread_ratio As 'Physical CPU Count',physical_memory_kb/1024 AS 'Physical Memory (MB)',sqlserver_start_time AS 'Last <strong>SQL</strong> Start'FROM sys.dm_os_sys_info;2. Click Execute. Task 3: Write a SELECT statement to retrieve the current memory information1. In the query pane, type the following query after the task 3 description:SELECTtotal_physical_memory_kb,available_physical_memory_kb,total_page_file_kb,available_page_file_kb,system_memory_state_descFROM sys.dm_os_sys_memory;2. Highlight the written query and click Execute.


L16-125Module 16: Executing Stored ProceduresLab: Executing Stored ProceduresLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L16-126 Module 16: Executing Stored Procedures11. In the Connect to Server window, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Executing Stored Procedures L16-127Exercise 1: Using the EXECUTE Statement to Invoke Stored Procedures Task 1: Create and execute a stored procedure1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_16_PRJ\10774A_16_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If using <strong>SQL</strong> Azure select the T<strong>SQL</strong><strong>2012</strong> database in theAvailable Databases drop-down box.5. Highlight the following T-<strong>SQL</strong> code under the task 1 description:CREATE PROCEDURE Sales.GetTopCustomers ASSELECT TOP(10)c.custid,c.contactname,SUM(o.val) AS salesvalueFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidGROUP BY c.custid, c.contactnameORDER BY salesvalue DESC;6. Click Execute. You have created a stored procedure named Sales.GetTopCustomers.7. In the query pane, type the following T-<strong>SQL</strong> code after the previous T-<strong>SQL</strong> code:EXECUTE Sales.GetTopCustomers;8. Highlight the written T-<strong>SQL</strong> code and click Execute. You have executed the stored procedure. Task 2: Modify the stored procedure and execute it1. Highlight the following T-<strong>SQL</strong> code after the task 2 description:ALTER PROCEDURE Sales.GetTopCustomers ASSELECTc.custid,c.contactname,SUM(o.val) AS salesvalueFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidGROUP BY c.custid, c.contactnameORDER BY salesvalue DESCOFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;2. Click Execute. You have modified the Sales.GetTopCustomers stored procedure.3. In the query pane, type the following T-<strong>SQL</strong> code after the previous T-<strong>SQL</strong> code:EXECUTE Sales.GetTopCustomers;


L16-128 Module 16: Executing Stored Procedures4. Highlight the written T-<strong>SQL</strong> code and click Execute. You have executed the modified storedprocedure.5. Compare both the code and the result of the two versions of the stored procedure. What is thedifference between them? In the modified version, the TOP option has been replaced with theOFFSET-FETCH option. Despite this change, the result is the same.If some applications had been using the stored procedure in task 1, would they still work properlyafter the change you applied in task 2? Yes, since the result from the stored procedure is still thesame. This demonstrates a huge benefit of using stored procedures as an additional layer betweenthe database and the application/middle tier: Even if you change the underlying T-<strong>SQL</strong> code, theapplication would work properly without any changes. There are also other benefits of using storedprocedures in terms of performance (e.g., caching and reuse of plans) and security (e.g., preventing<strong>SQL</strong> injections).


Lab: Executing Stored Procedures L16-129Exercise 2: Passing Parameters to Stored Procedures Task 1: Execute a stored procedure with a parameter for order year1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. Highlight the following T-<strong>SQL</strong> code under the task 1 description:ALTER PROCEDURE Sales.GetTopCustomers@orderyear intASSELECTc.custid,c.contactname,SUM(o.val) AS salesvalueFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidWHERE YEAR(o.orderdate) = @orderyearGROUP BY c.custid, c.contactnameORDER BY salesvalue DESCOFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;4. Click Execute. You have modified the Sales.GetTopCustomers stored procedure to accept theparameter @orderyear. Notice that the modified stored procedure uses a predicate in the WHEREclause that isn’t a search argument. This predicate was used to keep things simple. The best practice isto avoid such filtering because it does not allow efficient use of indexing. A better approach would beto use the DATETIMEFROMPARTS function to provide a search argument for orderdate:WHERE o.orderdate >= DATETIMEFROMPARTS(@orderyear, 1, 1, 0, 0, 0, 0)AND o.orderdate < DATETIMEFROMPARTS(@orderyear + 1, 1, 1, 0, 0, 0, 0)5. In the query pane, type the following T-<strong>SQL</strong> code after the previous T-<strong>SQL</strong> code:EXECUTE Sales.GetTopCustomers @orderyear = 2007;Notice that you are passing the parameter by name—this is considered the best practice. There is alsosupport for passing parameters by position. For example, the following EXECUTE statement wouldretrieve the same result as the T-<strong>SQL</strong> code you just typed:EXECUTE Sales.GetTopCustomers 2007;6. Highlight the written T-<strong>SQL</strong> code and click Execute.7. After the previous T-<strong>SQL</strong> code, type the following T-<strong>SQL</strong> code to execute the stored procedure for theorder year 2008:EXECUTE Sales.GetTopCustomers @orderyear = 2008;8. Highlight the written T-<strong>SQL</strong> code and click Execute.9. After the previous T-<strong>SQL</strong> code, type the following T-<strong>SQL</strong> code to execute the stored procedurewithout specifying a parameter:EXECUTE Sales.GetTopCustomers;


L16-130 Module 16: Executing Stored Procedures10. Highlight the written T-<strong>SQL</strong> code and click Execute.11. Observe the error message:Procedure or function 'GetTopCustomers' expects parameter '@orderyear', which was not supplied.This error message is telling you that the @orderyear parameter was not supplied.12. Suppose that an application named MyCustomers is using the exercise 1 version of the storedprocedure. Would the modification made to the stored procedure in this exercise impact the usabilityof the GetCustomerInfo application? Yes. The exercise 1 version of the stored procedure did not needa parameter, whereas the version in this exercise does not work without a parameter. To avoidproblems, you can add a default parameter to the stored procedure. That way, the MyCustomersapplication does not have to be changed to support the @orderyear parameter. Task 2: Modify the stored procedure to have a default value for the parameter1. Highlight the following T-<strong>SQL</strong> code under the task 2 description:ALTER PROCEDURE Sales.GetTopCustomers@orderyear int = NULLASSELECTc.custid,c.contactname,SUM(o.val) AS salesvalueFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidWHERE YEAR(o.orderdate) = @orderyear OR @orderyear IS NULLGROUP BY c.custid, c.contactnameORDER BY salesvalue DESCOFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;2. Click Execute. You have modified the Sales.GetTopCustomers stored procedure to have a defaultvalue (NULL) for the @orderyear parameter. You have also added an additional logical expression tothe WHERE clause.3. In the query pane, type the following T-<strong>SQL</strong> code after the previous T-<strong>SQL</strong> code:EXECUTE Sales.GetTopCustomers;This code tests the modified stored procedure by executing it without specifying a parameter.4. Highlight the written query and click Execute.5. Observe the result. How do the changes to the stored procedure in task 2 influence the MyCustomersapplication and the design of future applications? The changes enable the MyCustomers applicationto use the modified stored procedure; no changes need to be made to the application. The changesadd new possibilities for future applications because the modified stored procedure accepts the orderyear as a parameter.


Lab: Executing Stored Procedures L16-131 Task 3: Pass multiple parameters to the stored procedure1. Highlight the following T-<strong>SQL</strong> code under the task 3 description:ALTER PROCEDURE Sales.GetTopCustomers@orderyear int = NULL,@n int = 10ASSELECTc.custid,c.contactname,SUM(o.val) AS salesvalueFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidWHERE YEAR(o.orderdate) = @orderyear OR @orderyear IS NULLGROUP BY c.custid, c.contactnameORDER BY salesvalue DESCOFFSET 0 ROWS FETCH NEXT @n ROWS ONLY;2. Click Execute. You have modified the Sales.GetTopCustomers stored procedure to have an additionalparameter named @n. You can use this parameter to specify how many customers to retrieve. Thedefault value is 10.3. After the previous T-<strong>SQL</strong> code, type the following T-<strong>SQL</strong> code to execute the modified storedprocedure:EXECUTE Sales.GetTopCustomers;4. Highlight the written query and click Execute.5. After the previous T-<strong>SQL</strong> code, type the following T-<strong>SQL</strong> code to retrieve the top five customers forthe year 2008:EXECUTE Sales.GetTopCustomers @orderyear = 2008, @n = 5;6. Highlight the written query and click Execute.7. After the previous T-<strong>SQL</strong> code, type the following T-<strong>SQL</strong> code to retrieve the top 10 customers forthe year 2007:EXECUTE Sales.GetTopCustomers @orderyear = 2007;8. Highlight the written query and click Execute.9. After the previous T-<strong>SQL</strong> code, type the following T-<strong>SQL</strong> code to retrieve the top 20 customers:EXECUTE Sales.GetTopCustomers @n = 20;10. Highlight the written query and click Execute.11. Do the applications using the stored procedure need to be changed because another parameter wasadded? No changes need to be made to the application.


L16-132 Module 16: Executing Stored Procedures Task 4: Return the result from a stored procedure using the OUTPUT clause1. Highlight the following T-<strong>SQL</strong> code under the task 4 description:ALTER PROCEDURE Sales.GetTopCustomers@customerpos int = 1,@customername nvarchar(30) OUTPUTASSET @customername = (SELECTc.contactnameFROM Sales.OrderValues AS oINNER JOIN Sales.Customers AS c ON c.custid = o.custidGROUP BY c.custid, c.contactnameORDER BY SUM(o.val) DESCOFFSET @customerpos - 1 ROWS FETCH NEXT 1 ROW ONLY);2. Click Execute.3. Find the following DECLARE statement in the provided code:DECLARE @outcustomername nvarchar(30);This statement declares a parameter named @outcustomername.4. After the DECLARE statement, add code that uses the OUTPUT clause to return the stored procedure’sresult as a variable named @outcustomername. Your code together with the provided DECLAREstatement should look like this:DECLARE @outcustomername nvarchar(30);EXECUTE Sales.GetTopCustomers @customerpos = 1, @customername = @outcustomernameOUTPUT;SELECT @outcustomername AS customername;5. Highlight all three T-<strong>SQL</strong> statements and click Execute.


Lab: Executing Stored Procedures L16-133Exercise 3: Executing System Stored Procedures Task 1: Execute the stored procedure sys.sp_help1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following T-<strong>SQL</strong> code after the task 1 description:EXEC sys.sp_help;4. Highlight the written query and click Execute.5. In the query pane, type the following T-<strong>SQL</strong> code after the previous T-<strong>SQL</strong> code:EXEC sys.sp_help N'Sales.Customers';6. Highlight the written query and click Execute. Task 2: Execute the stored procedure sys.sp_helptext1. In the query pane, type the following T-<strong>SQL</strong> code after the task 2 description:EXEC sys.sp_helptext N'Sales.GetTopCustomers';2. Highlight the written query and click Execute. Task 3: Execute the stored procedure sys.sp_columns1. In the query pane, type the following T-<strong>SQL</strong> code after the task 3 description:EXEC sys.sp_columns @table_name = N'Customers', @table_owner = N'Sales';2. Highlight the written query and click Execute. Task 4: Drop the created stored procedure• Highlight the provided T-<strong>SQL</strong> statement under the task 4 description and click Execute.


L16-134 Module 16: Executing Stored Procedures


L17-135Module 17: Programming with T-<strong>SQL</strong>Lab: Programming with T-<strong>SQL</strong>Lab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L17-136 Module 17: Programming with T-<strong>SQL</strong>11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Programming with T-<strong>SQL</strong> L17-137Exercise 1: Declaring Variables and Delimiting Batches Task 1: Declare a variable and retrieve the value1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_17_PRJ\10774A_17_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard).5. In the query pane, type the following T-<strong>SQL</strong> code after the task 1 description:DECLARE @num int = 5;SELECT @num AS mynumber;6. Highlight the written T-<strong>SQL</strong> code and click Execute.7. In the query pane, type the following T-<strong>SQL</strong> code after the previous T-<strong>SQL</strong> code:DECLARE@num1 int,@num2 int;SET @num1 = 4;SET @num2 = 6;SELECT @num1 + @num2 AS totalnum;8. Highlight the written T-<strong>SQL</strong> code and click Execute. Task 2: Set the variable value using a SELECT statement1. In the query pane, type the following T-<strong>SQL</strong> code after the task 2 description:DECLARE @empname nvarchar(30);SET @empname = (SELECT firstname + N' ' + lastname FROM HR.Employees WHERE empid =1);SELECT @empname AS employee;2. Highlight the written T-<strong>SQL</strong> code and click Execute.3. Observe the result. What would happen if the SELECT statement would return more than one row?You would get an error because the SET statement requires you to use a scalar subquery to pull datafrom a table. Remember that a scalar subquery fails at runtime if it returns more than one value.


L17-138 Module 17: Programming with T-<strong>SQL</strong> Task 3: Use a variable in the WHERE clause1. In the query pane, type the following T-<strong>SQL</strong> code after the task 3 description:DECLARE@empname nvarchar(30),@empid int;SET @empid = 5;SET @empname = (SELECT firstname + N' ' + lastname FROM HR.Employees WHERE empid =@empid);SELECT @empname AS employee;2. Highlight the written T-<strong>SQL</strong> code and click Execute. Task 4: Add a batch delimiter1. Highlight the T-<strong>SQL</strong> code in task 3. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 4 description. On the toolbar, click Edit and thenPaste.3. In the code you just copied, add the batch delimiter GO before this statement:SELECT @empname AS employee;4. Make sure your T-<strong>SQL</strong> code looks like this:DECLARE@empname nvarchar(30),@empid int;SET @empid = 5;SET @empname = (SELECT firstname + N' ' + lastname FROM HR.Employees WHERE empid =@empid)GOSELECT @empname AS employee;5. Highlight the written T-<strong>SQL</strong> code and click Execute.6. Observe the error message:Must declare the scalar variable "@empname".Can you explain why the batch delimiter caused an error? Variables are local to the batch in whichthey are defined. If you try to refer to a variable that was defined in another batch, you get an errorsaying that the variable was not defined. Also, keep in mind that GO is a client command and not aserver T-<strong>SQL</strong> command.


Lab: Programming with T-<strong>SQL</strong> L17-139Exercise 2: Using Control-of-Flow Elements Task 1: Write basic conditional logic1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following T-<strong>SQL</strong> code after the task 1 description:DECLARE@i int = 8,@result nvarchar(20);IF @i < 5SET @result = N'Less than 5'ELSE IF @i 10SET @result = N'More than 10'ELSESET @result = N'Unknown';SELECT @result AS result;4. Highlight the written T-<strong>SQL</strong> code and click Execute.5. In the query pane, type the following T-<strong>SQL</strong> code:DECLARE@i int = 8,@result nvarchar(20);SET @result =CASEWHEN @i < 5 THENN'Less than 5'WHEN @i 10 THENN'More than 10'ELSEN'Unknown'END;SELECT @result AS result;This code uses a CASE expression and only one SET expression to get the same result as the previousT-<strong>SQL</strong> code. Remember to use a CASE expression when it is a matter of returning an expression.However, if you need to execute multiple statements, you cannot replace IF with CASE.6. Highlight the written T-<strong>SQL</strong> code and click Execute.


L17-140 Module 17: Programming with T-<strong>SQL</strong> Task 2: Check the employee birthdate1. In the query pane, type the following T-<strong>SQL</strong> code after the task 2 description:DECLARE@birthdate date,@cmpdate date;SET @birthdate = (SELECT birthdate FROM HR.Employees WHERE empid = 5);SET @cmpdate = '19700101';IF @birthdate < @cmpdatePRINT 'The person selected was born before January 1, 1970'ELSEPRINT 'The person selected was born on or after January 1, 1970';2. Highlight the written T-<strong>SQL</strong> code and click Execute. Task 3: Create and execute a stored procedure1. Highlight the following T-<strong>SQL</strong> code under the task 3 description:CREATE PROCEDURE Sales.CheckPersonBirthDate@empid int,@cmpdate dateASDECLARE@birthdate date;SET @birthdate = (SELECT birthdate FROM HR.Employees WHERE empid = @empid);IF @birthdate < @cmpdatePRINT 'The person selected was born before ' + FORMAT(@cmpdate, 'MMMM d, yyyy','en-US');ELSEPRINT 'The person selected was born on or after ' + FORMAT(@cmpdate, 'MMMM d,yyyy', 'en-US');2. Click Execute. You have created a stored procedure named Sales.CheckPersonBirthDate. It has twoparameters: @empid, which you use to specify an employee ID, and @cmpdate, which you use as acomparison date.3. In the query pane, type the following T-<strong>SQL</strong> code after the provided T-<strong>SQL</strong> code:EXECUTE Sales.CheckPersonBirthDate @empid = 3, @cmpdate = '19900101';4. Highlight the written T-<strong>SQL</strong> code and click Execute.


Lab: Programming with T-<strong>SQL</strong> L17-141 Task 4: Execute a loop using the WHILE statement1. In the query pane, type the following T-<strong>SQL</strong> code after the task 4 description:DECLARE @i int = 1;WHILE @i


L17-142 Module 17: Programming with T-<strong>SQL</strong>Exercise 3: Generating a Dynamic <strong>SQL</strong> Statement Task 1: Write a dynamic <strong>SQL</strong> statement that does not use a parameter1. In Solution Explorer, double-click the query 71 - Lab Exercise 3.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following T-<strong>SQL</strong> code after the task 1 description:DECLARE @<strong>SQL</strong>str nvarchar(200);SET @<strong>SQL</strong>str = N'SELECT empid, firstname, lastname FROM HR.Employees';EXECUTE sys.sp_executesql @statement = @<strong>SQL</strong>str;4. Highlight the written T-<strong>SQL</strong> code and click Execute. Task 2: Write a dynamic <strong>SQL</strong> statement that uses a parameter1. Highlight the T-<strong>SQL</strong> code in task 1. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 2 description. On the toolbar, click Edit andthen Paste.3. Modify the T-<strong>SQL</strong> code to look like this:DECLARE@<strong>SQL</strong>str nvarchar(200),@<strong>SQL</strong>param nvarchar(100);SET @<strong>SQL</strong>str = N'SELECT empid, firstname, lastname FROM HR.Employees WHERE empid =@empid';SET @<strong>SQL</strong>param = N'@empid int';EXECUTE sys.sp_executesql @statement = @<strong>SQL</strong>str, @params = @<strong>SQL</strong>param, @empid = 5;4. Highlight the written T-<strong>SQL</strong> code and click Execute.


Lab: Programming with T-<strong>SQL</strong> L17-143Exercise 4: Using Synonyms Task 1: Create and use a synonym for a table1. In Solution Explorer, double-click the query 81 - Lab Exercise 4.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. In the query pane, type the following T-<strong>SQL</strong> code after the task 1 description:CREATE SYNONYM dbo.PersonFOR AdventureWorks2008R2.Person.Person;4. Highlight the written T-<strong>SQL</strong> code and click Execute. You have created a synonym named dbo.Person.5. In the query pane, type the following SELECT statement after the previous T-<strong>SQL</strong> code:SELECT FirstName, LastNameFROM dbo.Person;6. Highlight the written query and click Execute. Task 2: Drop the synonym1. Highlight the following T-<strong>SQL</strong> code under the task 2 description:DROP SYNONYM dbo.Person;2. Click Execute.


L17-144 Module 17: Programming with T-<strong>SQL</strong>


L18-145Module 18: Implementing Error HandlingLab: Implementing Error HandlingLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L18-146 Module 18: Implementing Error Handling11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Implementing Error Handling L18-147Exercise 1: Redirecting Errors with TRY / CATCH Task 1: Write a basic TRY / CATCH construct1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_18_PRJ\10774A_18_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard). If you are using <strong>SQL</strong> Azure you will get an error, because theUSE statement is not supported and you must manually set the database context using the AvailableDatabases box.5. Highlight the following SELECT statement under the task 1 description:SELECT CAST(N'Some text' AS int);6. Click Execute. Notice the conversion error.7. Write a TRY / CATCH construct. Your T-<strong>SQL</strong> code should look like this:BEGIN TRYSELECT CAST(N'Some text' AS int);END TRYBEGIN CATCHPRINT 'Error';END CATCH;8. Highlight the written T-<strong>SQL</strong> code and click Execute. Task 2: Display an error number and an error message1. Highlight the following T-<strong>SQL</strong> code under the task 2 description:DECLARE @num varchar(20) = '0';BEGIN TRYPRINT 5. / CAST(@num AS numeric(10,4));END TRYBEGIN CATCHEND CATCH;2. Click Execute. Notice that you did not get an error because you used the TRY / CATCH construct.3. Modify the T-<strong>SQL</strong> code by adding two PRINT statements. The T-<strong>SQL</strong> code should look like this:DECLARE @num varchar(20) = '0';BEGIN TRYPRINT 5. / CAST(@num AS numeric(10,4));END TRYBEGIN CATCHPRINT 'Error Number: ' + CAST(ERROR_NUMBER() AS varchar(10));PRINT 'Error Message: ' + ERROR_MESSAGE();END CATCH;


L18-148 Module 18: Implementing Error Handling4. Highlight the T-<strong>SQL</strong> code and click Execute.5. Change the value of the @num variable to look like this:DECLARE @num varchar(20) = 'A';6. Highlight the T-<strong>SQL</strong> code and click Execute. Notice that you get a different error number andmessage.7. Change the value of the @num variable to look like this:DECLARE @num varchar(20) = ' 1000000000';8. Highlight the T-<strong>SQL</strong> code and click Execute. Notice that you get a different error number andmessage. Task 3: Add conditional logic to a CATCH block1. Highlight the T-<strong>SQL</strong> code in task 2, step 3. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 3 description. On the toolbar, click Edit and thenPaste.3. Modify the T-<strong>SQL</strong> code to look like this:DECLARE @num varchar(20) = 'A';BEGIN TRYPRINT 5. / CAST(@num AS numeric(10,4));END TRYBEGIN CATCHIF ERROR_NUMBER() IN (245, 8114)BEGINPRINT 'Handling conversion error...'ENDELSEBEGINPRINT 'Handling non-conversion error...';END;PRINT 'Error Number: ' + CAST(ERROR_NUMBER() AS varchar(10));PRINT 'Error Message: ' + ERROR_MESSAGE();END CATCH;4. Highlight the written query and click Execute.5. Change the value of the @num variable to look like this:DECLARE @num varchar(20) = '0';6. Highlight the T-<strong>SQL</strong> code and click Execute.


Lab: Implementing Error Handling L18-149 Task 4: Execute a stored procedure in the CATCH block1. Highlight the following T-<strong>SQL</strong> code under the task 4 description:CREATE PROCEDURE dbo.GetErrorInfo ASPRINT 'Error Number: ' + CAST(ERROR_NUMBER() AS varchar(10));PRINT 'Error Message: ' + ERROR_MESSAGE();PRINT 'Error Severity: ' + CAST(ERROR_SEVERITY() AS varchar(10));PRINT 'Error State: ' + CAST(ERROR_STATE() AS varchar(10));PRINT 'Error Line: ' + CAST(ERROR_LINE() AS varchar(10));PRINT 'Error Proc: ' + COALESCE(ERROR_PROCEDURE(), 'Not within procedure');2. Click Execute. You have created a stored procedure named dbo.GetErrorInfo.3. Highlight the T-<strong>SQL</strong> code in task 2, step 3. On the toolbar, click Edit and then Copy.4. In the query window, click the line after the written stored procedure. On the toolbar, click Edit andthen Paste.5. Modify the T-<strong>SQL</strong> code to look like this:DECLARE @num varchar(20) = '0';BEGIN TRYPRINT 5. / CAST(@num AS numeric(10,4));END TRYBEGIN CATCHEXECUTE dbo.GetErrorInfo;END CATCH;6. Highlight the written T-<strong>SQL</strong> code and click Execute.


L18-150 Module 18: Implementing Error HandlingExercise 2: Using THROW to Pass an Error Message Back to a Client Task 1: Re-throw the existing error back to a client1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. Highlight the T-<strong>SQL</strong> code in exercise 1, task 4, step 5. On the toolbar, click Edit and then Copy.4. In the query window, click the line after the task 1 description. On the toolbar, click Edit andthen Paste.5. Modify the T-<strong>SQL</strong> code to look like this:DECLARE @num varchar(20) = '0';BEGIN TRYPRINT 5. / CAST(@num AS numeric(10,4));END TRYBEGIN CATCHEXECUTE dbo.GetErrorInfo;THROW;END CATCH;6. Highlight the written T-<strong>SQL</strong> code and click Execute. Task 2: Add an error handling routine1. Highlight the T-<strong>SQL</strong> code in task 1. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 2 description. On the toolbar, click Edit andthen Paste.3. Modify the T-<strong>SQL</strong> code to look like this:DECLARE @num varchar(20) = 'A';BEGIN TRYPRINT 5. / CAST(@num AS numeric(10,4));END TRYBEGIN CATCHEXECUTE dbo.GetErrorInfo;IF ERROR_NUMBER() = 8134BEGINPRINT 'Handling devision by zero...';ENDELSEBEGINPRINT 'Throwing original error';THROW;END;END CATCH;4. Highlight the written T-<strong>SQL</strong> code and click Execute.


Lab: Implementing Error Handling L18-151 Task 3: Add a different error handling routine1. Find the following T-<strong>SQL</strong> code under the task 3 description:DECLARE @msg AS varchar(2048);SET @msg = 'You are doing the exercise for Module 18 on ' + FORMAT(CURRENT_TIMESTAMP,'MMMM d, yyyy', 'en-US') + '. It''s not an error but it means that you are near thefinal module!';2. After the provided code, add a THROW statement. The completed T-<strong>SQL</strong> code should look like this:DECLARE @msg AS varchar(2048);SET @msg = 'You are doing the exercise for Module 18 on ' + FORMAT(CURRENT_TIMESTAMP,'MMMM d, yyyy', 'en-US') + '. It''s not an error but it means that you are near thefinal module!';THROW 50001, @msg, 1;3. Highlight the written T-<strong>SQL</strong> code and click Execute. Task 4: Remove the stored procedure• Highlight the provided T-<strong>SQL</strong> statement under the task 4 description and click Execute.


L18-152 Module 18: Implementing Error Handling


L19-153Module 19: Implementing TransactionsLab: Implementing TransactionsLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on the Actionmenu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L19-154 Module 19: Implementing Transactions11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Implementing Transactions L19-155Exercise 1: Controlling Transactions with BEGIN, COMMIT, and ROLLBACK Task 1: Commit a transaction1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_19_PRJ\10774A_19_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is notvisible, select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard).5. Modify the T-<strong>SQL</strong> code under the task 1 description by adding the BEGIN TRAN and COMMIT TRANstatements. Your T-<strong>SQL</strong> code should look like this:BEGIN TRAN;INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Johnson', N'Test 1', N'Sales Manager', N'Mr.', '19700101', '20110101',N'Some Address 18', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386) 113322', 2);INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Robertson', N'Test 2', N'Sales Representative', N'Mr.', '19850101','20110601', N'Some Address 22', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386)553344', 10);COMMIT TRAN;6. Highlight the written T-<strong>SQL</strong> code and click Execute.7. In the query pane, type the following query after the previous T-<strong>SQL</strong> code:SELECT empid, lastname, firstnameFROM HR.EmployeesORDER BY empid DESC;8. Highlight the written query and click Execute. Task 2: Delete the previously inserted rows from the HR.Employees table1. Highlight the following T-<strong>SQL</strong> code under the task 2 description:DELETE HR.EmployeesWHERE empid IN (10, 11);DBCC CHECKIDENT ('HR.Employees', RESEED, 9);2. Click Execute.


L19-156 Module 19: Implementing Transactions Task 3: Open a transaction and use the ROLLBACK statement1. Modify the T-<strong>SQL</strong> code under the task 3 description by adding the BEGIN TRAN statement. YourT-<strong>SQL</strong> code should look like this:BEGIN TRAN;INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Johnson', N'Test 1', N'Sales Manager', N'Mr.', '19700101', '20110101',N'Some Address 18', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386) 113322', 2);INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Robertson', N'Test 2', N'Sales Representative', N'Mr.', '19850101','20110601', N'Some Address 22', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386)553344', 10);2. Highlight the written T-<strong>SQL</strong> code and click Execute.3. In the query pane, type the following query after the previous T-<strong>SQL</strong> code:SELECT empid, lastname, firstnameFROM HR.EmployeesORDER BY empid DESC;4. Highlight the written query and click Execute.5. In the query pane, type the following statement after the SELECT statement:ROLLBACK TRAN;6. Highlight the written statement and click Execute.7. Again highlight the SELECT statement shown in step 3 and click Execute. Task 4: Clear the modifications against the HR.Employees table1. Highlight the following T-<strong>SQL</strong> code after the task 4 description:DBCC CHECKIDENT ('HR.Employees', RESEED, 9);2. Click Execute.


Lab: Implementing Transactions L19-157Exercise 2: Adding Error Handling to a CATCH Block Task 1: Observe the provided T-<strong>SQL</strong> code1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. Highlight only the following SELECT statement under the task 1 description:SELECT empid, lastname, firstnameFROM HR.EmployeesORDER BY empid DESC;4. Click Execute.5. In the provided T-<strong>SQL</strong> code, highlight the code between the BEGIN TRAN and COMMIT TRANstatements. Your highlighted T-<strong>SQL</strong> code should look like this:BEGIN TRAN;INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Johnson', N'Test 1', N'Sales Manager', N'Mr.', '19700101', '20110101',N'Some Address 18', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386) 113322', 2);INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Robertson', N'Test 2', N'Sales Representative', N'Mr.', '19850101','10110601', N'Some Address 22', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386)553344', 10);COMMIT TRAN;6. Click Execute. Notice that you get a conversion error in the second INSERT statement.7. Again highlight the SELECT statement shown in step 3 and click Execute. Task 2: Delete the previously inserted row in the HR.Employees table1. Highlight the following T-<strong>SQL</strong> code under the task 2 description:DELETE HR.EmployeesWHERE empid IN (10, 11);DBCC CHECKIDENT ('HR.Employees', RESEED, 9);2. Click Execute.


L19-158 Module 19: Implementing Transactions Task 3: Abort both INSERT statements if an error occurs1. Modify the T-<strong>SQL</strong> code under the task 3 description to look like this:BEGIN TRYBEGIN TRAN;INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Johnson', N'Test 1', N'Sales Manager', N'Mr.', '19700101', '20110101',N'Some Address 18', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386) 113322', 2);INSERT INTO HR.Employees (lastname, firstname, title, titleofcourtesy, birthdate,hiredate, address, city, region, postalcode, country, phone, mgrid)VALUES (N'Robertson', N'Test 2', N'Sales Representative', N'Mr.', '19850101','10110601', N'Some Address 22', N'Ljubljana', NULL, N'1000', N'Slovenia', N'(386)553344', 10);PRINT 'Commit the transaction...';COMMIT TRAN;END TRYBEGIN CATCHIF @@TRANCOUNT > 0BEGINPRINT 'Rollback the transaction...';ROLLBACK TRAN;ENDEND CATCH;2. Highlight the modified T-<strong>SQL</strong> code and click Execute.3. In the query pane, type the following query after the modified T-<strong>SQL</strong> code:SELECT empid, lastname, firstnameFROM HR.EmployeesORDER BY empid DESC;4. Highlight the written query and click Execute. Task 4: Clear the modifications against the HR.Employees table1. Highlight the following T-<strong>SQL</strong> code under the task 4 description:DBCC CHECKIDENT ('HR.Employees', RESEED, 9);2. Click Execute.


L20-159Module 20: Improving Query PerformanceLab: Improving Query PerformanceLab SetupFor this lab, you will use the available virtual machine environment. Before you begin the lab, you mustcomplete the following steps:1. On the host computer, click Start, point to Administrative Tools, and click Hyper-V Manager.2. Maximize the Hyper-V Manager window.3. If the virtual machine 10774A-MIA-DC1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-DC1 and click Start.• Right-click 10774A-MIA-DC1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.4. If the virtual machine 10774A-MIA-<strong>SQL</strong>1 is not started:• In the Virtual Machines list, right-click 10774A-MIA-<strong>SQL</strong>1 and click Start.• Right-click 10774A-MIA-<strong>SQL</strong>1 and click Connect.• In the Virtual Machine Connection window, wait until the “Press CTRL+ALT+DELETE to log on”message appears, and then close the Virtual Machine Connection window.5. In the Virtual Machine Connection window, click the Revert toolbar icon.6. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action tocomplete.7. If you are not already logged on:• In the Virtual Machine Connection window, click the Ctrl-Alt-Delete menu item on theAction menu.• Click Switch User, and then click Other User.• Log on using the following credentials:• User name: AdventureWorks\Administrator• Password: Pa$$w0rd8. In the Virtual Machine Connection window, click Full Screen Mode on the View menu.9. If the Server Manager window appears, check the Do not show me this console at logon checkbox and close the Server Manager window.10. On the virtual machine, click Start, click All Programs, click Microsoft <strong>SQL</strong> Server <strong>2012</strong>, and click<strong>SQL</strong> Server Management Studio.


L20-160 Module 20: Improving Query Performance11. In the Connect to Server window, depending on the type of deployment (ask your instructor for acurrent list of Microsoft <strong>SQL</strong> Azure enabled labs):• For an on-premises Microsoft <strong>SQL</strong> Server instance, type Proseware in the Server name text box.• For Windows Azure, type in the Server Name text box.12. Click the Options button. Under Connection Properties, select in the Connect todatabase list. Choose Yes when prompted for the connection to the database. Under UserDatabases, select the T<strong>SQL</strong><strong>2012</strong> database.13. Choose the authentication type, depending on the type of deployment:• For an on-premises Microsoft <strong>SQL</strong> Server instance, click the Login tab, select WindowsAuthentication in the Authentication list, and click Connect.• For Windows Azure, click the Login tab, select <strong>SQL</strong> Server Authentication in theAuthentication list, type your login name in the Login text box and the password in thePassword text box, and click Connect.


Lab: Improving Query Performance L20-161Exercise 1: Viewing Query Execution Plans Task 1: Create and populate the sample table Sales.TempOrders1. In the File menu, click Open and click Project/Solution.2. In the Open Project window, open the projectF:\10774A_Labs\10774A_20_PRJ\10774A_20_PRJ.ssmssln.3. In Solution Explorer, double-click the query 51 - Lab Exercise 1.sql. (If Solution Explorer is not visible,select Solution Explorer on the View menu or press Ctrl+Alt+L on the keyboard.)4. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute on thetoolbar (or press F5 on the keyboard).5. In the query pane, highlight the T-<strong>SQL</strong> code after the task 1 description and click Execute. Task 2: Show estimated and actual execution plans1. In the query pane, type the following query after the task 2 description:SELECT orderid, custid, orderdateFROM Sales.TempOrders;2. Highlight the written query and click Display Estimated Execution Plan.3. In the Results pane, click the Execution plan tab. Hover your mouse pointer over the Table Scanoperator and look at the properties displayed in the yellow tooltip box.4. Position your mouse pointer over the arrow between the SELECT operator and the Table Scanoperator in the execution plan. You should see three properties: Estimated Number of Rows,Estimated Data Size, and Estimated Row Size.5. Right-click the SELECT operator and click Properties in the context menu.6. On the toolbar, click Include Actual Execution Plan.7. Highlight the written query and click Execute.8. In the Results pane, click the Execution plan tab and observe the actual execution plan. Task 3: Analyze the execution plan of another SELECT statement1. Highlight the previous query in task 2. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 3 description. On the toolbar, click Edit andthen Paste.3. In the query pane, alter the copied query to look like this:SELECT TOP (1) orderid, custid, orderdateFROM Sales.TempOrders;4. Highlight the altered query and click Display Estimated Execution Plan.5. Compare this task’s execution plan with the execution plan in the previous task. Which operator isnew? The TOP operator is new.


L20-162 Module 20: Improving Query Performance Task 4: Graphically compare two execution plans1. Highlight the query in task 2. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 4 description. On the toolbar, click Edit andthen Paste.3. Highlight the query in task 3. On the toolbar, click Edit and then Copy.4. In the query window, click the line after the copied SELECT statement. On the toolbar, click Edit andthen Paste.5. Highlight both SELECT statements and click Display Estimated Execution Plan.6. In the toolbar, click Include Actual Execution Plan.7. Highlight both SELECT statements and click Execute.


Lab: Improving Query Performance L20-163Exercise 2: Viewing Index Usage and Using SET STATISTICS Statements Task 1: Create a clustered index and write a SELECT statement1. In Solution Explorer, double-click the query 61 - Lab Exercise 2.sql.2. When the query window opens, highlight the statement USE T<strong>SQL</strong><strong>2012</strong>; and click Execute.3. Highlight the provided T-<strong>SQL</strong> code after the task 1 description and click Execute.4. In the query pane, type the following query after the provided T-<strong>SQL</strong> code:SELECT orderid, custid, orderdateFROM Sales.TempOrdersWHERE YEAR(orderdate) = 2007 AND MONTH(orderdate) = 6;5. Highlight the written query and click Execute.6. Highlight the written query and click Display Estimated Execution Plan. Task 2: Enable I/O statistics to observe the number of needed reads1. In the query pane, type the following T-<strong>SQL</strong> statement after the task 2 description:SET STATISTICS IO ON;2. Highlight the written statement and click Execute.3. Highlight the query in task 1. On the toolbar, click Edit and then Copy.4. In the query window, click the line after the written T-<strong>SQL</strong> statement. On the toolbar, click Edit andthen Paste.5. Highlight the copied SELECT statement and click Execute.6. In the Results pane, click the Messages tab and observe the number of logical reads. Task 3: Modify the SELECT statement to use a search argument in the WHERE clause1. Highlight the query in task 1. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 3 description. On the toolbar, click Edit andthen Paste.3. Modify the SELECT statement to look like this:SELECT orderid, custid, orderdateFROM Sales.TempOrdersWHERE orderdate >= '20070601' AND orderdate < '20070701';4. Highlight the modified query and click Execute.5. Highlight the modified query and click Display Estimated Execution Plan.


L20-164 Module 20: Improving Query Performance Task 4: Compare both SELECT statements1. Highlight the query in task 1. On the toolbar, click Edit and then Copy.2. In the query window, click the line after the task 4 description. On the toolbar, click Edit andthen Paste.3. Highlight the query in task 3. On the toolbar, click Edit and then Copy.4. In the query window, click the line after the copied SELECT statement. On the toolbar, click Edit andthen Paste.5. Highlight both SELECT statements and click Execute.6. Highlight both SELECT statements and click Display Estimated Execution Plan.7. Compare the execution plans for the two queries. Why is the SELECT statement from task 3 so muchfaster? This SELECT statement efficiently uses the created clustered index and does a clustered indexseek operation. The SELECT statement from task 1 does a clustered index scan (i.e., table scan). Task 5: Remove the created table and disable IO statistics• Highlight the provided T-<strong>SQL</strong> code and click Execute.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!