[00:00:00] The Ultimate T-SQL and Microsoft SQL Server Bootcamp
[00:00:05] Trevoir Williams Hi everyone, I’m Trevoir Williams. I’ve been designing database systems for over a decade now, [00:00:10]and I’m here to ensure that you learn Transact-SQL, or T-SQL for short, [00:00:15]which is the premier language used by Microsoft for their SQL Server.
[00:00:20] Emar Morrison Hi there, I’m Emar Morrison, a SQL Server Specialist [00:00:25]with almost a decade of experience managing databases and analyzing data using T-SQL. [00:00:30]Together, we’ll explore the world of T-SQL [00:00:35]and its importance in data manipulation and management.
Trevoir Williams Now, why is this a good course? [00:00:40]T-SQL, or Transact-SQL, is Microsoft’s adaptation of SQL, [00:00:45]meaning it is used in Microsoft SQL Server, which is one of the most popular database management systems in the industry.
[00:00:50] Emar Morrison Our course will be much more than theoretical knowledge. [00:00:55]We have designed it to be highly interactive with plenty of hands-on exercises [00:01:00]and questions to test your understanding. [00:01:05]Plus, we have included a bunch of practical scenarios where T-SQL shines, so that you can see it work in real-world scenarios way beyond the textbooks.
[00:01:10] Trevoir Williams Having a thorough understanding of T-SQL [00:01:15]is important for anybody who is serious about advancing their career in data management, data analysis, [00:01:20]or related fields.
Emar Morrison Finally, you’ll benefit from our course [00:01:25]because we’ll be there with you every step of the way, guiding you, answering your queries, [00:01:30]and ensuring you understand the T-SQL language thoroughly. You’ll also be a part of a growing community of learners, [00:01:35]allowing you to network, collaborate, [00:01:40]and engage with like-minded individuals on a journey just like you.
[00:01:45] Trevoir Williams Now, why should you enroll in this course? Our world is heavily data-driven, and having a good understanding of Transact-SQL [00:01:50]can open up many doors for you. Whether you’re a software developer, [00:01:55]data analyst, or just a hobbyist, knowing how to navigate, manipulate, [00:02:00]and manage data using SQL will greatly enhance your capabilities, [00:02:05]and it is a vital skill for this day and age. So join us in exploring this powerful language, [00:02:10]and we’re excited to meet you, and we can’t wait to have you along for this journey.
[00:02:15][music]
[00:02:20] Emar Morrison Before we get into working with SQL Server, it’s probably a good idea [00:02:25]to talk about what SQL Server actually is. SQL Server is a relational database management system, [00:02:30]or RDBMS. [00:02:35]It uses a database engine to handle all the tasks associated with storing [00:02:40]and retrieving data from a database, creating new databases and their components, [00:02:45]such as tables, views, and store procedures. [00:02:50]Because of its nature as a server, it’s typically always running on a computer [00:02:55]that it’s installed on, ready to respond to requests, [00:03:00]to perform required tasks, and then send information back out to the user [00:03:05]that requested it. In most production environments, [00:03:10]SQL Server would be installed on a dedicated machine, and users would log in remotely from their own computers [00:03:15]to access the databases that they want to use. [00:03:20]However, SQL Server can be installed on a local computer. [00:03:25]This approach simplifies the connections and is the method [00:03:30]we’re going to be using for this course. A SQL Server installation [00:03:35]is called an instance, and a single instance can hold many individual databases [00:03:40]under its umbrella. You might have one database [00:03:45]to track your product offerings, and a separate database to contain employee records, [00:03:50]all on the same instance. You can install up to 50 instances [00:03:55]on a single server. However, this is not recommended. [00:04:00]At the heart of SQL Server is something called SQL or SQL. [00:04:05]SQL stands for Structured Query Language. [00:04:10]It is the standardized way database administrators, developers, [00:04:15]data analysts, and engineers interact with most of the database systems [00:04:20]on the market today. In the next lecture coming up, we’ll be taking a deeper look at what is SQL. [00:04:25]As you’d have learned in the previous lecture, [00:04:30]SQL stands for Structured Query Language, which is a language [00:04:35]for manipulating and defining data in databases. [00:04:40]It first came into use in 1974 and became the standard in 1986. [00:04:45]SQL gives us a standardized way of asking a specific question of a database, [00:04:50]or for making structured query [00:04:55]that a database knows how to respond to. So what SQL does is that it pretty much gives us a way for writing questions a database [00:05:00]can understand. [00:05:05]Databases aren’t clever like us, and they can’t figure out the meaning of questions [00:05:10]the way human can. If you were supposed to ask a question like, [00:05:15]how many goals were scored by France in the 2020 World Cup Finals, you, a person, [00:05:20]could pretty easily understand what I’m asking you. [00:05:25]But ask the database the same question, you’ll probably get whatever the computer equivalent of a blank stare is. [00:05:30]The database doesn’t know how to understand the meaning [00:05:35]or the intention of my question. [00:05:40]To make questions like this approachable for a database, [00:05:45]we need to break them down into a series of smaller questions that are structured in a way that the database software can understand. [00:05:50]Because it’s such a powerful way of thinking about data, [00:05:55]SQL has been adopted into many database products. [00:06:00]In this course, we’ll cover the basic and widely supported parts of SQL, [00:06:05]whether you’re working with Microsoft Transact-SQL [00:06:10]or T-SQL, MySQL, Postgres, or even SQLite and other databases. [00:06:15]The way we say the name may be a bit confusing sometimes. [00:06:20]Sometimes I use SQL, sometimes I use SQL, it all depends. [00:06:25]So before we start building out SQL statements, [00:06:30]we need to understand what the basic parts of a statement are. [00:06:35]Overall, something you’ll write in SQL gets an answer from the database or make a change to it is called a statement. [00:06:40]SQL is generally white space independent, meaning, [00:06:45]if you want to add some white space or lines between clause [00:06:50]or expression to make your statement easier to read, you can do so. [00:06:55]In this course, we’ll break statements across various lines [00:07:00]in order to make them more clearly readable. I find it really helpful [00:07:05]when I’m putting together a more complicated statement so I can see what’s going on. [00:07:10]A statement is made up of clauses. Don’t worry too much about what this actual statement does right now. [00:07:15]We’ll see how to make clauses and statements later on in this course. [00:07:20]Clauses are the basic components of statements, [00:07:25]the smaller building blocks that make up the whole thing. [00:07:30]These clauses are constructed out of various elements including keywords, [00:07:35]which are special or reserved words, which tell the database to take some action. [00:07:40]Fieldnames, which let us refer to fields or columns of data whose value [00:07:45]we want to use. Table names, which tell the database which table to use, [00:07:50]and predicates, which we use to specify the information [00:07:55]or condition we’re looking for. Predicates include a value [00:08:00]or condition called an expression. [00:08:05]A clause can be a statement if you’re writing a really basic one. There are also operators. [00:08:10]As we’ll see later on, which let us compare equality or ranges of data [00:08:15]or treat information in other ways. These keywords and operators [00:08:20]are customarily written as uppercase, though usually they don’t have to be. [00:08:25]But it helps distinguish the SQL from your expression [00:08:30]and fieldnames at a glance. At the end of a statement, we put a semicolon. [00:08:35]This simply tells the database the statement has ended. [00:08:40]While the semicolon is often required in order for the database software to accept the statement as valid, [00:08:45]not all database software or database engine enforces this. [00:08:50]So it’s a good idea to get into the habit of using semicolon to end a statement [00:08:55]as you’d use a period to end a sentence. [00:09:00]Any SQL we write that takes some kind of action is a statement. And sometimes you’ll see a statement using the select word, [00:09:05]often called a query. A query suggests that we are asking a question [00:09:10]and when we are using the select keyword, that’s generally the case. [00:09:15]SQL statements can also be used to add, modify, [00:09:20]or delete data in a database, or even create, modify, and remove tables. [00:09:25]When we use SQL to work with data in existing tables, [00:09:30]that SQL being used as a DML, or Data Manipulation Language. [00:09:35]These operations where we change data are generally called CRUD, [00:09:40]shortened for create, read, update, and delete. [00:09:45]CRUD is a common short end for referring to modifying data in a database. [00:09:50]When we write SQL to make changes to the structure of tables themselves, [00:09:55]or change a database, that SQL being used as DDL, [00:10:00]or Data Definition Language. In this course, we’ll focus on all the CRUD operations, [00:10:05]as at the end of this course, we want you to be a pro in SQL, [00:10:10]to help take your career to the next level, whether it be data analytics [00:10:15]or database development. Why learn SQL? [00:10:20]Simply because SQL skills are among the most in demand IT skills, [00:10:25]and they have been for several years. In today’s digital world, [00:10:30]knowing at least one computer language is mandatory for good career opportunities. [00:10:35]That’s the ultimate reason why you should learn SQL, [00:10:40]an easy and highly universal language. Now, if you aren’t sure where to start, [00:10:45]you have selected the right course. Learning SQL is beneficial for several reasons. [00:10:50]First, database management. [00:10:55]SQL is the standard language for managing and querying relational databases. [00:11:00]It allows you to interact with the databases, retrieve data, modify data, [00:11:05]create and manage structures, and perform various administrative tasks. [00:11:10]Secondly, data analysis. SQL is a powerful tool for data analysis. [00:11:15]It enables you to extract, filter, and manipulate large datasets efficiently. [00:11:20]You can write complex queries to join multiple tables, [00:11:25]aggregate data, calculate statistics, and generate insightful reports. [00:11:30]Thirdly, data integration. [00:11:35]Many applications and systems rely on database to store and retrieve data. [00:11:40]By learning SQL, you can integrate and communicate with these databases effectively. [00:11:45]It enables you to extract data from different data sources, transform it, [00:11:50]and load it into your application [00:11:55]or reporting tool. Fourthly, career opportunities. [00:12:00]SQL skills are highly sought after in the job market, especially for roles in data analysis, [00:12:05]data administration, and software development. [00:12:10]Proficiency in SQL can enhance your employability and open up a wide range of career opportunities. [00:12:15]And last but not least, efficiency and productivity. [00:12:20]With SQL, you can perform complex data operations with minimal code. [00:12:25]It allows you to write concise and optimized queries, [00:12:30]which leads to improved efficiency and productivity in data-related tasks. [00:12:35]Overall, learning SQL empowers you to work with databases, [00:12:40]analyze data, make data-driven decisions, [00:12:45]and pursue a successful career in various data field, in various fields involving data management [00:12:50]and data analysis. [00:12:55]Databases and Structured Query Language were nearly synonymous over three decades. [00:13:00]SQL was required for everyone who wished to obtain data from a database. [00:13:05]There was no SQL alternative, and anyone who wishes to maintain databases [00:13:10]or work as a database administrator had to learn the intricacies of the system. [00:13:15]However, there are several alternatives available today, [00:13:20]and I’ll be naming a few of them. So the first one is PRQL, [00:13:25]pronounced Prequel. This stands for Pipelined Relational Query Language. [00:13:30]This language’s data querying systems [00:13:35]are made up of a series of 10 instructions. When all the instructions are combined, [00:13:40]you’ll obtain the results that only contains only the information that you need. [00:13:45]Another alternative is GraphQL. The name is a little misleading [00:13:50]because it isn’t truly a language built to make use of all the benefits of graph databases. [00:13:55]GraphQL is more of an elegant shortcut for accessing data [00:14:00]stored in layered JSON-like format. [00:14:05]The query is just a description of how the results should appear. [00:14:10]The third one is Malloy. The problem with SQL, according to the creators of Malloy, [00:14:15]lies in the synthetic details, expressing even the simplest of query [00:14:20]takes time because the language is verbose and is full of hidden performance traps. [00:14:25]So they created a modern programming language with natural defaults, [00:14:30]simpler syntax that can be used to compile SQL. [00:14:35]So no one needs to retrofit a stock database. The last one I’ll be talking about is NIQL, [00:14:40]pronounced nickel. This is designed to make it easier for SQL alternatives [00:14:45]to work with JSON objects that might be stored in Couchbase. [00:14:50]A basic query has several sections specified by the keywords select, [00:14:55]from, and where just like SQL. However, this is just a few of them. [00:15:00]And if you want to learn more, I’ll leave a link in the resource section [00:15:05]so you can do some additional reading.
[00:15:10] Trevoir Williams All right, guys, in this lesson we’re going to be looking at setting up SQL Server on our machine. [00:15:15]Now, finding SQL Servers install files is as easy as a Google search. [00:15:20]I literally just googled SQL Server and the very first search result is good enough for me. [00:15:25]You’ll see that you have different tools or different years. So based on your machine you may want to choose a version [00:15:30]that is in keeping with the specifications of your machine. [00:15:35]But at this point I’m going to install the latest version which is 2019. [00:15:40]So just by clicking that link it will bring me to the download for SQL Server 2019. [00:15:45]And then I have a few options. I can, one, install on Windows, Linux or Docker containers. [00:15:50]There you go. You have the different installation, um, instructions [00:15:55]and you have other things that you can look at. [00:16:00]But we really want to focus on the free versions which are the Developer version [00:16:05]and the Express version. So Express is a free edition that is ideal for development purposes [00:16:10]and for very small applications on servers or desktops whereas developer is full featured. [00:16:15]So you actually have different editions like Professional and Enterprise. [00:16:20]And you see here that you have Azure and on-premises. [00:16:25]And it varies based on it. But then based on the version that you select when it comes to on-premises [00:16:30]you realize that you have an evaluation for the Enterprise edition [00:16:35]or the…
[00:16:40][sil.]
[00:16:45] Trevoir Williams Professional edition, etc, right? So you can look through them [00:16:50]but at the end of the day we want to go with the one that is free for development and educational purposes. [00:16:55]So, in this course I will be using Express. [00:17:00]That being said everything I’m about to do in Express is also available in Developer. [00:17:05]However, Developer has a lot more that is available. [00:17:10]But for learning purposes and just because I don’t know where everybody’s machine [00:17:15]capabilities are we can start off with Express. So when you click download now, [00:17:20]you will get an installer file which you can launch immediately [00:17:25]and you might get prompted by your machine like I just did. But this is what that installation looks like. [00:17:30]So you have basic, custom, and download. Now, I’m using Express because the setup is easy [00:17:35]and it’s very easy to maneuver with. So you can go ahead, hit basic, accept, [00:17:40]choose where you want it to go if not the default location. [00:17:45]Make sure you have enough space relative to the download size. [00:17:50]And then you can hit install. Now, when that installation is done, you’re going to see some pertinent information being presented to you. [00:17:55]The first thing that stands out is the instance name. You’re going to see SQL Express. [00:18:00]I have SQL Express 01. The only reason for this difference is that [00:18:05]I already have SQL Express installed on my machine. [00:18:10]So in other words I have one version of SQL Express installed and I’m installing another one and for every time I would install [00:18:15]I would get a different instance name. An instance is like a container [00:18:20]that has all of the databases in it. So based on the instance that you connect to, right? [00:18:25]Then you would be storing your databases on that instance. [00:18:30]You don’t need to install multiple. I’m just explaining [00:18:35]why I have a different name from you. If you have gotten to this page successfully, [00:18:40]then you have successfully installed an SQL Express instance on your machine. [00:18:45]No need to worry. They also let you know that the administrators [00:18:50]would be your machine name slash your username and the engine [00:18:55]and everything and connection strings and some other bits of data that you don’t necessarily have to worry about right now. [00:19:00]The next major step would be to install the SSMS which is the SQL Server Management System. [00:19:05]So this is the user interface that will allow you to administrate your instance, [00:19:10]set up your databases, your tables and everything. [00:19:15]So you can go ahead and hit that which will launch a new window [00:19:20]in whatever browser is your default browser and then you can just download [00:19:25]that version that is available to you. So when you finish and you install that [00:19:30]and the installation of that is fairly simple and straightforward you’ll get this prompt [00:19:35]and you just click install and next, next, next to it. So I’m not going to walk you through step by step. [00:19:40]It’s fairly straightforward and you should not encounter any major issues. [00:19:45]Now, when all of that is done you would have completely and successfully installed SQL Server on your machine. [00:19:50]Whether this is your personal laptop or a server laptop, [00:19:55]it is now capable of hosting and administrating databases. [00:20:00]So stick around because in the next lesson we’re going to look at how to connect to our database [00:20:05]and start interacting with data. [00:20:10]Now, as it stands Microsoft SQL Server is almost exclusively only usable on Windows machines. [00:20:15]So the previous installation steps [00:20:20]may not have gone down well if you are not using a Windows machine. [00:20:25]Now, if you’re using Mac or Linux, don’t worry there is still a solution for you. [00:20:30]Solution number one would be that you can use a virtual machine. [00:20:35]So you can use VMware or some other tool that supports virtualization [00:20:40]and you can spin up a virtual machine that has a Windows OS and then use that. [00:20:45]Now, that can be resource intensive and I’m not going to put you through all of that just to use the one software. [00:20:50]So the alternative to a virtualized environment for Windows [00:20:55]would be to use Docker which is what I have up on my screen. Docker. [00:21:00]You can easily get here by going to docker.com. Docker is a very fast application [00:21:05]that allows us to use what we call containers instead of a whole virtualized environment. [00:21:10]So what we can do is use Docker to simulate the environment needed [00:21:15]and only the environment needed for a particular application to run [00:21:20]without needing the entire operating system. [00:21:25]So what we’re going to do is use Docker to simulate an environment for SQL Server [00:21:30]and then we’ll be able to connect to the SQL Server just the same even if you’re not using a Windows machine. [00:21:35]Now, the first thing you’ll notice is that it is available for every operating system pretty much, right? [00:21:40]So if you’re using Windows, you can still use Docker. [00:21:45]If you have an Apple device or a Linux based device or Intel chip based device, [00:21:50]you can just the same way install Docker. [00:21:55]So go ahead. Download and install it. I already have it installed on my Windows machine [00:22:00]but once you have installed it, what you will get is access to the Docker command line commands. [00:22:05]So once you have it installed, you know, hit pause, [00:22:10]let it install, and then you can continue. I would encourage you to launch your terminal. [00:22:15]So once again, I’m using a Windows machine but your terminal on Linux [00:22:20]or Mac OS X would look very similar to this. [00:22:25]And you can simply run the command Docker just to make sure that it’s installed and if you see something looking like this, [00:22:30]then you know you have access to the Docker CLI commands. All right? [00:22:35]So what we want to do at this point is run a command that’s called Docker pull. [00:22:40]Let me zoom in a bit so it’s easier to read. So we’re going to do Docker pull. [00:22:45]So Docker pull [00:22:50]and then we’re going to pull this what we call image. [00:22:55]So Docker has predefined files that outline the environment that is needed [00:23:00]for a particular application and these are called images. [00:23:05]So the image that we want is the Microsoft MS SQL server image. [00:23:10]So we’re going to do a Docker pull against that image. So you can hit pause, [00:23:15]make sure you type it in just the way I have it and when you press enter, it is going to go ahead say, okay, [00:23:20]I’m getting latest and then you’re going to see it downloading. So I already pulled that image, so I already have it on my machine, [00:23:25]but you’re going to see it say pulling and then it’s going to start showing you metrics of it downloading [00:23:30]and it would actually look something more like this. [00:23:35]So this is a screenshot I took earlier from when I was downloading it and you’re going to see [00:23:40]that it’s going to spawn up these a bunch of lines looking similar to this [00:23:45]and you’re going to have these downloading tags. So once that is completed, [00:23:50]the next step is to actually run it. So to run it, you need this command. [00:23:55]So we’re going to say Docker run and then hyphen e and then we’ll do the EULA accept. [00:24:00]So what happens is that SQL Server usually has one of those documents [00:24:05]that you need to accept the terms and conditions. So we’re just putting it in a parameter that, yes, we accept the terms and conditions [00:24:10]and then another one that says SA password. [00:24:15]So if you looked at the installation process when we’re using Windows, [00:24:20]um, we can use Windows authentication to connect to the database, right? [00:24:25]So all we need is the machine name and we can use the Windows user, [00:24:30]the current Windows user, Windows authentication and just connect. [00:24:35]Now, because this is Docker and it’s a container, there’s no Windows or there’s no Mac or there’s no Linux authentication. [00:24:40]So it’s not really that you can just connect using the default user on your computer. [00:24:45]So this step is applicable whether you’re using Windows, Mac, Linux, etc. [00:24:50]So what we need to do is specify an SA password. So SA is the default user [00:24:55]which means system admin or system administrator. [00:25:00]Every time we install a database engine for Microsoft SQL Server, you get this SA user. [00:25:05]So we’re going to set up this SA password and you can put in any password you wish, right? [00:25:10]I’m just putting in a strong password here and this is really a password [00:25:15]that you might see in other demos that you might watch anywhere on the internet. [00:25:20]So this password is not necessarily unique to me or to this exercise. You can put in any password value that you feel comfortable [00:25:25]with and you know you will remember. So I’m just putting [00:25:30]the word strong password of course with special characters, numerals, [00:25:35]and a couple capital letters. Then, we specify the port. [00:25:40]So the port here at the front is the port that we want to go through and the port [00:25:45]on the other end of the colon is the port that it will map to. [00:25:50]So what this means is SQL Server by default broadcasts from port 1433. [00:25:55]That’s the default port. [00:26:00]So without doing anything specifying any port or anything we’ll always go through 1433 once we’re connecting. [00:26:05]However, Docker is running in its own specialized environment. [00:26:10]So we need to map. So this is the default port and then this is the port from our machine that we want to tunnel through to get to this port. [00:26:15]So you could actually just leave that as 1433:1433. [00:26:20]So if you don’t have SQL Server installed already and you’re running Mac [00:26:25]and Linux then 1433:1433 is fine. You don’t have to do anything extra. [00:26:30]You can just connect. However, because I’m using a Windows machine [00:26:35]I had to change my port because 1433 is already occupied by my native SQL Server installation. [00:26:40]So I’m just showing you that you can do 1433:1433 [00:26:45]by default or you can put in your own specific port if you so desire. [00:26:50]Then the next and final thing is we say hyphen d [00:26:55]and then we specify the image that we want to run. [00:27:00]So basically we’re saying Docker, run this image and make sure that all of these parameters in between are configured. [00:27:05]That’s essentially what we just did. So when you press enter [00:27:10]and you allow this one to run what it will do is launch that image [00:27:15]inside of the Docker UI. So in the Docker UI, [00:27:20]you’re going to see something looking like this. It’s going to appear under containers [00:27:25]and you can see here that I have several containers, right? I even have another SQL container [00:27:30]that I installed from earlier and here’s the new one from my just running that command. [00:27:35]So it created a brand new container for Microsoft SQL Server [00:27:40]and it is currently running and it’s been running for 30 seconds [00:27:45]and the port it uses is 1400 which if you didn’t change that and you use the default 1433 [00:27:50]would be 1433. You can always stop and start the containers. [00:27:55]You can also delete and you can also watch what is happening, [00:28:00]so you can open it in the terminal and you can interact with it here. [00:28:05]You can also inspect to see the health of it and look at some of the configurations, right? [00:28:10]So these are some of the environment variables that we had set up or the parameters that we passed in. [00:28:15]You can also look at the logs. So you see here that it seems to have started up successfully. [00:28:20]So after I’ve… I’ve confirmed all of these things now, [00:28:25]I would want to connect. Now, for Windows we can use the Microsoft SQL Server Management Studio. [00:28:30]However, Management Studio [00:28:35]is not necessarily available on Linux and Mac. So the alternative here would be to get the Azure Data Studio. [00:28:40]You can simply do a Google search and you can go ahead [00:28:45]and follow the Microsoft documentation to the Azure Data Studio. [00:28:50]So Azure Data Studio is a cross-platform database tool [00:28:55]for professionals and it can work on Windows, macOS and Linux. [00:29:00]So you can go ahead and install the appropriate version for yourself and, [00:29:05]of course, you can look at any warnings just to make sure that you are [00:29:10]in a compatible state. All right? [00:29:15]So the thing is that the Data Studio [00:29:20]can do most things that the Management Studio can do [00:29:25]especially within the confines of this course where we’re learning about database development and queries and such. [00:29:30]The experience however will be slightly different. [00:29:35]So certain things won’t be at the same place and might not be called the same thing. However, to connect, let me just show you how we connect. [00:29:40]So you can see I’ve connected to quite a few apps over the time or databases rather. [00:29:45]But here, I’m going to connect Microsoft SQL Server [00:29:50]and then the server here is going to be localhost comma the port that you specified. [00:29:55]So in my case, I specified 1400 on my port. [00:30:00]You might have specified 1400 as well or whatever it is that you specified [00:30:05]when we said the container should run. And if you don’t remember, you can just go back over and look. [00:30:10]So you specify that port and then not Windows authentication, [00:30:15]but SQL login and our username is SA and our password [00:30:20]is the password that we typed. And once again, [00:30:25]if you don’t remember what that password is, you can always go to the container [00:30:30]and then click inspect and I can just copy this value. [00:30:35]And then paste it and then for future, you just remember password. [00:30:40]Then we can connect. And then this is a sign of a successful connection. [00:30:45]You see here that OS version. So I am still on my Windows machine, [00:30:50]but the OS version that it has detected is Ubuntu. [00:30:55]So that is what the container is doing. It is running in a Linux environment, [00:31:00]but it’s simulating the environment, exact environment needed for SQL Server to be able to run. [00:31:05]So if I expand databases, you’ll see it’s empty. [00:31:10]And then basically everything that we can do from the Management Studio, [00:31:15]we can do from here. One thing that you may notice, though, [00:31:20]is that some of the tooling is limited. So in the Management Studio, [00:31:25]I can easily or more easily right click and say do certain things [00:31:30]like create a new database and so on. In the Management… [00:31:35]in the Data Studio, however, it will probably have to be scripted. [00:31:40]So it’s something that you’d have to control and create a new script file [00:31:45]and then to create a new database, you’d have to say create database and then state the name. [00:31:50]Let’s say TestDb and then F5 and then it gets run. [00:31:55]So then you can refresh the list of databases and then you’ll see TestDb, right? [00:32:00]But in this course, we’re going to be looking at how to do both scripts [00:32:05]and use the graphical user interface in the Management Studio. [00:32:10]So you should be able to follow along quite fine. And at any rate, [00:32:15]if you run into difficulties, feel free to reach out. [00:32:20]All right guys, in this lesson, I want to take some time to get familiar with the SQL Server Management Studio [00:32:25]or SSMS. It is a very powerful tool [00:32:30]and it helps when we know some keyboard shortcuts, some, you know, [00:32:35]ways to navigate around it and get comfortable. So to open it, um, [00:32:40]if you had closed it since you did the installation, you can always click in your search bar [00:32:45]and go to SQL Server. Of course, if you’re not using a Windows computer, then you would launch that Docker container [00:32:50]that you would have installed. But once you have launched it, [00:32:55]it will take some time to load. And once it’s up, it will prompt you to connect to the server. [00:33:00]Now, some things to note here. Our server type is database engine. [00:33:05]The server name refers to the name [00:33:10]of the instance that you are connecting to. [00:33:15]So when you would have installed SQL Server Express, then your instance would be localhost slash SQL Express. [00:33:20]All right? [00:33:25]Just so we’re clear. So to get in, if you installed SQL Express, [00:33:30]you would say localhost, then the backslash and then SQL Express. [00:33:35]Another way you could write this would be your machine name. [00:33:40]So here my machine name is SQL. So I could have easily said SQL backslash SQL Express. [00:33:45]I named my machine simply enough for the purpose of this course. [00:33:50]But you might not have a simple enough machine name. So you could say, [00:33:55]well, your machine name, you could say localhost. But the easiest one is the full stop. [00:34:00]So you can say full stop, then the same backslash SQL Express. [00:34:05]Any of those will allow you to connect to your SQL Express instance. [00:34:10]Now, if you were using Docker, you would have started your container [00:34:15]that would contain your SQL instance. [00:34:20]So you can go ahead and start it. And then when you’re connecting to it, [00:34:25]you would use localhost comma and the port that you had specified during setup. [00:34:30]So once you specify that, you also have to change the authentication to SQL Server authentication. [00:34:35]And then the login would be SA and then you can connect. [00:34:40]Of course, while setting up the container, you’d have put in whatever login name [00:34:45]and password you’d have preferred. So you can go ahead and fill those out [00:34:50]and then you can connect to your instance. [00:34:55]Now going back over to connecting to the SQL Express instance. Once I click connect, [00:35:00]it takes a few seconds and then it launches this section in the object Explorer. [00:35:05]So our object Explorer, which we can pin or hide at will, it shows us all of the objects [00:35:10]that are currently in this instance. [00:35:15]So you are actually capable of connecting to multiple instances [00:35:20]on this same machine. [00:35:25]So I have another instance on this machine as well. And each time you install SQL server, [00:35:30]you would actually get pretty much a new instance. So I can connect to another instance called localhost. [00:35:35]So within a scenario where you may be working with multiple computers [00:35:40]that are database servers, you can connect to multiple instances [00:35:45]in the same sitting here using the Management Studio. [00:35:50]Now, let’s refer to a scenario where we only have our one instance [00:35:55]and you can use this plug to launch the connector server window. [00:36:00]You can also use this one with the X to disconnect from an instance [00:36:05]to which you may already be connected. Now, if we expand the databases folder, [00:36:10]we’ll see that, well, nothing is in it. We haven’t gotten around to creating a database just yet, [00:36:15]but we do have some sample databases or some system databases rather. [00:36:20]They’re not samples. They shouldn’t be played with. So I would advise not to modify any of these unless you have [00:36:25]absolute mastery of SQL Server Management. [00:36:30]So these are some default databases that are required for the operation of the database instance. [00:36:35]So those are the databases that we get and later on, [00:36:40]we will see how we can create our own databases, [00:36:45]but other options that we have access to, we can access security options. [00:36:50]We can look at different logins and the credentials and roles for the server and other auditing [00:36:55]and more advanced things that are outside of the scope of this particular course. [00:37:00]Now, a key feature of using the Management Studio is the ability to write a query. [00:37:05]So a query is written in a language called SQL, [00:37:10]which we’re going to look at. But when you want to write a query, [00:37:15]you have two options to launch the text editor that allows you to write a query. [00:37:20]You can either click new query up top here or you can use the keyboard shortcut control plus N. [00:37:25]So if I use the keyboard shortcut control plus N, it’s going to launch a tab [00:37:30]that contains a text editor that allows me to write whatever I need to write. [00:37:35]Of course, it is within the context of SQL. [00:37:40]So this gibberish will not go down so well in the context of what it expects. [00:37:45]Now, a few things to note here. One, when I write a SQL query, [00:37:50]let us say I write a simple query like select name, [00:37:55]database ID, [00:38:00]create date from sys.databases. Now, you can take the time and rewrite this. [00:38:05]Of course, you can hit pause, replicate it. [00:38:10]But once you write it and you want to see the results, let’s do that again from scratch. [00:38:15]I printed that. So to get a new query window, all I have to do is control N [00:38:20]or click new query. So you can have as many query windows as you may need because you’ll be working with multiple databases [00:38:25]or multiple tables at least, and you may need to separate your queries. [00:38:30]Now, when I write this query [00:38:35]and I want to see the results of this query, I can click execute. [00:38:40]So I can click execute or I can press F5 on my keyboard. [00:38:45]So whichever one will actually execute this query and it will show us the results [00:38:50]in the bottom section. [00:38:55]Now, another thing that you want to take note of is the active connection [00:39:00]or the active database relative to the script. [00:39:05]So whatever database you see here is the database that is going to be affected by the script [00:39:10]or that the script will be run against. So when you have multiple databases, [00:39:15]then you want to make sure that the correct database is here. [00:39:20]And if you click the dropdown list, you’ll see all the available databases in the system at this point. [00:39:25]So if I try to run the same query against a different database, [00:39:30]it will still work because this is going to sys, right? [00:39:35]But then if I try to run it without that sys, I am going to get an error here, right? [00:39:40]Because none of these objects exist in this database. [00:39:45]If I try master MSDB or even temp DB, all of them will give me the same issue. [00:39:50]And if I try to execute, [00:39:55]I will get this error message below saying that this is an invalid object name. [00:40:00]So anytime we run a query that it’s not quite familiar with, we might see the red lines, [00:40:05]we might see the red lines and it’s just that the Management Studio [00:40:10]needs to recontextualize itself. But if we click execute [00:40:15]and it is not a valid query relative to the database that we are using, [00:40:20]then we’re going to see an error message looking something like this. [00:40:25]So these are some visual cues that can help you along as we build out our database. [00:40:30]Of course, I’ll be giving you more tips and tricks. But for now, I just wanted to give you a quick introduction to the Management Studio [00:40:35]and how it helps us to construct queries and carry out our operations. [00:40:40]Now, the final thing that I want to share with you is the fact [00:40:45]that we can actually save our queries because queries are there. [00:40:50]They really help with automation, right? [00:40:55]So you can write this one time and then you can save the query and then relaunch it at will. [00:41:00]So to save the query, it’s the same thing like saving a regular text file on a computer. [00:41:05]You can either use control plus S, you can click the floppy disk up top here, [00:41:10]or you can go to file and click save whichever one it is that you choose to do, [00:41:15]the end result will be that it’s asking you where do you want to save this query file. [00:41:20]So I can say test [00:41:25]or let’s say list databases query. [00:41:30]And I’m going to just save it on the desktop for easy access [00:41:35]and then I can just click save. Now, once I do that, if I was to close our Management Studio [00:41:40]and you see it’s prompting me that I have another query [00:41:45]that I have not saved. Would I like to save it? [00:41:50]I’ll choose not to save that one because that is the poorly written query. [00:41:55]However, I saved this one on the desktop and you can see here that I can double click the file [00:42:00]and it will prompt me where do I want with which app do I want to launch this file? [00:42:05]So I’ll choose SSM… SSMS and I’ll tell it to open with that all the time. [00:42:10]Click okay. And once SSMS is launched, [00:42:15]I am prompted to connect to the instance, [00:42:20]um, with which I intend to run this query. [00:42:25]And once I do that, you might get double prompted. So let’s just connect again. [00:42:30]But once I do that, you see it launches the window. It launches everything and my query is here and ready for me to run. [00:42:35]So that is another tidbit as to how you can help your own productivity going forward using SSMS. [00:42:40]Now, we will be looking at both scripting and using the UI [00:42:45]to complete certain operations. And that is where SSMS really has some advantages [00:42:50]because it has a powerful, uh, UI engine that gives us tools [00:42:55]to do certain operations. For instance, if I wanted to create a database, [00:43:00]I have the option of writing the script to create database [00:43:05]and let us say intro DB, right? [00:43:10]I can write that script. I can use this to create the database. [00:43:15]However, not everybody likes scripting and sometimes there are some simple operations that you may not necessarily want to go and write a script to do. [00:43:20]So you can actually right click the databases folder [00:43:25]and you can actually just create a new database here. So if I do this create new database, [00:43:30]then you’re going to see this dialog box come up and I can give it a name intro DB [00:43:35]to… I’ll get my spelling right [00:43:40]and then I can click okay. And then that would create the database for me. [00:43:45]So as we go along, we’re going to look at the fact that yes, [00:43:50]we can write a script, but we can also use the UI to complete certain tasks. [00:43:55]And, of course, we look at the pros and cons of either. So those are the things that the SSMS helps us to do [00:44:00]and it makes it really easy for us to interact with our database and the instance. [00:44:05]Now, when we come back, we’re going to look at some of the differences [00:44:10]and similarities between the SSMS and the Data Studio. [00:44:15]All right, guys, so in this lesson, we’re going to take a look at the Azure Data Studio, [00:44:20]and what it has to offer for us and our database development. [00:44:25]Now, you’ll probably want to use the Azure Data Studio [00:44:30]if you do not necessarily have, you know, super powered machine [00:44:35]because the SSMS can be a resource hog, but you also need to have it if you are not running on a Windows machine. [00:44:40]So if you’re not using Windows, then you need the Data Studio. [00:44:45]Now, the Data Studio comes with a number of things that the SMS… SSMS probably doesn’t prioritize [00:44:50]and the SSMS prioritizes certain things that the Data Studio does not prioritize. [00:44:55]Like for instance, the Data Studio allows us to use dark mode. That is pretty cool, right? [00:45:00]So you can always change your theme. You can go to settings. You can change your color theme, [00:45:05]and they do have various ones and you can actually download others and extend it. [00:45:10]The other thing with the Data Studio is that it does support multiple database engines. [00:45:15]So it’s not unique or limited rather to just Microsoft SQL Server. [00:45:20]I have been able to connect to a PostgreSQL Server as well. [00:45:25]I haven’t tested it with every single one of them, but it is versatile enough [00:45:30]that you can actually connect to other kinds of database engines through this one interface. [00:45:35]Now, when we launch and we would like to connect to our instance, [00:45:40]we would want to create a connection. You can also click this section here, which says connections. [00:45:45]You can see new connection. So clicking this and clicking this would launch the same window, [00:45:50]which will ask us the connection type. [00:45:55]So by default, we have a Microsoft SQL Server [00:46:00]and the connection parameters are pretty much the same. So for SQL Express, [00:46:05]I will type in localhost backslash and SQL Express. [00:46:10]I am using Windows authentication and I don’t need to select anything else. [00:46:15]But if I had a particular database I wanted to connect to, I could put it there, [00:46:20]but we don’t have any databases just yet, so that’s fine. [00:46:25]And I can just click connect. Once I do that and it is connected, then I will see that instance listed underneath that servers section [00:46:30]and just the same way I’ll see the databases. [00:46:35]Now, what you’ll notice is that you’re seeing far fewer folders [00:46:40]and options than we saw with the SSMS. [00:46:45]So you’re… you’re going to have to take note of that and what you don’t see here in terms of the UI, [00:46:50]you’re going to probably have to master how to write the script [00:46:55]to accomplish the same thing. It’s a good thing that we’ll be looking at both ways to do it. [00:47:00]So don’t worry. Now, for databases, if I wanted a new database, [00:47:05]I wouldn’t be able to right click and say new database like we did for the SSMS. [00:47:10]However, I would be able to write a script, so I can always say new query. [00:47:15]I can also say control N which is very similar to the SSMS and then that will allow me to write a query. [00:47:20]I can make the interface bigger and smaller by holding down on control [00:47:25]and pressing minus to make it smaller or plus to make it bigger. [00:47:30]All right? So those are little things that you can do to customize your experience [00:47:35]and make sure that you are as comfortable as possible. [00:47:40]So if I write the same query that we wrote in the SSMS and then execute it, [00:47:45]then we’re going to see the same kind of results. [00:47:50]Of course, it looks a little different but we can take heart that it is basically the same experience [00:47:55]once we know how to write our queries. So to create a database, [00:48:00]I would definitely need to be able to write create database. [00:48:05]But then you see here, we’re getting this thing called IntelliSense. We also have snippets. So I could actually [00:48:10]just use that snippet to generate a script that would just allow me to fill in the blanks. [00:48:15]So there are certain things that it makes a bit easier than the SSMS, [00:48:20]I guess because they know that, you know, they, [00:48:25]they are not catering for every single scenario with the UI. [00:48:30]So they try to make the scripting as easy as possible. So to get that snippet, I just typed SQL [00:48:35]and then I can, you know, scroll through all of the potential templates. [00:48:40]So if I wanted a new database, that was the one I tried just now, [00:48:45]create a new database, press enter, then it’s going to let me know, [00:48:50]create a new database called whatever it is I want and it will connect to master. [00:48:55]So it’s going to use master, check if the database and I can always just customize this user interface. [00:49:00]I can drag down the results and scroll. So if it does not exist, [00:49:05]so this lists all the databases, right? So this very query is being used here. [00:49:10]Select name, name, right? From sys.databases, sys.databases, [00:49:15]where the name is equal to whatever database name [00:49:20]I intend to create. So if it doesn’t exist, [00:49:25]then we want to create the database, right? [00:49:30]And then you can always click run to execute. So I’m just showing you that the Data Studio [00:49:35]does not have as many things for Microsoft SQL Server [00:49:40]as the SSMS does, but for the purposes of this course, [00:49:45]it is an adequate and very capable tool and we’re going to have fun using it [00:49:50]and using both of them and everything that you will learn will be transferable. [00:49:55]So stay tuned. In the next lesson, what we’re going to look at is draw.io.
[00:50:00] Emar Morrison In this section, we’ll be setting up the AdventureWorks database. [00:50:05]Now, this is a database from Microsoft that has pre-populated schemas and data, [00:50:10]which is what we’ll be using throughout this course. [00:50:15]At the end of this section, you’ll understand what are schemas and how to perform a backup [00:50:20]and restore of the AdventureWorks database. [00:50:25]In this video, you’ll learn how to set up the AdventureWorks database by performing a restore of the database. [00:50:30]Before we download the AdventureWorks database backup, [00:50:35]you need to check which version of SQL Server you’re using. [00:50:40]This is important because you cannot restore a higher version of the database [00:50:45]to a lower version of the SQL Server. So for instance, [00:50:50]currently I have a SQL Server 2019 edition running, right? [00:50:55]So if I download the AdventureWorks LT 2022 if one exists, then when I try to restore that database to the 2019 instance, [00:51:00]it will not be restored. [00:51:05]However, you can restore lower versions to higher versions as the databases [00:51:10]will be automatically upgraded in the process. So to check your database version, [00:51:15]you can use the command Select Attach Version. [00:51:20]So if you execute this, you’ll see the version of your database. [00:51:25]So now we need to head over to the Microsoft website to download a backup of the AdventureWorks LT database. [00:51:30]So I’m going to minimize this. [00:51:35]You can just Google AdventureWorks LT sample database [00:51:40]as well as I’ll leave the link in the resource section of this lecture, right? [00:51:45]So you’re going to scroll down and we want to get the OLTP version. [00:51:50]So here I have the AdventureWorks 2022 backup as well as the AdventureWorks 2019. [00:51:55]So I’m going to download AdventureWorks 22 just to demonstrate [00:52:00]what I was mentioning earlier. And I am also going to download AdventureWorks 2019. [00:52:05]So I’m going to minimize this. So the downloads were completed. [00:52:10]I’m now going to retrieve these from my desktop and copy them to the backup folder. [00:52:15]If you’re not sure where your backup folder is located, [00:52:20]right-click on your server instance, select properties, select database settings, [00:52:25]and then you’ll see where your backup location is. So I’m going to click okay here. [00:52:30]Now to restore the database, right click on the databases folder, [00:52:35]select restore database, select device. Here, select this icon with the three little dots, [00:52:40]select add, and here it took me to the default backup directory. [00:52:45]If your backups are not in your backup directory, you can browse to locate it in your downloaded folder. [00:52:50]So here I’m just going to attempt to restore the AdventureWorks 2022. [00:52:55]Select okay, okay, and okay again. [00:53:00]As expected, the restore failed. The database was backed up on a server running version 16. [00:53:05]That version is incompatible with the server [00:53:10]which is running version 15. So I’m just going to select okay [00:53:15]and browse to locate the 2019 backup. [00:53:20]Add, select the AdventureWorks 2019 backup, then select okay. [00:53:25]Now, you can remove the 2022 backup. So select the backup and then select remove. [00:53:30]Now select okay. So here when you’re restoring the database, [00:53:35]you have the option to change the name of the database, right? [00:53:40]So I’m going to leave it as AdventureWorks 2019, then select okay. [00:53:45]The database has been successfully restored. So select okay. [00:53:50]Now refresh databases. [00:53:55]So you right click and then scroll down to refresh. Now here we can see the AdventureWorks 2019 database. [00:54:00]In the next lecture, we’ll be exploring the AdventureWorks 2019 database. [00:54:05]So in the previous lecture, we had successfully installed [00:54:10]AdventureWorks 2019 database. [00:54:15]So now we’re going to explore the structure of the AdventureWorks 2019 database. [00:54:20]So to start, click this little plus icon here to expand the databases. [00:54:25]Typically, a database is made up of several objects. [00:54:30]You have tables, you have views, you have synonyms. [00:54:35]Under programmability, you have procedures, function, database triggers, and much more. [00:54:40]Later on in this course, you’ll learn more about these. So what we want to take a look at now [00:54:45]is the database tables. So select the plus for the tables. [00:54:50]Here we can see we have a bunch of different tables. So if you look carefully, [00:54:55]you’ll see a common naming convention among the tables. [00:55:00]You’ll realize that it has a two-part name. So it has a schema name and after the schema is a table name. [00:55:05]So it’s dbo.tablename, dbo.databaselog, which is a table name. [00:55:10]And when you scroll down, you’ll see that you have human resource and it continues. [00:55:15]Then it goes on to person, that table name, [00:55:20]and so on and so forth. [00:55:25]Now each of these that I just mentioned are called a schema. So you have a dbo schema, which is a default schema, [00:55:30]and schemas like human resource, person, [00:55:35]are all user-defined schemas. In simple terms, [00:55:40]a schema is just a logical collection of related database objects. [00:55:45]So for example, in the person schema, all the tables within the person schema are associated with a person. [00:55:50]All the tables within the human resource schema are associated [00:55:55]with human resource. So when you’re accessing an object within a schema, [00:56:00]you have to specify the schema name. So let me drag this across here. [00:56:05]So for example, if you wanted to access the department table, first you have to specify the schema [00:56:10]in which it is located and then you use a period to get access to the department table. [00:56:15]So here I’m just going to do a simple select all [00:56:20]from the department table. So here I have to first change the database [00:56:25]because currently this session which is open is to the master database. [00:56:30]Now here’s another thing. Without actually changing the database, [00:56:35]I could also specify the name of the database, then a period, right, [00:56:40]and I’ll still be able to access the data within the department schema. [00:56:45]So now you’ll see that first we have to actually go to the database, [00:56:50]then to the schema and then to the department’s table. [00:56:55]Now, let’s execute this and we’ll have the result returned. [00:57:00]We can change the database to the AdventureWorks 2019 [00:57:05]by selecting it from the dropdown. Also, you could use the use statement. [00:57:10]I’m going to copy the name. This also works. [00:57:15]Now in this case, I just need to get rid of the AdventureWorks and I’ll be able to query the department table. [00:57:20]So if I execute, I’ll still get the same result. [00:57:25]Now if I get rid of the schema totally, let’s execute, then it doesn’t know where to locate the department table. [00:57:30]However, if this table was in the DBO schema, [00:57:35]which is the DBO, which is the default schema, right? [00:57:40]Then I would be able to access this table without specifying the schema name. [00:57:45]So for example, if I grab the AW build version table and do a select on that table, [00:57:50]then I will be able to see the results. Now if I specify the schema, [00:57:55]I should be able to see the results. [00:58:00]So when you create objects without specifying the schema name, [00:58:05]they’ll be created in the default schema. So those are the tables. [00:58:10]Now, let’s look at the views. So let’s expand views. And here you can see that we have a bunch of views. [00:58:15]Don’t worry too much about the views though. Views are pretty much virtual tables [00:58:20]and are defined by underlying queries. So this query here, [00:58:25]I can now create a view on top of this query. Don’t worry about this right now. [00:58:30]You’ll learn about it later on in this course. In order to access the database, [00:58:35]you have to have users. So I’m going to minimize views. Honor the security. [00:58:40]Expand logins. And here are the logins that can be used to access the database server. [00:58:45]So currently, I am logged in as SQL admin. [00:58:50]Now when you’re logged in as the admin user, and this user has all the permission [00:58:55]that I need on the database. However, I am not going to be going deep into security [00:59:00]because that’s database administration. So when you look in the login section, [00:59:05]the user that you are logged in as, you’ll see it right here. [00:59:10]Or if you enable the SA user when you were creating the instance, [00:59:15]then you will not see a disable icon here. [00:59:20]Another important part of the database is the database diagrams. [00:59:25]This will give you a graphical representation of how your database looks. [00:59:30]So basically, this will show you the relationships with all your tables. [00:59:35]So here, you’ll see the database diagram. And when I click the plus icon, [00:59:40]it says the database does not have one or more supported objects required to use database diagramming. [00:59:45]Do you wish to create them? Sure, so I’m going to select yes. [00:59:50]Now, let’s refresh again, expand, now right click on the database, [00:59:55]select new database diagram. Oh, it’s a bunch of tables, so I’ll be just adding a few so you can see what the database diagram looks like. [01:00:00]Table, so I’m just going to select close here. [01:00:05]Now here you can see a graphical representation of the tables. [01:00:10]So these tables at the top are tables that do not have any relationship based on the tables that I’ve had it so far. [01:00:15]Now when you scroll down, you’ll see that the employee’s department history [01:00:20]is associated with the department table, [01:00:25]and it is related by the department ID. So you can scroll across and scroll down, [01:00:30]and you’ll see the rest of relationship of how the tables are integrated. [01:00:35]However, later on down in this course, you’ll learn more on how the tables [01:00:40]are actually related by primary keys and foreign keys. [01:00:45]So to summarize, a database is contained of different objects such as tables, views, [01:00:50]store procedures and triggers. And these objects are typically grouped by a schema, [01:00:55]whether it be the default schema or a user defined schema.
[01:01:00] Trevoir Williams Welcome back. In this lesson, we will be exploring what it takes to use SQL statements [01:01:05]to interact with a database. [01:01:10]Now we’re going to start off with our server instance and connect. [01:01:15]And I have no databases on this SQL Server instance. [01:01:20]So the first thing we’d want to do is open a new query window. Now once we have that new query window, [01:01:25]we can start writing our SQL statements. And to create a new database, [01:01:30]I need a create command. Now do note that SQL is not really case sensitive. [01:01:35]So uppercase create [01:01:40]has the same effect as lowercase create. What is important is that your SQL Server Management Studio [01:01:45]or your editor will color code the keywords. [01:01:50]So you want to pay attention to that. However, what I will do to make it clear [01:01:55]what the keywords are versus what are not keywords is I will try to write the keywords in uppercase [01:02:00]and then write the other words normally. [01:02:05]So once again, our task is to create a new database using an SQL statement. [01:02:10]So here I’ll say create database. And then this statement is followed by the name of the database [01:02:15]that we wish to create. [01:02:20]So I’m going to call this one AdventureWorks. Now please note, [01:02:25]throughout this course, you will be using the AdventureWorks database, and that is a ready-made database. [01:02:30]So this is just for example sake, afterwards we will remove it before we work with the real AdventureWorks database. [01:02:35]Now when creating a database, there are certain rules you want to follow [01:02:40]and best practices. One, it is always a good idea to camel case your names, [01:02:45]which means that each new word starts with a capital letter. [01:02:50]You can also use an underscore where if you don’t want the words joined, [01:02:55]you can use an underscore. I highly discourage spaces because once you insert a space, [01:03:00]then you need special characters surrounding the database name [01:03:05]so that the SQL Server will see it as one unit. [01:03:10]And every time you need to reference this database, you’ll need to remember to use the square brackets. [01:03:15]So for ease, it is better to avoid spaces and either camel case [01:03:20]or use underscores to separate the different words. [01:03:25]Now that you have your first statement created, which is going to create a new database, you can go ahead and execute. [01:03:30]Now you can do that by clicking execute here, or you can use F5 on your keyboard. [01:03:35]So once we execute that query, you’ll see a confirmation that the command was completed successfully. [01:03:40]And by refreshing the list of databases underneath the server that you’re connected to, [01:03:45]you will now see your new database. [01:03:50]In this lesson, we’re going to look at how we can remove a database after we have created it. [01:03:55]Now one of the things with SQL scripts is that they are repeatable commands, [01:04:00]which means that the operation of creating a database can be done multiple times. [01:04:05]I cannot create a database with the same name twice. [01:04:10]So you see I ran the command from the previous lesson, [01:04:15]and it says that the AdventureWorks database already exists. So we need to choose a different database name. [01:04:20]However, if I wanted another database, I could easily modify the name or change the name in some way. [01:04:25]So that’s AdventureWorks1, then AdventureWorks2. [01:04:30]And all I’m doing is changing the name of the database and pressing F5, so it executed it each time. [01:04:35]Now if I refresh the list of databases, I would see that I now have four AdventureWorks databases, [01:04:40]the original one and the ones that I just created. Now, if I wanted to remove these, [01:04:45]I have a command for that as well. [01:04:50]So to write the command to remove the database or drop the database, [01:04:55]I need a command that says drop, then database, and then the name of the database [01:05:00]that I wish to drop, which in this case, [01:05:05]I’m just going to double click this, copy, and then paste. [01:05:10]And this command will now say drop the database with that name. [01:05:15]Now if I have multiple scripts in the same file, and I only want to execute one [01:05:20]or multiple commands rather in the same script file, [01:05:25]and I only want to execute one, I can simply highlight that statement and then execute. [01:05:30]Now it only executed the drop database AdventureWorks3. [01:05:35]And if I refresh this list, I will see that statement [01:05:40]or that I will see that database is no longer there. [01:05:45]Now, if I wanted to comment out an existing statement, [01:05:50]which means that I want to leave it in the script, [01:05:55]but I don’t want the responsibility of needing to select the exact line every single time, [01:06:00]I can precede that statement with a double dash or double hyphens [01:06:05]that will comment it out. So I can now press F5 [01:06:10]for the entire script, and it will execute the entire script but ignore the section that has the double hyphen in front of it. [01:06:15]So with that done, we have seen how we can drop the database [01:06:20]and we’ve also seen how scripts help us to automate these kinds of operations. [01:06:25]So if I wanted to drop the other two AdventureWorks databases, [01:06:30]I could simply say drop database AdventureWorks1, press F5, [01:06:35]and then I get my confirmation message. And then I’ll do the same thing for AdventureWorks2. [01:06:40]And when I refresh the list of databases, [01:06:45]I see that I’m back where I started with the original AdventureWorks database. [01:06:50]When we come back, we’ll look at how we can use our SQL scripts to add tables to our database. [01:06:55]Now we want to add tables and possibly drop them if we have any mistakes. [01:07:00]So I’m going to open up a new query tab [01:07:05]in my SQL Server Management Studio. [01:07:10]And that is easily done by clicking new query, or on your keyboard, you can use control and the letter N for new. [01:07:15]And that will also open up a new query tab. [01:07:20]In this query tab, we want to start off with a use statement. [01:07:25]So the use statement is used to declare the database that is going to be targeted for all the scripts inside [01:07:30]of this SQL script file. So here I’m going to say use AdventureWorks. [01:07:35]Here I’m declaring once again, [01:07:40]that I want to use the AdventureWorks database to carry out all of these commands. [01:07:45]Now inside of this AdventureWorks database, I intend to create a new table. [01:07:50]The command to create a new table is once again create, [01:07:55]but this time we say table, not database. Then we proceed to put in the name of the table. [01:08:00]So in this case, I’m creating a table called employees. [01:08:05]Now, SQL commands can actually go from left to right forever, [01:08:10]meaning you don’t have to space them. You don’t have to break lines in between them and so on. [01:08:15]You can actually write everything in one line from left to right. [01:08:20]However, for readability, I’m going to break it up into different lines so you can see each line clearly. [01:08:25]So I’m going to press enter and open and close parentheses. [01:08:30]And then I’m going to press enter again twice to create a space [01:08:35]or several spaces in between these parentheses. Now what’s happening here is that we’re saying create a table [01:08:40]with this name, and then we’re going to give it the attributes. [01:08:45]A table typically has rows and columns, but in the design process, [01:08:50]we need to define what the columns are because each column represents [01:08:55]the storage area for a data point. And then, of course, [01:09:00]the row represents the entire row of data spanning all of those columns. [01:09:05]So here we need to define each column and the data type that they should have. [01:09:10]Let us start off by defining the primary key column, which is generally very important. [01:09:15]And I’m going to call it ID. I’m calling this one ID, [01:09:20]and then I’m going to give it a data type of integer. [01:09:25]And then I’m going to tell it that it is the primary key. [01:09:30]And finally, I’m going to tell it that it’s an identity column. [01:09:35]Now let us insert another column. This time we’re calling it first name. [01:09:40]And the data type for first name will be VARCHAR 50. [01:09:45]Now different data types have different requirements. So VARCHAR is a suitable data type for alphanumeric [01:09:50]and special character combinations. So this would be an ideal data type for a first name. [01:09:55]And then I can add an attribute called not null, [01:10:00]which would indicate that this column should never have a null value. [01:10:05]So null represents nothing. No value was provided. [01:10:10]But I don’t want to have any employees stored in my table that don’t have a first name. [01:10:15]So it’s important for us to make sure that we add attributes that help us to enforce what we call data integrity [01:10:20]in our database tables to make sure that the data is as accurate as possible. [01:10:25]Then I have another column and I want to call it last name. [01:10:30]And it’s going to be very similar to first name. Instead of typing it from scratch, [01:10:35]I can actually put the cursor on the first name column line, hold on control [01:10:40]and press C and then V. And it will actually duplicate that line. [01:10:45]Now the editor is showing me a red line because I already have first name. [01:10:50]So I can just edit that and change the name to last name. [01:10:55]And that helped me to write that script a bit faster than doing it from scratch. [01:11:00]So I have ID, first name, last name. Maybe the last thing that I’ll put in here is date of birth. [01:11:05]The data type for date of birth would be DATETIME. [01:11:10]And there’s actually DATETIME2. So DATETIME2 has a wider range [01:11:15]for date values than the standard DATETIME. [01:11:20]For this example, I will use DATETIME2. And I will allow this to be nullable. [01:11:25]So I can actually just say null or if I leave it by default, it will be nullable. [01:11:30]And that is how we can go about creating [01:11:35]or one defining the table to defining the columns in the table. [01:11:40]And in order to create the table, we can execute this script and it will now switch over to AdventureWorks [01:11:45]and create that table. And to prove it, we can now look in the tables folder [01:11:50]for our database and we will see that employee’s table. [01:11:55]And if we expand this and look at the columns, we will see the columns listed [01:12:00]as defined in our script. You’ll also see that we get a snapshot peek [01:12:05]that this is a primary key. It’s integer and it’s not nullable. [01:12:10]So we don’t have to define not null on the primary key that’s implied. [01:12:15]And then the two that we defined as not null are defined as not null. [01:12:20]And the one that we did not define null on is null. [01:12:25]Now, once again, this is repeatable. [01:12:30]So I can create multiple tables just by making sure that I have different names. [01:12:35]Now, if I try to execute this entire script, I’m going to get an error saying that there’s already an object [01:12:40]by that name because I did not comment out this statement. [01:12:45]Now, when you have multiple lines like this and you want to comment out the entire statement, [01:12:50]I would suggest that you highlight the entire section of that statement and hold on control [01:12:55]and press the letter K and then C. And that will just apply that [01:13:00]double hyphen prepend to all the selected lines. [01:13:05]Now, if I try to execute again, it will use AdventureWorks, ignore the commented lines [01:13:10]and execute the create script on employees one. If I refresh the table’s folder, [01:13:15]I will see that I now have employees and employees 1. [01:13:20]Now, if I made a mistake and I created employees 1, then we can, of course, [01:13:25]drop that table. So to drop the table, [01:13:30]if you said drop table is the command, then you’re absolutely right. [01:13:35]Drop table and then the table name. And I’ll just execute this single line, [01:13:40]press F5 and the command was completed successfully. If I refresh the tables, there I go. [01:13:45]That table has been dropped. So now you see how simple it is to create a table [01:13:50]and also drop a table. In this lesson, [01:13:55]we’re going to look at how we alter or change a table after creation. [01:14:00]And we’re going to create additional tables [01:14:05]and then look at how we create relationships between these tables, [01:14:10]all using SQL statements. So up until now, we’ve created [01:14:15]and dropped the database. We know that we need to precede all of our commands with the use statement. [01:14:20]We’ve created a table called employees, and we know how to drop a table if we need to. [01:14:25]Now, notice I’m trying to keep all of the commands in one script file, [01:14:30]which you can reference at the end of this section, of course. But I am just commenting out the commands [01:14:35]that I don’t want to run again as I continue to work. [01:14:40]So do remember that as you build out your scripts, [01:14:45]you can always comment out commands if you just want to keep them there, but you don’t want to run them every single time. [01:14:50]Now let us move on. Now, I’m going to create another table. [01:14:55]So I’m going to use the same technique that we just learned earlier. [01:15:00]And let us call this table position. So this table is going to represent [01:15:05]the employee’s position in the company. And now remember, just for readability, [01:15:10]I’m going to break line, open parentheses, break the lines twice, close the parentheses, [01:15:15]and then we can start defining our columns in here. [01:15:20]So most, if not all the time, you want your table to have a primary key, [01:15:25]and you can call it ID. Naming convention wise, you can also precede the word ID [01:15:30]with the name of the table. Generally speaking, I already know I’m in that table. [01:15:35]So personally, I don’t do that one. But you do have the option, [01:15:40]and readability is very important for other persons to be able to use your database after you’ve created it. [01:15:45]So that is why I’m always sharing these naming conventions [01:15:50]and best practices as I go along. So we have ID. It is going to be an integer. [01:15:55]It’s going to be the primary key. And it’s, it’s going to be an identity column. [01:16:00]So that means it will automatically count. I think we understand that from the previous activity. [01:16:05]The next column that I’m going to put in this new table is name. [01:16:10]So here, it’s just name. But notice that when I type the word name, it’s blue, [01:16:15]just like all the other keywords. [01:16:20]So sometimes you may want a column name that is also a keyword. [01:16:25]And in that case, you can actually use the square brackets and wrap it. [01:16:30]So SQL will now ignore it as a keyword and treat it like a regular word. [01:16:35]So this name here represents the name of the position, right? [01:16:40]You could also maybe call it description. But I’ll just use name for simplicity. [01:16:45]I’m going to give it a data type of VARCHAR. And I’m going to give this a size of 100 [01:16:50]because I don’t know what kind of job titles, um, might be used. [01:16:55]And I’m going to say not null because it doesn’t make sense you enter a record here [01:17:00]without giving this a name. So I just used a different word which was job titles. [01:17:05]I’ll actually change that table name to job titles. [01:17:10]So create table, job titles. And it’s going to have an ID, primary key. [01:17:15]And then it’s going to have a column where we’re going to actually put the name [01:17:20]or the actual job title value. So we can go ahead and execute this. [01:17:25]So now when we refresh our tables, [01:17:30]we have two tables present. Essentially, we want to be able to associate an employee with a job title. [01:17:35]So now what we need to do is modify our employee’s table, [01:17:40]which only has the ID, first name, last name and date of birth. [01:17:45]We need to modify this table with another column [01:17:50]that represents the foreign key from our job titles table. [01:17:55]So this foreign key is what establishes that there is a relationship between the two tables. [01:18:00]So now we have two changes that we need to make. [01:18:05]We need to one, add a new column to this table, employees, which already exists. [01:18:10]And then we need to add what we call the foreign key constraint [01:18:15]that will bind this new column, which we’re going to call job title ID [01:18:20]to the primary key value of the job titles table. So let us get that done. [01:18:25]So to modify or alter a table, we use the keyword alter, [01:18:30]then specify a table and then give the table name. [01:18:35]Then I’m going to specify what it is that I want to alter. [01:18:40]So in this case, I want to add a column. So I’m saying add, [01:18:45]and I’m going to give it the name and then state that it’s an integer. [01:18:50]At this point as well, I can go ahead and specify other constraints. [01:18:55]For instance, I can specify that job title ID is not allowed to be null. [01:19:00]You can’t be an employee without a job title ID. Once again, [01:19:05]that’s up to you and your context to make those determinations as to what constraints [01:19:10]you want to add to your columns. However, with this done and before I execute, [01:19:15]I’m just going to comment out that previous create command. [01:19:20]And now when I execute, this will now add job title ID to the employee’s table. [01:19:25]So if I refresh this table and then look at the list of columns, [01:19:30]I’ll now see that I have a brand new column that is integer and not allowed to be null. [01:19:35]So at this point, we have a new column. What we don’t have yet is the foreign key constraint, [01:19:40]which is what actually tells SQL that this, this column is actually related [01:19:45]to a column in another table. So we’re going to run another alter command, [01:19:50]and this one is now going to alter this column [01:19:55]that we just created to tell it that it is a foreign key. [01:20:00]So I just copied and pasted, so I didn’t have to type that all over. [01:20:05]And then I’m going to say here, add foreign key, and then specify the column, [01:20:10]which in this case is job title ID, [01:20:15]and then references, and then the name of the table with the primary key, [01:20:20]and then the column that is the primary key. [01:20:25]So just in case you’re not very familiar with, you know, [01:20:30]the concept of foreign keys and primary keys and relationships, [01:20:35]in a nutshell, within a table, a primary key acts as the unique identifier per row. [01:20:40]I think we discussed that earlier. And then when it comes to foreign keys and relationships, [01:20:45]there are times when we don’t want to repeat certain data all over our database. [01:20:50]Like in this case, if we have several persons who are managers, [01:20:55]I don’t want to repeat the word manager every time, because then if that job title changes in the future, [01:21:00]that means I have that many places to change that job title. [01:21:05]Instead, we create one table, and then we have that job title listed once, [01:21:10]and then we need to reference it whenever we need it, [01:21:15]which in this case is what we’re doing with the employee’s table. [01:21:20]So instead of writing the job title name for every employee, instead, [01:21:25]I’m just going to reference that job title by its ID. And then that is why we have to add this foreign key constraint, [01:21:30]because then we don’t want to allow the job title ID to have a value [01:21:35]that doesn’t directly correspond with an actual job title record. [01:21:40]So this foreign key constraint here is saying that whatever value that can go into the job title ID [01:21:45]in the employee’s table is directly bound to the possible values [01:21:50]that are in the job titles table and in the ID column. So if I have five job titles, [01:21:55]I cannot be referencing job title ID 30. [01:22:00]If you want more hands-on teaching and practice with relationships, [01:22:05]you can check out my complete Microsoft SQL Server Database Design Masterclass, [01:22:10]where I actually bring you through all of these concepts from the ground up. [01:22:15]For now, however, we now know how to write SQL statements to modify our table [01:22:20]and facilitate relationships between our tables. Now, this has concluded this lesson. [01:22:25]I’ll see you in the next one. Welcome back. In this lesson, [01:22:30]we’re going to be looking at unique and default constraints and just the overall concept of how we can add constraints [01:22:35]that can go a bit further than just saying not null. [01:22:40]So we’ve discussed constraints before. Not null is a form of constraint [01:22:45]because it places a limitation over the possible values for the column [01:22:50]that it is specified against. We could look at another constraint like adding the foreign key, [01:22:55]where we place a limitation over the potential set of values that can go into job title ID [01:23:00]relative to the values that are available in the ID column of another table. [01:23:05]But there are times when you have other needs for constraints. [01:23:10]Like maybe for the employee table, you want to add an employee ID, [01:23:15]which is different from the auto-incrementing ID that is strictly for database purposes, [01:23:20]but maybe the employee ID that would get printed out on somebody’s [01:23:25]actual identification card. This could be system generated. [01:23:30]But the fact is that you actually want that once a value goes in, it is going to be a unique one. [01:23:35]So that is a form of constraint that we would probably want to implement on such a table and column. [01:23:40]So we’re going to continue altering our employee’s table. [01:23:45]I’ll just copy that command. [01:23:50]And this time we’re going to say add employee ID. [01:23:55]And then I’m going to specify that it should be unique. Of course, I need a data type. [01:24:00]So because this one is just for identification purposes, [01:24:05]I’m going to use the VARCHAR data type. And it’s very important that you use the correct data types and sizes. [01:24:10]So I’m using VARCHAR here because different companies may have [01:24:15]different patterns for ID numbers. They might have hyphens. [01:24:20]They might have alphanumeric combinations. So it doesn’t make sense I use an integer [01:24:25]because then I would be limiting the possible values and combinations of values. [01:24:30]Especially since this ID value, the employee ID value rather is not mathematical in nature. [01:24:35]So it doesn’t have to be a number. So I don’t have to use a numeric type for it. [01:24:40]That’s the rule that I abide by, and that would be my recommendation to you [01:24:45]when you’re trying to decide the best data type. Always think about the implications of the data going in. [01:24:50]So here I’m going to say VARCHAR and let’s say 10 [01:24:55]because the ID numbers are generally up to 10 digits long, right? [01:25:00]So I think that should be good enough. And then we’re familiar with this part. [01:25:05]The new part here is this new constraint, which is unique. [01:25:10]So you see that even though it’s not grayed out like not null is, but it is a constraint. [01:25:15]And once I add this, I can jump over and expand my employee’s table. [01:25:20]I see that I now have this employee ID added. And if you notice, I didn’t point this out before, [01:25:25]but with foreign key, you’ll see that little key up here [01:25:30]because we added that constraint. But then in the indexes section, [01:25:35]you’re going to notice that you have the PK employee, which is the index on the primary key of the table. [01:25:40]And you’ll now see UQ employee, which is representing that unique value [01:25:45]for the employee ID. And it is now an index as well. [01:25:50]So that is how you can go ahead and add a unique constraint. [01:25:55]Now, as it stands, I’m unable to enter two employee records with the same value. [01:26:00]It will take the first one and reject every other one afterwards, [01:26:05]because whatever goes in this column has to be unique across the entire table. [01:26:10]So that is a good restriction to have for a column like this. [01:26:15]Now, another kind of constraint that you may add would be one for default values. [01:26:20]So let’s do another alter employee’s statement. [01:26:25]And this time we’re adding employment date as our column. [01:26:30]This is going to be DateTime2. [01:26:35]And in Employment Date, we want to specify, obviously, [01:26:40]which date the employee was hired. Now, the thing is that we don’t want to necessarily [01:26:45]leave it up to maybe HR or whoever is putting in the value every time [01:26:50]to actually specify that, hey, this was employment date. [01:26:55]And we can probably safely assume that the day that they’re going into the database is the day that they were hired. [01:27:00]So we can set a default constraint here, [01:27:05]which is simply going to say that whatever date, if the date is provided [01:27:10]when it is entered, then default to the value that comes back [01:27:15]from this function call. Later on, we’re going to get into functions, [01:27:20]but here’s your quick and dirty introduction to functions. [01:27:25]So this function called Get Date is a built in mechanism that will look at the computer date [01:27:30]and return that value. So in other words, if I don’t provide a date, [01:27:35]it’s not allowed to be null or I’m not telling it it’s not allowed to be null explicitly, [01:27:40]but instead of being null, it will default to whatever the date is at the time [01:27:45]the record is going in. [01:27:50]So that is another type of constraint that you could find useful based on your situation. [01:27:55]Now, this time, if I refresh the employee’s table [01:28:00]and expand the columns, I’ll see employee date. And if I expand constraints, [01:28:05]I will now see that constraint added for the default. [01:28:10]Now, these are two examples of commonly used [01:28:15]and popularly used constraints, [01:28:20]but there are others because you can just add an index, which is a high speed lookup. [01:28:25]Indexing is implied once something is unique and you can always go ahead [01:28:30]and explore and use them according to your situation. [01:28:35]But this is the basic concept behind them. So it’s very important that you research the constraint that you want [01:28:40]and make a decision as to whether or not it is best for your particular situation. [01:28:45]Now, beyond altering and adding foreign keys [01:28:50]and constraints and new columns, we can also drop all of these things. [01:28:55]So in the next lesson, we’re just going to look at how if we wanted to remove any of these, [01:29:00]we would go about doing that. All right. So in this lesson, we’re going to look at how we can drop some of the columns [01:29:05]and constraints using SQL statements if we really want it. [01:29:10]So once again, anytime we’re making a change, [01:29:15]we have to use our alter statement. And then in this case, [01:29:20]I’m going to state what I want to drop. So I would say drop, if it was a column, [01:29:25]maybe I no longer want the date of birth column, for instance. [01:29:30]So I’ll say drop column, date of birth. And that would drop the column for the date of birth. [01:29:35]And it’s that simple. Now, while we’re here, yes, we’re talking about dropping, [01:29:40]but you may end up in a situation where you may be needing to change the data type. [01:29:45]For instance, date of birth doesn’t necessarily need to be date time [01:29:50]because we’re not actually interested in the time of birth. We really just want the date. So I already have the data in the table. [01:29:55]I already created it, but I want to alter it. So I can say alter, uh, [01:30:00]column and then specify that I’m altering date of birth [01:30:05]and then simply state new data type which would be date. [01:30:10]And right there I would change [01:30:15]the data type of date of birth to date. [01:30:20]So here it is, that is date of birth as Date Time. If I refresh this, now you’ll see it there as date. [01:30:25]And it’s that simple. Of course when altering, be mindful of the fact [01:30:30]that you will end up trunc… what we call truncating data [01:30:35]that is already in the table. So all the timestamps would no longer be there. [01:30:40]The dates would be there no longer the timestamps. So similarly if you were to increase or sorry, [01:30:45]decrease the size of like a VARCHAR, then you would definitely be chopping off parts of the words [01:30:50]that were stored in there prior to. So be very careful when making those decisions. [01:30:55]Now, let us move on to if we wanted to drop a constraint. [01:31:00]So I’m just going to comment each line here [01:31:05]and I’ll just use the alter table of top instead of copying and pasting each time. [01:31:10]So when we’re adding the constraint, like for the unique, what we did not look at was the fact that you could actually name it. [01:31:15]So here we have a name. If we look in indexes, [01:31:20]this is the name of that constraint and I actually have to reference that name [01:31:25]if I’m going to drop it. So if I was to go ahead and say drop constraint, [01:31:30]I would say drop constraint, right? [01:31:35]But then I need the name here, so I’m just going to click it perceive tool [01:31:40]so it becomes editable and then paste it over here. [01:31:45]Now, this will allow me to drop that unique constraint on that column, [01:31:50]but then this constraint name was long. So it’s auto generated SQL took [01:31:55]the work out of it for you to have to name it, especially if you’re doing several of them. [01:32:00]It can become tedious to be naming each one. But the reality is that we have the option to do so [01:32:05]and it can lead to maybe more manageable names when we want to do a drop command like this. [01:32:10]So let us re-add that constraint, [01:32:15]but this time I’m going to give it my own name. [01:32:20]So I’m going to say we already have the alter table command [01:32:25]and then I’m going to say add constraint [01:32:30]and then I can give it a person, uh, sorry a name. So I can say here, [01:32:35]UQ_EmployeeId, which is short for unique employee ID. [01:32:40]And then I’m just going to specify the kind of constraint. [01:32:45]It’s unique and then I’m going to specify the column that it should target, which is employee ID. [01:32:50]Now in this case we’re assuming, well, the column obviously has to exist prior to. [01:32:55]So here we’re doing both adding column and unique constraint. [01:33:00]In this case I would be adding the constraint retroactively [01:33:05]and also giving it my own name. So if I complete that one, [01:33:10]then if I refresh the indexes section of our explorer, [01:33:15]you’ll see UQ employee IDs now there. [01:33:20]So that is now the name I can use when I want to drop it. [01:33:25]So instead of this one with the query and hash behind it, I have a much simpler name [01:33:30]that I gave it. Once again, make these decisions based on your needs [01:33:35]and you’ll be fine. Now that concludes this lesson [01:33:40]for how we would go about dropping parts of the table. We already know how to drop the entire table and drop the entire database. [01:33:45]So in the next lesson we’re just going to clean up our environment.
[01:33:50] Emar Morrison We have completed several activities in this module, [01:33:55]but we are going to have to do some cleanup because we are going to be using the AdventureWorks database [01:34:00]for this entire course. Of course I don’t want that. [01:34:05]Our example AdventureWorks database is going to cause any conflict [01:34:10]with the AdventureWorks database that we will restore and use later on. [01:34:15]So as for our cleanup activities, what we’re going to do is remove the database [01:34:20]and I’m sure that you already know [01:34:25]which statement you’re going to use. And if you’re not sure, then just work with me. [01:34:30]We’re using the drop database and then the name of the database [01:34:35]and that is our command. So if you completed this exercise using a different name [01:34:40]from AdventureWorks and there’s no risk of ambiguity [01:34:45]when we use AdventureWorks later on in the course, then that is no problem. [01:34:50]Now when I execute the command, I get an error and this error is saying that it cannot drop the database [01:34:55]by that name because it is currently in use. [01:35:00]Now, the reason it is saying it is in use is I have this square window that is currently connected to it [01:35:05]and I have two other query windows from previous activities that are still [01:35:10]seeing it as the database that they’re connected to. [01:35:15]So for, for context, when a database is in use, whether in the Management Studio [01:35:20]or by other applications [01:35:25]that are actively connecting to it and using it, you cannot just drop it. [01:35:30]So be very careful when you’re running a drop command one [01:35:35]because you don’t want to accidentally drop a database. There’s no undo method for this operation. [01:35:40]And the two, when it is in use, it cannot just be dropped, [01:35:45]it has to be disconnected from completely and then dropped. [01:35:50]So for our purposes, I can click on one of my script windows [01:35:55]and I can go down to connection and I can say disconnect. [01:36:00]I can also say disconnect all queries, that disconnect all queries command, [01:36:05]disconnected all the query windows from the database. [01:36:10]So now there are no active connections to our AdventureWorks database. [01:36:15]So if I go back to the original one, I’ll actually need to reconnect to the server so that I can execute the drop command. [01:36:20]So I can right click once again, go to connection, choose connect, [01:36:25]it will relaunch that connect window and I confirm the server that I’m connecting to, [01:36:30]and then I can execute this query and that command was completed successfully. [01:36:35]And if I refresh the list of databases, you will see that AdventureWorks is no longer there. [01:36:40]And that is how you can go about actually dropping a database [01:36:45]that might be in use by other applications and by extension cleaning up our environment for this course. [01:36:50]If you are interested in saving your scripts like these scripts [01:36:55]that we wrote for these activities, then feel free to use Ctrl and S [01:37:00]or you can use the floppy disc in the toolbar above [01:37:05]or you can go to file and go to save or save as [01:37:10]any one of these will bring you to the same dialogue window that allows you to save the .SQL file [01:37:15]on your computer for future reference. [01:37:20]All right, so in this lesson we’re going to look at a select statement. [01:37:25]Now, basically with databases [01:37:30]there are four fundamental operations that you would carry out [01:37:35]when it comes to interacting with the data. [01:37:40]And they are characterized by an acronym called CRUD. [01:37:45]The C is for create, the R is for read, the U is for update [01:37:50]and the D is for delete. Now in looking at select statements, [01:37:55]we’re going to be looking at doing read operations [01:38:00]because the reality is that to see the data we need to be able to read the data. [01:38:05]Um, data has to be present and we are starting off with the AdventureWorks database [01:38:10]that you would’ve set up by now. So there is data there for us to work with and what we’re going to do is [01:38:15]focus on different scenarios and different ways that we can interact with the data so that we can have it in a presentable manner [01:38:20]for our use. [01:38:25]So I’m already connected to my database instance and I have my AdventureWorks database, [01:38:30]AdventureWorks 2019 database and you would’ve already done your setup as well. [01:38:35]So let us start with a basic select statement. [01:38:40]The first thing that I always try to put in my SQL state, [01:38:45]uh, scripts before I do anything else is the use statement. [01:38:50]So I can use and then specify that I am using AdventureWorks for the next set of queries. [01:38:55]And then let us say that we wanted to select all. [01:39:00]So I’m just going to kind of write a scenario above in a comment. [01:39:05]So I want to select all data from a table, something nice and simple. [01:39:10]So to select all the data from a table, [01:39:15]that means I need to have what we call a select statement. [01:39:20]So select which is a key word and then I’m going to say asterisk or star, right? [01:39:25]So all you have to do is put that symbol that asterisk [01:39:30]and then you say from, and then you specify the table [01:39:35]that you want to select everything from. Now, with the AdventureWorks database [01:39:40]do recall that we have what we call schemas or schema names before each table. [01:39:45]By default we get DBO. [01:39:50]However, when creating the table with a specific schema, schema, sorry, you’re going to end up with that specific schema preceding the actual table name. [01:39:55]So when you want to select from that particular table [01:40:00]that has a schema, that’s not the default, [01:40:05]then you want to fully qualify the name, meaning you’re going to specify the schema dot the table. [01:40:10]So here I’m going to do the employee table ‘cause we had [01:40:15]some experiments earlier in the course with you know what an employee table might look like [01:40:20]in a database called AdventureWorks. [01:40:25]So I feel emotionally attached to this one if you will. So when we say select star from human resources dot employee [01:40:30]and run this, it does the use statement, [01:40:35]then it goes searches for that schema and that table in that schema [01:40:40]and then it brings back all of the data in this grid. [01:40:45]So from here we can see the different columns and the different values per column [01:40:50]and remember that the columns represent the data points [01:40:55]and then the rows represent the actual record. [01:41:00]So here we have that layout. Now, there are certain indicators [01:41:05]that we can use to inform how many records came back. [01:41:10]If you look in the bottom right hand corner of your Management Studio, and I’m sure it’s in a similar position in the Data Studio, [01:41:15]then you’ll see the number of rows that the square brought back. [01:41:20]Now, this square can be, uh, resource intensive query. [01:41:25]The bigger the table, the slower your machine. So if you had a table with tens of thousands of records, [01:41:30]you probably wouldn’t want to just do one big select to get all of them, right? [01:41:35]So typically you would do a select maybe just to get a snapshot of what is in the table [01:41:40]and to get a snapshot, [01:41:45]you don’t need every single record, you probably just need like the first 100 or the first 1000, [01:41:50]something like that. So here’s another scenario then, [01:41:55]I want to select the top 100 records from the table. [01:42:00]So this statement is going to say select, [01:42:05]then we say top and a numeral, which in this case would be 100, [01:42:10]it could be 1000, whatever that number is that you really want to see, [01:42:15]then you specify that number. And then we still say star. [01:42:20]And I’ll go into another scenario now where we might not use star and then from, [01:42:25]and we’re selecting from the same human resources dot employee. [01:42:30]So I’m going to comment this one out so it doesn’t run again. [01:42:35]And then when we press F5, now we’re seeing only 100. [01:42:40]If I only wanted to see 10, well guess what? Top 10 gives me the first 10 records. All right? [01:42:45]So that’s how you can now limit the number [01:42:50]and it will run much quicker against a much bigger dataset and it’s just more efficient. [01:42:55]Now I just mentioned that there are scenarios where you won’t use star and the star there or asterisk however you want to say it, [01:43:00]but generally speaking it say select star. [01:43:05]So I’m going to keep on using that, um, speech pattern so that it sticks [01:43:10]because that’s generally how it is set. So when you select star, [01:43:15]what you’re saying is that you want every single data point [01:43:20]for every single record that you are selecting from that particular table. [01:43:25]The fact is that you may not necessarily want to see every single one because you probably don’t need to see the real query. [01:43:30]You probably don’t need to see the current flag and especially if you’re doing this for like a report. [01:43:35]So you can actually go ahead and filter out the exact columns. [01:43:40]So I want to say let us select specific columns from the table, right? [01:43:45]So here I’ll say select again. [01:43:50]So I, I hope you see the common theme. Anytime you want to read data, [01:43:55]it’s a select statement. Now instead of star, we’re actually going to specify the column names [01:44:00]that we’re interested in. So if I wanted to see maybe [01:44:05]that employee’s login ID [01:44:10]and their job title and maybe their hire dates, [01:44:15]let’s just say those are the three things that we’re interested in. [01:44:20]Login ID, what they do in the organization and what date they were hired. [01:44:25]So I can actually say select, this is the column login ID and then comma separate [01:44:30]all of the columns that I am specifically interested in. [01:44:35]So job title and hire date. And once again, it’s not very strict. [01:44:40]It being SQL is not very strict when it comes to the casing of your, your, your typing, right? [01:44:45]So if I say job title in lower caps here, [01:44:50]even though it is capital J, capital T, and I just write it in all lowercase, [01:44:55]if I, you know was a little slack [01:45:00]and wrote login with a common L when it’s a capital L and then wrote this one perfectly, it’s really not going to matter that much. [01:45:05]So I’m specifying those columns and then I still need to stay to state [01:45:10]from which table, so I’m still in human resources, [01:45:15]that employee and then those errors go away because now it knows which table it is looking for them in. [01:45:20]So let me comment this out and then run this statement [01:45:25]and now you’ll see that I’m getting the specific columns. [01:45:30]Also notice that the column names that are being printed out here in the grid kind of match the same case that I used here, right? [01:45:35]So you know, all of those, the things do matter. [01:45:40]So if I just cart them based on how they were they’re originally presented, [01:45:45]then you’ll see that they’ll come back more specifically, right? [01:45:50]So that is in a nutshell how you can go about using select statements [01:45:55]to start looking at the data. But then all we’ve done so far is filter out columns. [01:46:00]What if we actually wanted to filter out records like maybe we only wanted to see particular records [01:46:05]out of the entire 290 row dataset? [01:46:10]So in the next lesson we’re going to come back and look at how we well one filter data to specific, um, [01:46:15]conditions and how we arrange our data or sort our data.
[01:46:20] Trevoir Williams Welcome back. In this lesson we’re going to be looking at filtering [01:46:25]and sorting our data. And in this scenario we’re going to want to select [01:46:30]only persons who are marketing assistance for example. [01:46:35]Now, I’ve already run the big statements to get everything from the database [01:46:40]and this is the general process because generally speaking, you probably, [01:46:45]especially if you are not the one who built the database, [01:46:50]won’t be familiar with the structure of the database or even the data that is in the database. [01:46:55]So sometimes you run like a select star statement, maybe you limit the number of course to the top 10 or 100, [01:47:00]whatever it is. But you would generally want to see, okay, [01:47:05]what does the data look like so that I can assess and see what is the best kind of condition [01:47:10]to add to get exactly what I want. So for this scenario, we want only marketing assistance. [01:47:15]So we’re going to amend our select statement [01:47:20]and then we’re going to add our filter statement, which is where, [01:47:25]and I’m just going to break line. So remember that SQ L goes as far left to as far right as, [01:47:30]as you can type. However for readability, it’s always good to the break line so that you can see the clear distinct lines [01:47:35]in the entire statement. [01:47:40]So select star from that table where, and then the column name here is job title. [01:47:45]So this is not a column that’s going to serve as the pivot point for our condition. [01:47:50]So I’m going to say where the value in [01:47:55]the job title column might be equal to. [01:48:00]And then I’m using a single quote and then pasting in what we call a literal string, [01:48:05]which is marketing assistance. So I use the single quotation because this is clearly a word, [01:48:10]it’s a clearly a set of words or words that would be in the job title column [01:48:15]as opposed to say organization level, which would have numerals. [01:48:20]So whenever you’re dealing with words or something that is just not standard numerals, [01:48:25]then you want to have your quotation mark surrounding the condition [01:48:30]and then you can close quotation mark. And this quotation mark is a single quote mark, [01:48:35]not to be confused with at tilde, which is an entirely different, um, symbol, right? [01:48:40]So on at least western keyboard you would have the single quotation mark [01:48:45]on the same key as the double quotation mark. [01:48:50]And in SQL we tend to use single quotes and not double quotes. [01:48:55]So when I execute this, now you see nobody has that job title. [01:49:00]So let me, well go back to square once. [01:49:05]I’m going to comment out the word clause. So that’s another benefit to breaking line [01:49:10]because breaking your lines ‘cause I can just comment one line out, run again and then it is marketing assistant not assistance, right? [01:49:15]So you see that it was very specific. [01:49:20]I said that it must be equal to this value. None of them had that value. [01:49:25]So nothing came back with a filter. So now I can uncomment this line [01:49:30]and change my filter and try again. [01:49:35]And now you’ll see that I have three marketing assistance in this entire dataset, right? [01:49:40]So let’s go back, let us try another scenario. [01:49:45]Let me get a snapshot of the data [01:49:50]and let us try two other scenarios where we would want to filter. [01:49:55]Now, I want a specific employee. [01:50:00]Let us say that I wanted the employee who has the business entity ID of 20. [01:50:05]So once again, generally speaking a table has a primary key [01:50:10]which serves as the unique identifier for that record. [01:50:15]And that is usually the easiest, quickest, uh, most effective way to get a specific record [01:50:20]because that value should never be repeated between records. [01:50:25]So anybody with that value is the specific record. So similarly I can say where this column, [01:50:30]which is business entity ID, has the value of 20. [01:50:35]Note, no need for quotation marks because that’s a numeral [01:50:40]and it’s a numeral storing column, right? So I just updated my scenario text, [01:50:45]I’ll comment out that previous one and let us run this new one [01:50:50]and I’m going to get back this specific marketing assistant [01:50:55]who has the ID 20. [01:51:00]All right, so that is working well so far. So generally speaking, [01:51:05]that is how you go about filtering. All you need is a where clause and you can have a condition. [01:51:10]And a condition is not limited to just one column. So I went ahead and I typed out another filter statement [01:51:15]and you can hit pause, replicate it. But I’m going to explain, of course, [01:51:20]in this case I’m saying we’re condition number one and condition number two. [01:51:25]So in this case I want all of the male marketing assistance [01:51:30]from the record set. So you can actually add more [01:51:35]and more conditions to hone in and specify exactly [01:51:40]what you need out of the dataset. So here if I execute this one, [01:51:45]I’m just going to get back this person with business entity ID 17 [01:51:50]who is a marketing assistant who has the gender value of M [01:51:55]and that’s basically it for filtering out and how we would add more and more. [01:52:00]Now there are several other scenarios [01:52:05]and we’re going to look at another scenario for filtering in the next lesson. But while we’re here, let us look at sorting. [01:52:10]So what if I wanted to sort, uh, select all employees [01:52:15]sorted by their employment date [01:52:20]or their hire date, right? So in this case, once again, [01:52:25]we always do our select, I’m just going to do a start to make it simple from, [01:52:30]and then we have the table and the schema, [01:52:35]just copying and pasting to speed this along. But instead of where, [01:52:40]because I’m not necessarily saying I want specific ones, I want everybody, but I only want to see [01:52:45]who has been with the company since whatever time. And you know, [01:52:50]I just want it in that order. So we have the order by statement [01:52:55]that we would add and then we specify the column. So in this case, [01:53:00]the column that I want to order by is higher date and then I can specify the direction. [01:53:05]So let us first look at what happens with the default behavior when we just write statement like this. [01:53:10]So I did a select all ordered by hire date. [01:53:15]Notice that the business entity IDs are all jumbled now. So it’s not just coming from one to the end [01:53:20]because now it is using the hire date to determine who should be at the top [01:53:25]and then the order accordingly, right? [01:53:30]So here, this person has been with the company since 2006, and when you go down to the bottom of the table, [01:53:35]you see that you have the most recent hire according to the database [01:53:40]would be the person who came in 2013. So the default behavior of the order by is what we call ascending order. [01:53:45]You could have also specified that by saying ASC, [01:53:50]so that it knows that that’s the order that it should go in. Now you can also, [01:53:55]and I’ll just comment this line, first duplicate it. [01:54:00]So you’ll notice I love keyboard shortcuts. [01:54:05]So to duplicate, that’s Ctrl C, then Ctrl V to just make a quick copy of it and then Ctrl K, then C to comment this one out [01:54:10]and then I’ll just edit this line to change the ASC to DESC. [01:54:15]So this is the opposite of ascending, which is now descending. [01:54:20]So what would happen is that now the value of the highest would be at the top, right? [01:54:25]So now this would be the newest employee and he would be at the top [01:54:30]and then, or she rather would be at the top [01:54:35]and then the oldest employee would be done at the bottom of the dataset. [01:54:40]And that’s really all there is to ordering. [01:54:45]Um, you can, of course, add more to it. So I could actually specify that, yes, [01:54:50]order by hire date, but then also hire, um, order, sorry, [01:54:55]by the maybe the job title. So you know, we might have had some employees coming on the same day, [01:55:00]but they have different job titles. [01:55:05]Well, that’s not the case here. They’re all same sales reps. [01:55:10]But based on that I could also just say, [01:55:15]um, hire date, DESC. So hire date in descending order, [01:55:20]but job title in ascending order. [01:55:25]And then I can specify more and more columns and the specific order that I would like them to be in [01:55:30]and mix and match and come up with some nice decent representation of the data. [01:55:35]So those are things you can play around with as you extract data, [01:55:40]look at it and make it presentable. In the next lesson, we’re going to look at how we go about filtering using wild cards. [01:55:45]All right. So in this lesson we’re going to be looking at [01:55:50]filtering with wild cards. So we looked at filtering and we touched on sorting for a bit, [01:55:55]but wild cards can get a little bit more technical than the simple filter. [01:56:00]So I wanted to dedicate a lesson where we can actually explore that. [01:56:05]Now, what is a wild card? A wild card means that you don’t know the specific value, [01:56:10]but you want to give some form of pattern that can be used to get, uh, [01:56:15]records that match that pattern. So let’s just jump into it. [01:56:20]I am just going to go ahead and write out the scenario here [01:56:25]and let us say that we wanted to select all employees [01:56:30]who have the word marketing, all of them who are somehow associated with marketing. [01:56:35]And if you look at the dataset that’s here, you see that you do have marketing assistant [01:56:40]and marketing specialist, [01:56:45]and you might also have other kinds of marketing related persons. [01:56:50]Now, instead of you sitting down and trying to figure out the specific ones, [01:56:55]all, all, you know that specific list so that you can say where job title is equal to that one [01:57:00]or ‘cause and means both have to be true or means it, you know, [01:57:05]if this condition isn’t met, then the other one can be as well. [01:57:10]And then you would’ve to say where job title is equal to value number one, or job title is equal to value number two, or et cetera, [01:57:15]et cetera, et cetera. That’s tedious. So I want to select all records with the word, [01:57:20]let me be specific, [01:57:25]marketing in the job title. [01:57:30]So we have our select statement, and I’ll just do star from our table. [01:57:35]And for our work clause, [01:57:40]I’m going to say job title. [01:57:45]And then instead of saying equals, we’re going to say like, [01:57:50]so column is like, and then we specify that pattern that we want to look for. [01:57:55]Now, in this case, I want to know if it contains the word marketing, [01:58:00]not, it may end with it, you know, it could be director of marketing [01:58:05]versus marketing assistant. You know, I don’t know where the marketing is going to fall. [01:58:10]So I’m going to now specify that wild card symbol [01:58:15]that is now wrapped around the word that I’m looking for and it’s ending with that wild card symbol. [01:58:20]So I’m going to run the query first and then we can explore what exactly is happening [01:58:25]with this modular or percentage sign that I’ve added. [01:58:30]So when I run this, you’re going to see that, okay, we filtered out some records and if you look there, [01:58:35]you see that I’m getting about marketing manager, marketing assistant, marketing specialist, [01:58:40]without specifying all three of these and all of the others. [01:58:45]So I was able to just say marketing. So let us get to understand what this wild card is doing. [01:58:50]This wild card symbol is saying, I don’t really care, whatever it is, [01:58:55]whatever might be in the text, right? But look for this word [01:59:00]and whatever might be after the word. So I don’t care what is before the word [01:59:05]and what is after the word in the string. I’m just looking for this, right? [01:59:10]So this is a nice way to just say, all right, [01:59:15]ignore the noise around the real focal point of what I’m searching for. [01:59:20]That’s, that’s one way of putting it. So let us say that I wanted to do something similar. [01:59:25]I’m going to write a scenario, let’s just run the query. [01:59:30]And I wanted to see anybody whose job title has started with manager. [01:59:35]Uh, well, I don’t think anybody’s job title starts with manager, [01:59:40]but what I would do is actually remove one of the symbols. [01:59:45]So I’m starting off with an empty string, then I’m going to say the word that I’m looking for. [01:59:50]Then I’m going to say wild card, meaning ignore anything that comes after the word manager. [01:59:55]I don’t care what comes after the word manager as long as the word manager is there, but then that’s the start of the string. [02:00:00]There’s no wild card here so it’s not going to ignore what comes before manager. [02:00:05]It’s going to start looking for a string that starts with manager [02:00:10]and then once it finds that it starts with manager, it won’t care about what comes after the word manager. [02:00:15]It just means that I have looked for something that starts with this string pattern. [02:00:20]So if I execute this one, nobody’s job title starts with manager. [02:00:25]All right, that’s fine. [02:00:30]But what if I wanted to find anybody whose job title ended with the word manager [02:00:35]regardless of what comes before it. So then all we do is flip around the position of that wild card token. [02:00:40]So right there [02:00:45]I’m simply saying I don’t care what might be at the first few words [02:00:50]of this string as long as manager is the last thing in the string. [02:00:55]And then if I do this one, then we’re going to get back engineering manager, [02:01:00]research and development manager, marketing manager. [02:01:05]So it doesn’t matter what came before the word manager, it’s just going to look for anything that ends with manager. [02:01:10]And just the same way if we wanted maybe manager word might end up in the middle of the string [02:01:15]then we want to wrap that with the wild card. [02:01:20]So this concept can take a bit of practice but just, just look at it like this. [02:01:25]When the wild card precedes [02:01:30]and comes after the string that means we’re looking for anything that contains. [02:01:35]All right, so let’s just say it contains that string. [02:01:40]If the… If you place the wild card after that string, [02:01:45]then you’re looking for anything that starts with. And then if you place the wild card before the string, [02:01:50]then you’re looking for anything that ends with. [02:01:55]So that’s, that’s a nice and easy way to just remember how that wild card can be used. [02:02:00]Now we’re going to move on to going back to our column manipulation [02:02:05]where we may want to specify better names or alternative names [02:02:10]for the columns that come back as opposed to the ones that are there in the… in the database table. [02:02:15]So see you in the next lesson. Welcome back. In this lesson, [02:02:20]we’re going to be looking at aliasing columns. Now, the context for why we would want to alias columns [02:02:25]is that sometimes columns are not very human readable [02:02:30]or you know very friendly. So business entity ID [02:02:35]that really means nothing to some people. National ID number [02:02:40]with the camel casing that can be a bit difficult for somebody with an untrained IT eye to read. [02:02:45]So as somebody who is manipulating data [02:02:50]and producing a report you want to make sure that these column headers [02:02:55]are readable for whoever will consume it whether they are IT centric or not. [02:03:00]So the concept of aliasing the column means that we actually get to rename the column. [02:03:05]And we saw in our previous example where we could actually [02:03:10]specify the columns that we wanted. And we actually looked at the fact that when we wrote a lowercase j [02:03:15]that the display actually came out with a lowercase j. [02:03:20]And that whatever the casing was that we used here that was a casing that came back. [02:03:25]So now what we want to do is be able to select these same columns but actually put spaces safely [02:03:30]in those column names. [02:03:35]So let us just reuse this previous example. And I’m just going to say select data [02:03:40]with aliased columns. That is our activity. [02:03:45]And we’re reusing this query. And I’ll just paste it and uncomment it. [02:03:50]Ctrl K and U to uncomment. And let us run the query and make sure it still works. [02:03:55]And there we have our data. So we see that we have login ID, [02:04:00]we have job title and we have the hire date. But once again [02:04:05]I want these columns to look a bit more friendly. So I’m just going to break the line [02:04:10]so that we can see exactly where everything starts and stops. [02:04:15]And I’m just going to kind of indent the columns. There we go. So select these columns from that table. [02:04:20]All right. Now the alias are common. It’s very easy. [02:04:25]And you have two methods of doing it. You can use the keyword as [02:04:30]and then you would give it another name. Now, if you want to assign a name that has a space in there, [02:04:35]then you definitely need to use your square bracket. [02:04:40]So I would say login ID, right? Or it could be sign on. [02:04:45]Sign on ID, right? Whatever it is, but as long as you wrap it [02:04:50]in the square brackets then you’re fine. Without the square brackets, it will try to parse it. It will try to figure out is this a keyword. [02:04:55]What does this mean? What’s that hyphen? [02:05:00]What is ID? Right? So you definitely when you’re writing your custom names, [02:05:05]always just wrap them in square brackets. Also anybody who comes and inherits this [02:05:10]script from you would be able to see the square brackets [02:05:15]and be able to deduce that this is an alias as well. Now, you can use the as keyword [02:05:20]but you also don’t have to use the as keyword, but the square brackets are still required. [02:05:25]So I can say job title in just square brackets and you’ll see there’s no error. [02:05:30]So whether you use the as keyword or not the fact is that you can alias using the square brackets [02:05:35]and whatever word alphanumeric combination you need to use in there. [02:05:40]So I’m going to do the same thing for higher date. [02:05:45]And then when I run this, now you’ll see that the column headings [02:05:50]are much easier on the eye, much easier to read and they make a bit more sense [02:05:55]especially when you’re going to presenting this to a manager. [02:06:00]And I keep on saying, okay, presenting this to a manager, later on we’re going to look at how you can actually export the data [02:06:05]into an Excel format and actually send off to somebody. [02:06:10]But for now we know how to alias our columns. When we come back, [02:06:15]we’re going to look at how we can do joins because sometimes [02:06:20]like we would have explored before the data that we need [02:06:25]on a person or on a particular entity is actually spread across several tables and it is made reference to. [02:06:30]So when we come back, we’re going to look at how exactly we look in different tables [02:06:35]and then combine all of that data into one display. [02:06:40]Welcome back, guys. In this lesson, we’re going to look at how we select [02:06:45]data from multiple tables and combine them into one display. [02:06:50]In this context I already wrote the scenario so that we can get into it. [02:06:55]We’re going to select employees and the departments that they represent. [02:07:00]Now, if you look at the tables, so far we’ve been looking at HR employee, [02:07:05]human resources dot employee and that is where we’ve been getting the actual data about the person, their job title etc. [02:07:10]However, if you look closely you see that you also have human resources dot department [02:07:15]and you also have employee department history. [02:07:20]Now once again I’m not getting into normalization and how foreign keys work too, [02:07:25]in too much detail but generally speaking when you want to break up data [02:07:30]so that you can repeat fewer details across multiple tables, [02:07:35]that process is called normalization. And then as a result of normalization, [02:07:40]you end up with well, yes, multiple tables as well as foreign keys [02:07:45]between the tables. So it is up to you as the data analyst [02:07:50]the person manipulating the data once again to be able to assess the different tables, [02:07:55]to see the different data and figure out what the foreign key relationship column might be [02:08:00]and then that is what you’re going to use to be able to join the tables. [02:08:05]So we’re going to do some quick queries here [02:08:10]and I’m going to show you guys a shortcut that I haven’t shown you before. You probably already figured it out, [02:08:15]but if we want to see all the employees without writing out the statement, we can actually just right click here in the Management Studio [02:08:20]and we can just say select top 1000 rows. [02:08:25]That generates the same kind of select top query that we looked at earlier [02:08:30]and it will actually give us the data and because I highlighted that while I was executing it, [02:08:35]stopped, there we go. So at a glance I can see, okay, these, [02:08:40]that’s what the employee data looks like. Now, if I look at the department data. [02:08:45]Now, when we look at the department data, [02:08:50]we see that this is simply a list of departments and their names [02:08:55]and when they were last modified and that’s fine, but when I’m looking at the data I’m not seeing anything [02:09:00]that would connect the department to an employee. [02:09:05]However, once again here’s another table that says employee department history [02:09:10]and this is where naming becomes very important. Just by the name, [02:09:15]I can assume or safely assume that this table will contain data about both the employee [02:09:20]and the department. So when I look in this table, [02:09:25]I would expect to see that there’s something here that would be able to link to the department [02:09:30]and link to the employee and once again naming convention but also analysis. [02:09:35]So if we look at this closely, we’ll see that there’s a department ID column. [02:09:40]This department ID column suggests to me that this is a foreign key [02:09:45]to the department ID table. Sometimes, once again, [02:09:50]when you’re naming your columns, you might name it table name ID [02:09:55]or just ID and the assumption is that it’s already in the table. [02:10:00]Whichever naming convention works for you, but generally speaking with the foreign key would take the naming convention of the table name [02:10:05]and ID that it is to link to. [02:10:10]So here I can safely assume that this department ID is the foreign key relationship column [02:10:15]to the department ID in the department table. [02:10:20]So I can use those two to join the data. However, I have to do a bit more digging [02:10:25]or analysis now to figure out how do I show that this record relates to an employee. [02:10:30]Well, I have business entity ID [02:10:35]and then if I look back in the employee’s table, there’s also business entity ID. [02:10:40]So here I can now safely assume that this business entity ID [02:10:45]is associated with this one. Now, it’s not as clear as department ID to department ID [02:10:50]because business entity ID doesn’t necessarily scream employee. [02:10:55]However within the context it is also a safe assumption. [02:11:00]So I just wanted to quickly go through this exercise with you and we’re not going to write any code just yet. I just wanted to kind of break down [02:11:05]how data might get spread across multiple tables [02:11:10]and the techniques that you need to apply in analysis to figure out [02:11:15]how exactly you’re going to figure out what should link to what. [02:11:20]So now that we have a clear path as to the columns that we need and the different tables that we need. [02:11:25]When we come back, we’re going to continue with our scenario. [02:11:30]All right. So let us start off this exercise and we’re going to be looking at several things in this exercise. [02:11:35]One we’re going to look at selecting from multiple tables in one display, [02:11:40]aliasing our tables, and I’m going to show you guys some shortcuts, [02:11:45]so that you can be a bit more productive along the way. All right? [02:11:50]So far when we wrote our queries we would write them from scratch, select star from and then try to write all the tables. [02:11:55]Well, in this case, I’m to show you that you can actually drag and drop. So we’re going to select and I’m going to leave star for now and say from. [02:12:00]Now I know I need HR. I’m just going to say HR, [02:12:05]but when I say HR I mean human resources. So we need HR dot employee. [02:12:10]So instead of typing this all from scratch I can actually just drag it over [02:12:15]and look at that. All right. So you can practice that if maybe you prefer to use the most than to type from scratch, [02:12:20]that’s fine. Remember that you could also just copy and paste, [02:12:25]but once again productivity find the rhythm that works for you. So we already are familiar with the select star from human resources. [02:12:30]Sorry, yeah, human resources dot employee. [02:12:35]Now, what we need to do is join this [02:12:40]to the employee department history table. [02:12:45]Why are we joining these two? Once again these two have columns in common. [02:12:50]So that’s what I like to say they have columns in common. [02:12:55]So we can join them based on the columns in common. [02:13:00]That means that anything that is business entity ID1 will now [02:13:05]be directly linked to the same row or the row in the next table with the same value. [02:13:10]So 1 will be linked to 1, 2 will be linked to 2, 16 will be linked to 16. [02:13:15]You see that you have 16 several times because this is a history table. [02:13:20]So this person more than likely started off in one department [02:13:25]and moved to another one eventually but it’s the same person. [02:13:30]Which means that if we look back over here, we know that this marketing manager [02:13:35]would have moved departments at some point. All right? [02:13:40]So once again just giving context. So we need to link business entity ID table [02:13:45]to business entity ID having table. So over in our query I’m going to introduce a new keyword [02:13:50]or new keywords and this one is going to be called inner join. [02:13:55]So that’s a keyword to say that I wish to join this table with another table. [02:14:00]So the other table will be human resources [02:14:05]dot employment department history. [02:14:10]So here the statement once again, and I broke the line so it could be a bit more readable [02:14:15]but once again from left to right would be select all from this table with an inner join [02:14:20]onto that table. Then we need a condition. [02:14:25]So I need to say on and then the condition is that the column [02:14:30]that the column that they both have in common have the same value. That’s the condition. [02:14:35]So business entity ID from this table must have the same value as business entity ID [02:14:40]in that table. [02:14:45]Now, it is a mouthful to write this out. It can be difficult to write this out and it gets very messy [02:14:50]because I’m going to have to say table dot business entity ID [02:14:55]is equal to and then the next table and you see this is long [02:15:00]and it’s becoming very confusing as I’m typing this out. All right? [02:15:05]So and if I was to make this a bit smaller, [02:15:10]it would be easier on the eyes and you’d see it a bit better. Well, I don’t know if you’d see it a bit better, [02:15:15]but it would be a bit clearer that everything here is one line. So we’re joining this table [02:15:20]on the condition that the HR dot employee [02:15:25]dot business identity business entity ID, sorry, [02:15:30]column is equal to HR dot employee department history [02:15:35]dot business entity ID and that can be very difficult to type out. [02:15:40]So here’s where I’m going to introduce the technique of aliasing tables [02:15:45]and this is where it becomes very, very useful. We can actually just the same way we aliased our columns earlier, [02:15:50]we can actually alias our tables as well. [02:15:55]So for short instead of typing out human resources dot employee, [02:16:00]I can actually just say as EMP. All right? [02:16:05]So now within the context of this query anytime I want this table, I no longer call it by its right name. [02:16:10]I’m going to call it by its short name and that is why this red line appeared [02:16:15]because now this name is no longer the name that it identifies by. [02:16:20]So I have to say EMP and that can help me to reduce the amount of typing. [02:16:25]So the same way for employee department history, [02:16:30]I can call this one HIST for short and then wherever I need it elsewhere in the query [02:16:35]I just use HIST and that would have shortened it. [02:16:40]So now when I zoom back in, it’s I guess a bit easier on the eyes [02:16:45]so to speak to read, [02:16:50]but I’m sure that you can see the value of aliasing the table. All right? [02:16:55]So now we have select star from and then this table which identifies as EMP [02:17:00]and we’re inner joining it on human resources employment history [02:17:05]which identifies as HIST and then on the condition [02:17:10]that emp dot business entity ID has the same value [02:17:15]as HIST dot business entity ID. [02:17:20]Now when I select that this is what we end up with. So between this column to this column, [02:17:25]all of those data points represent the employee table. [02:17:30]And then if you look to the right of that, you’ll see now we have similar data coming [02:17:35]from the employment history table and here’s our 16 repeated, right, [02:17:40]16 is repeating. [02:17:45]And you’ll see here that department ID for 16 is different in the two spaces, [02:17:50]so that means this person moved from department 5 to department 4 at some point. [02:17:55]All right? So now department ID means nothing to me, right? [02:18:00]I don’t know what department ID is. [02:18:05]So what we want to do is actually bring back the actual name of the department, [02:18:10]so we can see what departments this each person is in and what department in this, [02:18:15]in particular, sorry, this person moved from and to. [02:18:20]So what are we going to do? Well, if you said inner join another table, [02:18:25]then you’re absolutely right. So there is no real limit to the number of tables [02:18:30]that you can inner join and the fact is that as many tables as it takes to get the data, [02:18:35]you may need to do that and that’s one of the downsides of normalization. [02:18:40]While it helps to optimize storage, it is not very good for retrieving data, [02:18:45]but we have to do what we have to do to maintain proper database design. [02:18:50]So we’re going to inner join again and this time and I’ll just kind of keep the line breaks [02:18:55]so that we can keep the same form factor. I’m going to inner join [02:19:00]and I’ll just bring over the department table and guess what? I don’t want to write this out, [02:19:05]so I’m just going to say dep, so that’s the short name for the department table on the condition [02:19:10]that dep dot department ID is equal to [02:19:15]and remember that you are joining tables that have columns in common. [02:19:20]So department ID is in both the department table [02:19:25]and the employee department history table, it is not in employee table, [02:19:30]so I can’t directly join department onto employee [02:19:35]because they have nothing in common. These two have something in common which is the department ID, [02:19:40]so dep dot department ID is equal to HIST dot department ID. [02:19:45]Now, when I execute this query [02:19:50]the dataset just got a little longer, so here to here employee, [02:19:55]we know that already and then we can say here to here is department history. [02:20:00]And then guess what? The rest is department. [02:20:05]So you see as many tables as you join the list just gets, well, [02:20:10]the left to right data points just get more and more and especially since we’re selecting star. [02:20:15]So when we select star, it’s going to select star from employee, [02:20:20]star from every other table that is being joined. All right? [02:20:25]So beware of that. Now, that we have our data and we can see, you know, [02:20:30]everything that we need to see within the context of this activity [02:20:35]and here we see that this person moved from purchasing to marketing, right? [02:20:40]So that’s employee with the ID 16, moved from purchasing to marketing. [02:20:45]So now we’re starting to see the meaningful data points [02:20:50]that we can actually use to create a report so when we get to this point and we see all of the data, [02:20:55]then we want to refine our query, so we want to replace that star [02:21:00]with the actual columns that we want. Now let us say that I wanted job title, right? [02:21:05]And while we’re looking at aliasing, [02:21:10]we can always make it out to be more presentable. [02:21:15]We also want their hire date and I’m just making this up as I go along, right? [02:21:20]So I have no real method to do to my thoughts, right now I’m just picking out data points [02:21:25]that I think would be relevant for this kind of activity, [02:21:30]and I want to see if they are salaried. Let’s say salary flag, [02:21:35]salary flag and, um, paid, [02:21:40]employee right? So that is, that is the column name I want, [02:21:45]so like I said you can type any column type of column name as long as you wrap it in the square brackets. [02:21:50]So we have job title, we have when they were hired we have, [02:21:55]if they are salaried and I want to see their department, [02:22:00]so I’m going to say name. [02:22:05]Now, note that sometimes names or columns repeat [02:22:10]across the different tables, right? [02:22:15]So in this case we don’t have name repeating but name is a very common column that you may end up repeating across multiple tables [02:22:20]that you end up joining anyway. [02:22:25]So just the same way that we had to specify the table alias dot the column [02:22:30]and table alias dot the column because if we didn’t do that [02:22:35]you would actually complain about it being ambiguous, right? [02:22:40]Ambiguous column, because it’s seeing one big dataset [02:22:45]and multiple department IDs so which one is it that you want me to select, [02:22:50]should it be from this table or from that table, right? So it’s very important [02:22:55]to prefix that column name with, if not the table name then the table alias. [02:23:00]So just to drive that point home sometimes name will appear multiple times, [02:23:05]so it’s important to say something like, uh, this would be the… [02:23:10]I’m sorry, I’m just looking back. This would be the dep, [02:23:15]so dep dot and then we say name just to make sure that we know which name column [02:23:20]or which column it is but our alias has to be very explicit department, right? [02:23:25]So anybody reading it would know that [02:23:30]whatever word they see here represents the department. [02:23:35]And I think that this is good enough, let’s run that and look at our nicely cleaned up. [02:23:40]There we go, nicely cleaned up dataset. So now we’re seeing everybody’s job title [02:23:45]when they were hired, if they’re paid and the department. [02:23:50]Now, this could be useful, it could also use a bit more information. So my challenge to you now [02:23:55]is to look through the other tables, figure out where you could find maybe the person’s name, [02:24:00]the employee’s name, right? And join on that table and add their name to this query. [02:24:05]But for now, at least you understand the concept of how to join data. [02:24:10]Now, you do have different kinds of joins. [02:24:15]Right now we’re doing the inner join which is the simplest of them all, [02:24:20]but you do have the concept of a left join and a right join. So in the next lesson, we’re going to look at how the left join differs from the inner join. [02:24:25]Welcome back, guys. [02:24:30]In this lesson, we’re going to be looking at left joins and we’re going to be looking at how we can even mix [02:24:35]and match our joins, and why we would need to consider mixing and matching them. [02:24:40]To accomplish this, we’re going to move away from our human resources schema, [02:24:45]and we’re going to go over to production. [02:24:50]So in this scenario, we want to select work orders the product that the work order was done against and then their scrap reason. [02:24:55]So once again we always want to start off with our analysis. [02:25:00]We want to see the different tables, how they’re interconnected, [02:25:05]what data is available to us and then we can make our decisions. [02:25:10]So using the quick query, uh, where we just right click and say select top 1000. [02:25:15]I was able to look at the products. So here in the product table we see, well, [02:25:20]the details of the products, right? Adjustable race, etc, [02:25:25]so we can see that these are the products up to 500 products are in the database, and that’s fine. [02:25:30]Then we can look at the scrap reason. [02:25:35]We did say we wanted to see the scrap reason. We see that it’s just a metadata table, [02:25:40]meaning it’s just a list of reasons with an ID and a name and a modified date. [02:25:45]So nothing too fancy going on here. [02:25:50]But then we’ll go to the work order table. We see here that we have, yes, a work order ID. [02:25:55]We also have a product ID, so that means this work order is relative to a product each work order entry [02:26:00]is relative to a product. [02:26:05]So one product could have had many work orders done against it, [02:26:10]and you also see here that there’s a scrap reason ID. Most of these are null however, [02:26:15]and then you may see that maybe there’s a scrap reason in some of them. [02:26:20]So in joining these tables, we need to consider what might be null [02:26:25]versus what would never be null [02:26:30]because you can’t have a work order without a product, right? So let us start off. [02:26:35]So product would be the root of it all, so I’m going to say select star from [02:26:40]and I’ll just drag over that product table. So now we have all the products, that’s fine. [02:26:45]If we want to, we can actually start refining the query from here. [02:26:50]So I could just call this prod from right here alias it [02:26:55]and then break down exactly which columns I want from prod. So I can say I want prod dot name, right? [02:27:00]I could also say maybe I want prod dot product number. [02:27:05]And I think I’ll just do that for now with prod. [02:27:10]I don’t need any other detail for the context of this query, [02:27:15]so I know the name and I know the product number. [02:27:20]Now, I started refining the query, but I still don’t know really what data points I need, [02:27:25]so I can always jump back over to the other query windows, [02:27:30]so I know about products, now I can close this one. [02:27:35]Now, I am looking at scrap reason and there’s no, nothing from scrap reason to product. [02:27:40]I can’t link scrap reason directly to product, So I’m not going to focus on that one just yet, [02:27:45]but then I see in work order that there’s a product ID and I can see each work order done against products. [02:27:50]So going back to what we just learned. Now, we’re going to inner join [02:27:55]the work order table and I’ll just drag that one over [02:28:00]and I’ll just call this one WO, work order [02:28:05]on the condition that WO dot product ID [02:28:10]is equal to prod dot product ID. [02:28:15]Once again, when you have the same column present in multiple tables [02:28:20]it can be ambiguous if you don’t precede it with the table name or the alias of the table. [02:28:25]All right? And once again aliasing makes this part of the query much easier to write. [02:28:30]So now when we do this and I run again. [02:28:35]Well, I’m only seeing prod name and product number. [02:28:40]I’m not selecting anything from work order, so obviously I would want to see certain details from the work order [02:28:45]and so the details I would want to see are maybe the ID, [02:28:50]work order ID, the order quantity and stocked quantity. [02:28:55]So let’s do that one. [02:29:00]So WO dot order quantity and WO dot… [02:29:05]What was the other one that I said? We wanted stocked quantity [02:29:10]and WO dot ID, work order ID. [02:29:15]And I’ll actually put this one at the top. All right? [02:29:20]So now we have product and I’m missing a comma. [02:29:25]Do remember your commas very important in the syntax. [02:29:30]So now I’m selecting all of those and do remember not to end with a comma, right? [02:29:35]So let me run this query and now we’re seeing the name of the product, [02:29:40]the number, the work order, the order quantity, the stocked quantity. [02:29:45]All right? Then, the final thing we want is a scrap reason. [02:29:50]Now, I don’t want to see a scrap reason ID because this means nothing to me, right? [02:29:55]In, in the grand scheme of things seeing 7 and 11 don’t mean anything. [02:30:00]So instead of showing 7 and 11, I want to actually show the actual data, [02:30:05]if it is present, which would be the actual name. [02:30:10]So that means I need another join, correct? However, I can’t use an inner join [02:30:15]because it’s going to want to make sure that the data can be found on both sides, [02:30:20]and that’s what inner join means. So I’m going to do an inner join and show you why it would be a bad idea [02:30:25]to use the inner join, right? So we’re going to inner join [02:30:30]on scrap reason, and I’ll just call this SR [02:30:35]on SR dot scrap reason ID, [02:30:40]and which table also has scrap reason ID? Work order. [02:30:45]So it’s going to be is equal to WO dot the same column, scrap reason ID. [02:30:50]Now note, I have 72,591 rows [02:30:55]coming back from this query. All right? [02:31:00]So just the query that I ran earlier, where we joined the production work order [02:31:05]on the production product table, we got 72,000 columns, [02:31:10]ah, rows, sorry. [02:31:15]Now, when I run this one with the inner join on scrap reason, that number is going to dramatically fall to 729. [02:31:20]All right? And let me just add the SR dot name. [02:31:25]Once again, name, name. [02:31:30]Be very clear which name you are referring to. All right? [02:31:35]So here I see only 729 rows. Now this would imply [02:31:40]that there were only 729 work orders, right? [02:31:45]And that is where the data can get skewed. The reason for this, once again, [02:31:50]is that the inner join is checking to see that these two values are equal, [02:31:55]which means that whatever is in the scrap reason ID, on the scrap reason table [02:32:00]must match what is in the scrap reason ID on the work order table, [02:32:05]which we know may not be the case because in the scrap reason table, [02:32:10]this is never null. But in the work order table, there are several nulls. [02:32:15]So what this is doing is actually eliminating every row that is null, [02:32:20]because null is never equal to a value. [02:32:25]So this one comes back, this one comes back, and all of these are ignored, [02:32:30]which we don’t necessarily want. So that is where we have the left join. [02:32:35]So a left join basically says, so instead of inner, we say left join. [02:32:40]And the left join would say, give me everything on the left. [02:32:45]And if you can find values on the right, [02:32:50]then bring them back. Now you’re probably wondering what I mean by left and right. [02:32:55]So I’m going to have to zoom out again and show you a statement in one line. [02:33:00]So literally, a left join says what table is to the left. This is the table to the left of the join statement, right? [02:33:05]Because directionally, this is your left, right? [02:33:10]So inner join means look at both. So that’s like in math, we would say an intersect, [02:33:15]whereas the left would be more like a complement, right? [02:33:20]So give me everything to the left. [02:33:25]And if you can match to the right, then fine. So everything in the left [02:33:30]and try and match with what is on, with the records in this table that meet that condition. [02:33:35]If you can’t match, that’s fine. Still bring it back. [02:33:40]If you do match, then you will see the details. So now when I run this, I’m supposed to get back 72,000 rows, [02:33:45]but some of them will just have null because I was unable to match it. [02:33:50]So the name of the scrap reason here is null. [02:33:55]And then where there is a scrap reason, I can see it. [02:34:00]And that is how left joins work. And really and truly, like I said, it’s directional. [02:34:05]So a right join would just be the opposite. So the right join just means bring me everything back from here. [02:34:10]And if you can match it with what’s on the left, [02:34:15]directionally for me, at least I always use a left because it just feels more natural, right? [02:34:20]But you can decide which one you want to use. [02:34:25]And that is really all there is to the left join and right join. And then, of course, you’d want to clean up your columns because you have two columns called name and name. [02:34:30]So I’ll leave that to you for your activity. [02:34:35]Go ahead and clean up those column names and make sure that they represent what the data [02:34:40]in the actual column is. And I hope you got a better understanding of the left join. [02:34:45]It does take practice and it does take intuition [02:34:50]and analysis to know when to use which. Generally speaking, however, [02:34:55]you can always rely on the left join to bring back all the data anyway. [02:35:00]So you can’t go wrong, generally speaking, just using left join all the time. [02:35:05]But in specific situations, maybe you really just want to see the work orders [02:35:10]that have a scrap reason, and then you would want to use an inner join. [02:35:15]So it’s good to understand them and it’s good to know when to use them. [02:35:20]When the boss is telling me all the work orders that have a scrap reasons, then you inner join through and through [02:35:25]and you have 79, 729, sorry, work orders or records rather with actual scrap reasons. [02:35:30]And that is how you go about joining records, [02:35:35]even when the condition might not be met on both sides. [02:35:40]Next, we’re going to look at the union and union all operations. [02:35:45]Welcome back, guys. In this list, we’re going to be looking at union and union all. [02:35:50]Now, the union command [02:35:55]is used to join two different datasets from two different tables into one contiguous dataset. [02:36:00]What does that mean? We already looked at how we join data points [02:36:05]for a record across several tables. And that’s when we use our inner join or a left join or right join. [02:36:10]So when we want to see more details about a particular record, [02:36:15]when the details are in other tables, then we use joins. [02:36:20]However, let us say that one table gives us all the details on a certain entity or entity type. [02:36:25]And then another table has similar details on another entity type. [02:36:30]And we just want one big dataset of everything to be printed out. [02:36:35]That’s where we would want to union the two different datasets. [02:36:40]So here I have the example and I kind of wrote out some of the queries already. [02:36:45]And I’m going to walk you through exactly what we’re doing. So the scenario is that we want to select all customers and employers… employees, sorry, [02:36:50]into one dataset. [02:36:55]Now, the context for this, let me make this a little bigger so that we can make sure that we can see, [02:37:00]is that we have been looking at the human resources dot employee table. [02:37:05]And if I execute this one, you’ll see here, yeah, we get details about somebody [02:37:10]who we can safely assume is an employee, [02:37:15]but we don’t know much about them in terms of personal data. Now, there are other tables here. [02:37:20]There’s one called person dot person under the person schema. [02:37:25]And there’s another one, another one called sales or customer. [02:37:30]So under the person schema, if we were to look in the person table, [02:37:35]we would notice that we have several persons, 19,972 persons to be exact. [02:37:40]Now, based on what we’ve gone through with the employee table, [02:37:45]we can see that there are roughly 290 employees. [02:37:50]And then if we look in the customer table, we can see that there are 19,000 [02:37:55]and some employees. So for this example, we’re going to be manipulating our data a bit to make sure that [02:38:00]we get a dataset that we can union [02:38:05]from these three tables. [02:38:10]So let’s get to it. So these are the individual select queries. I don’t necessarily need these going forward, [02:38:15]but I am going to reuse some of the join techniques. So what do I want? [02:38:20]I want, let’s say, just the first name. So I’m going to say I want person dot first name. [02:38:25]And I want that from, [02:38:30]and let’s just start off with the employees’ tables. [02:38:35]Now, obviously, I can’t get person dot first name from the employee table. [02:38:40]So what do I need to do? If you said join, [02:38:45]then you’re absolutely correct. I need to inner join on the person table [02:38:50]on the premise that, and I’m just going to go ahead and shorten my table names with aliases. [02:38:55]So person is now per and employees now EMP. [02:39:00]So it’s going to be EMP dot business entity ID [02:39:05]is equal to person dot business entity ID. [02:39:10]So now I will be able to see [02:39:15]all the first names of all the employees. We couldn’t see that before [02:39:20]because we needed to join onto the person and that’s fine. Now I’m going to do something similar, [02:39:25]but for the customers, I want to see all the first names of the customers, right? [02:39:30]So I’m going to say, give me cost or rather per that first name as well, [02:39:35]because I can only get first name from the person table, [02:39:40]but I’m selecting from sales dot customer, and I’m just going to call this one cost. [02:39:45]And I’m going to inner join [02:39:50]on person called per, right? [02:39:55]So I’m copying and pasting to go faster. And you see, I’m actually kind of breaking my own rules [02:40:00]about using all caps just to display the keywords. [02:40:05]But I think by now we know the keywords, so that should be fine. [02:40:10]But I’m going to say per dot, and then the primary key, once again, is business entity ID. [02:40:15]And here’s where data analysis comes into the picture, because if you look at the sales dot customer table, [02:40:20]there is no business entity ID column here. [02:40:25]The only column that could possibly be a link to the person table would be person ID. [02:40:30]So sometimes when we’re doing a join, [02:40:35]the column names don’t match evenly, right? [02:40:40]So in our previous example, we saw product to product, scrap reason to scrap reason. [02:40:45]In this case, we saw business entity to business entity ID. [02:40:50]And now we’re going to see that business entity ID has to be inner joined onto customer dot person ID. [02:40:55]So once again, it’s very important to analyze the data [02:41:00]and the tables that you’re working with. Now I can execute both select queries simultaneously, [02:41:05]and that will result in two distinct dataset areas in the results pane, right? [02:41:10]So top would be the employees, [02:41:15]and below would be our customers. Now what do I want to do? [02:41:20]I want everything to be in one contiguous dataset. [02:41:25]So like I said, this is one result pane by itself, and this is one result pane by itself. [02:41:30]But I want to be able to just export everything all at once. So that is where we have union. [02:41:35]So when you have two select queries that are selecting basically the same data points, [02:41:40]they have to be the same data points as in the same columns going across, [02:41:45]then you can simply stick a union in between them. [02:41:50]And once you say union, what it will do is join everything into one big dataset. [02:41:55]All right? Now, please note, let’s look at the numbers. [02:42:00]Um, we have union, and we have the concept of union all. [02:42:05]And I’m going to show you why you may use one and not the other. [02:42:10]Now, when we look at the customers, we have 19,000 records [02:42:15]from this one query. [02:42:20]And then, of course, we know that we have about nine, okay, 200 employees. [02:42:25]But when I select everything with a union, I only end up with 936 rows. [02:42:30]So why is it that I’m reducing, [02:42:35]I’m reduced from the 19,000 here to just 936? [02:42:40]Well, what union does is, and that’s part of the reason I’m only using one column, [02:42:45]which is first name, several people may end up having the same first name. [02:42:50]And, of course, we can expand this. But remember that the union only works when you have the same columns [02:42:55]being selected from both queries. So whatever data points you add [02:43:00]have to be present on both sides. But my point here is that [02:43:05]because we’re using first name by alone, the first name may repeat. [02:43:10]So if you have several Johns, several Jones, several Forests, etc, [02:43:15]the union is actually just going to discard the duplicates and only bring back one. [02:43:20]So here we see that yet out of the 19,000, [02:43:25]there were several duplicates, probably and even worse when we joined onto the, [02:43:30]or when we unioned with the employees, there were even more duplicates. [02:43:35]So the union just says, okay, discard the duplicates and bring back the distinct values. [02:43:40]And we ended up with 936. Now let’s look at union all. [02:43:45]Union all in contrast to union is going to bring back everything. [02:43:50]So now we’re ending up with 19,000 and more than just the customers. [02:43:55]And that’s because it’s actually joining everything here with everything here. [02:44:00]And it is not taking it on its head to try and figure out what is a duplicate or not. [02:44:05]It is just saying, I’m going to join everything that came back. [02:44:10]So union will discard duplicates and union all brings everything back. [02:44:15]So once again, just know when to use them based on your situation [02:44:20]and how best to manipulate your data. So you can use a union when necessary. [02:44:25]Welcome back, guys. In this lesson, we’re going to be looking at the concept of grouping, [02:44:30]and we’re going to run a contrast with the concept of selecting distinct. [02:44:35]So I would have used the word distinct in the previous lesson, [02:44:40]where I mentioned that the union will actually bring back the distinct values from a dataset, [02:44:45]meaning it eliminates the duplicates. And that’s exactly what distinct does. [02:44:50]Now, you may not need a union, but you want to be distinct and in a select query. [02:44:55]And I’m just reusing the same select query that we used previously for our customers. [02:45:00]When we’re using this kind of query [02:45:05]and we have the risk of having duplicate values, [02:45:10]then we can easily say distinct before we start listing the columns. [02:45:15]So what this keyword does is it says when you’re selecting the data and the columns, [02:45:20]please look if you have any two columns that look the same way [02:45:25]with the same set of data. If you end up with that, then you can discard it. [02:45:30]And that’s, that’s all distinct does. So if you realize that when you’d run a select query, [02:45:35]you’re ending up with duplicate values and you want to eliminate them quickly, [02:45:40]you can easily use a distinct keyword and your query will be cleaned up. [02:45:45]So we know that without the distinct, we should get back over 19,000 records. [02:45:50]But look at when we introduce the distinct. [02:45:55]Now we only get back 871 rows. And note that distinct really works relative to the columns. [02:46:00]So the more columns you put in and the more variations of the data [02:46:05]obviously is the less distinct the data becomes. [02:46:10]So first name, it’s easy to eliminate all of the Scots, but then you may have several Scots with different last names as well. [02:46:15]So if I was to put in per dot last name as well and run that, [02:46:20]then that number is going to increase because now you have several Aarons [02:46:25]who have several last names. [02:46:30]So it’s very important that you make sure that you’re getting back the correct data because prior to this, there was only one Aaron coming back. [02:46:35]As far as the dataset was concerned, there was only one Aaron on here. [02:46:40]While we’re in the mode of writing more complex squares, [02:46:45]let me throw on an order by. So I’m going to order by the column first name. [02:46:50]And by default, it will be ascending, [02:46:55]so Aaron is at the top. So like I said, Aaron only came back once [02:47:00]because distinct was eliminating the duplicates. [02:47:05]Now, I am adding on a variation to this duplicate to this dataset, sorry. [02:47:10]So now, Aaron is no longer seen as a duplicate [02:47:15]because distinct also has to take into consideration the last name. [02:47:20]So Aaron Adams is different from Aaron Alexander, et cetera, et cetera. [02:47:25]However, all Aaron Alexander’s, all the duplicate ones have been eliminated because you see, [02:47:30]we’re still not bringing back the full complement of the data that we would have seen prior to putting in our distinct. [02:47:35]So now that we see how distinct works, let’s look at the group by [02:47:40]or the group by does a similar function, but it adds a bit more functionality [02:47:45]and usefulness to the data after it eliminates the duplicates. [02:47:50]So when we do a select query, and I’m just going to duplicate this select query, [02:47:55]so I don’t have to retype it. I’m going to remove the distinct [02:48:00]and let us just do this select by itself, right? So let me comment out the distinct. [02:48:05]So now we have a select query where we’re bringing about 19,000 and so on rows. [02:48:10]And we’re familiar with that. Now, when we do a group by, [02:48:15]it is usually in an effort to actually clump the data together. [02:48:20]So while distinct will see two and eliminate the second one, keep one and eliminate the second, third, et cetera. [02:48:25]What group by does is it actually clumps them, but it keeps track of how many records it clumped. [02:48:30]That makes sense. So in the case of Aaron, [02:48:35]where there are several Aarons, let’s say there are about 50, [02:48:40]50 plus Aarons in the system, right? [02:48:45]The distinct will just keep one, discard all the rest. The group by however, will actually remember [02:48:50]that even though it’s displaying one Aaron, it is, it actually clumped 50 Aarons [02:48:55]into one Aaron for display. So for this example, [02:49:00]let me remove the last name and I’m going to add a group by. [02:49:05]Now the group by has to come before the order by. [02:49:10]So I’m going to say group by, and then for every column that you are selecting, [02:49:15]you have to group by it. All right. So that’s the tricky part with the group by. [02:49:20]So if you’re selecting one column, you have to group by the one column. [02:49:25]And then what it’s going to do once again is clump all of the Aarons [02:49:30]because you saw that there were 50 just now. Now it’s only one for display, [02:49:35]but this, this functionality is actually tracking. And we’re going to see the relevance of that in the next lesson [02:49:40]when we look at the aggregate functions that go with the group by, but for now, [02:49:45]just know that that is what the group by does. So while it seems like it works just like a distinct, [02:49:50]it does give us a bit more functionality in the backend, in the background, [02:49:55]and we can do some more operations with the data that comes back. [02:50:00]Now similar to the distinct, however, the more data that you add is the less effective [02:50:05]that the grouping becomes. So let us try to add the last name value to this query. [02:50:10]And then when I run, [02:50:15]I’m going to get an error. And it’s saying that this column is invalid in the select list [02:50:20]because it is not contained in either an aggregate function or the group by clause. [02:50:25]So like I said earlier, every column that you select needs to be in the group by. [02:50:30]So if I’m selecting first name, I need it there. [02:50:35]So since I’m now selecting last name, I need to also group by the last name. So the group by knows [02:50:40]that when it’s trying to clump, it should be looking at both of these data points. [02:50:45]And then when I do that, the grouping is going to bring back the same kind of result that we got from the distinct. [02:50:50]However, in the backend, whatever was grouped, it knows how many of them, [02:50:55]it’s tracking how many of them were grouped and what the values were. [02:51:00]So when we come back, we’re going to look at the aggregate functions [02:51:05]and we are going to build on how this group by clause can help us to bring forth useful statistics. [02:51:10]All right, guys, welcome back. So in this lesson, we’re going to be taking it up a notch with the group by [02:51:15]concept that we looked at just now. [02:51:20]And we’re going to be looking at aggregate functions and how they work. [02:51:25]And here we’re going to kind of step out of the person exploration again and start looking at numbers, [02:51:30]but we’ll do it in, you know, step by step. So what is an aggregate function? [02:51:35]An aggregate function is a function that allows us to return certain, um, [02:51:40]statistics on our data. For instance, if I wanted to find the number of customers, yes, [02:51:45]it’s easy to run a select query and then just look at the number of rows that come back. [02:51:50]But for obvious reasons, that’s not the best way to do it. What if I wanted an actual number, [02:51:55]maybe for a report or for something else, what kind of query could I run? [02:52:00]So it’s a simple query really. An aggregate function can be put into [02:52:05]our select statement and I can just say select count star. [02:52:10]Here star means all or I could be specific with the data point. [02:52:15]But let us say that I’m going to use the previous query. [02:52:20]So let me reuse this select query [02:52:25]where we did select distinct and I’m just going to modify it a bit. [02:52:30]So I’m not interested in selecting distinct, but this time I want, let us say, [02:52:35]and let me just say all the first names. [02:52:40]I want to see all of the customers. So I want back one value. [02:52:45]So here I can say, give me the count. And this is a function, [02:52:50]which means I have to open parentheses and put in what we’ll call a parameter [02:52:55]and close parentheses. Notice the color coding on the function. [02:53:00]So function is an aggregate, sorry, count is an aggregate function. [02:53:05]And then we’re saying, give me a count of this value [02:53:10]from this query that we have written. And then when I run it, I’m getting this error saying that it’s invalid in the order by clause. [02:53:15]And that makes sense because I don’t need to order by count. [02:53:20]All right. So sometimes it’s good to just read the error message, [02:53:25]understand what it’s saying, because as we learn, as we hone our skills, [02:53:30]we are going to write statements that are invalid. So it’s important to be able to read the error message [02:53:35]and see what it complains about and know how to fix it. So let’s try that again. [02:53:40]Now look at that. I’m just getting a single value, nice, [02:53:45]single and simple value stating how much, um, many records are in that query. [02:53:50]All right. So that is your first example of the aggregate function. [02:53:55]So count is one of the easiest ones to use. [02:54:00]Now, what if I wanted to find the number of customers with the first, the same first name? [02:54:05]Now that’s slightly different because now [02:54:10]I need to know what the name is and how many times that name appeared. [02:54:15]So that is where we use our group by, because remember that we need to actually keep track [02:54:20]of the number of times that name was clumped together. [02:54:25]So let me remove this additional column. I only want to select the first name. [02:54:30]So I want the value to show, right? [02:54:35]But guess what? I also want the count for each time this value was shown. [02:54:40]So count here is just acting as another column. [02:54:45]I noticed that for the previous query where I just did count as a column, it said no column name. [02:54:50]So that means I would want to alias this. So let’s say as number, right? [02:54:55]And if you’re using one word, you don’t have to put it in square brackets, [02:55:00]but just be consistent. I will do that. And as a query gets longer, [02:55:05]I have to break the line so we can see what’s happening. So I’m selecting first names [02:55:10]and I’m selecting the number of times these first names appear. [02:55:15]And then here’s what is key. Remember that I said that a group by is actually keeping track [02:55:20]of the number of values that is actually grouping. [02:55:25]So when I do this and execute, you’re going to see, and let me comment this out so we don’t get an extra result. [02:55:30]So let’s do that again. Here, you’re actually going to see that Aaron appeared 54 times, [02:55:35]appeared 19 times. [02:55:40]These appeared once each, this one 76 times, there were 52 Adams, et cetera, et cetera, et cetera. [02:55:45]So I was able to select the name, group it. [02:55:50]And then because of the grouping, I’m able to see the number that appears [02:55:55]or number of times that value appeared. [02:56:00]Obviously, if I put on last name, then the counts won’t be so high, but at least then I would be able to see [02:56:05]how many times our last name appeared more than once, [02:56:10]which brings us to another activity. How would I be able to see [02:56:15]the number of times the number of duplicates, right? [02:56:20]So if it appeared once, then it’s not a duplicate. If it appears more than once, then obviously it’s a duplicate. [02:56:25]So I only want to see the duplicates. Now, generally speaking, [02:56:30]we would use a where clause to say something like where one column has a certain value, [02:56:35]but with a group by, we can’t use a where against an aggregate number because this value is an aggregate value. [02:56:40]So what I have to do is after I group by, I use the having keyword [02:56:45]and then state my condition. [02:56:50]So here I would say, having this aggregate number greater than one, [02:56:55]look at that. So now our skill statements are getting a bit longer [02:57:00]and a bit more complicated. [02:57:05]Remember that you can always use a where clause, but the where clause can only apply to values that are being selected here. [02:57:10]So I could say where first name is equal to maybe let’s say Aaron, right? [02:57:15]But then when I want to filter based on the aggregated value, [02:57:20]courtesy of my group by clause, [02:57:25]I have to say having, and then use that aggregate function in the condition. [02:57:30]So if I do that, then obviously I’m going to get back Aaron with 54, [02:57:35]because I did that where clause. [02:57:40]If I didn’t do that where clause and filter out relative to Aaron and just said, [02:57:45]I want everybody who all the first name, sorry, having a count of more than one, [02:57:50]then I’m not going to see any name come back. That’s one. So notice that, that a full stop doesn’t come back. [02:57:55]And those other names that were only appeared once do not come back. [02:58:00]And then I can also order by this value [02:58:05]so that I can see them in whichever order, whether ascending or descending accordingly, right. [02:58:10]I know you see that there are only 615 rows coming back [02:58:15]courtesy of that grouping and aggregation. [02:58:20]So that’s how aggregate functions can help us to maximize or, you know, just see deeper insights [02:58:25]into our data if we need them. Now, let’s look at another scenario [02:58:30]where we may want to find the total average lowest and highest amounts. [02:58:35]And we’re going to do all of these in one query using one table. [02:58:40]So this is going to be fairly simple. We’re just going to look at the different aggregate functions [02:58:45]that are needed to get these values. So let us start by selecting from our table. [02:58:50]I’m not going to select star. I could select star, but of course, [02:58:55]when you select star, the variations that exist across the dataset [02:59:00]will skew your results. So you want to be very careful and deliberate with what you are selecting. [02:59:05]In this case, I’m after the total due because I only want to see the sum [02:59:10]of the total due values and the average and all of these things, right? [02:59:15]So I’m just going to select total due from our sales order header table. [02:59:20]And let me be consistent. [02:59:25]So when I do that, I’m seeing that there are [02:59:30]over 31,000 sales that have happened. [02:59:35]I heard 31,000 sales. So for all of those sales, I want the total. So I can simply wrap this in a sum function. [02:59:40]And guess what I’m going to get from this? [02:59:45]One big value showing me the total number. I don’t even know what that numeral is. [02:59:50]I would love to have it in my bank account, but we’ll get there eventually, right? [02:59:55]So that is the total for all the sales that have happened in this database [03:00:00]as at the time this query is run. So now we have the total. What about the average? [03:00:05]Average amount? So for the average sale, right, [03:00:10]how much do we make? Well, for the average sale we make, [03:00:15]that’s what, $3915. [03:00:20]All right, that’s a little lower than I thought it would be considering the total, but we can work with that. All right. [03:00:25]So what is the lowest sale? Well, we have min. [03:00:30]Min, short for minimum, and then we say what is the minimum value, [03:00:35]the smallest value in that column for this entire dataset. Once I do that, [03:00:40]I want to see that $1.51 was the smallest sale. That was probably the very first sale [03:00:45]when we’re giving out samples. All right. [03:00:50]Now let us see what was the highest sale amount since we have started this business, [03:00:55]and the highest sale amount was $187,487. [03:01:00]So we see the different values here. [03:01:05]Now obviously there are no column names, and if you said that we need aliases, [03:01:10]then you go ahead and give yourself a pat on the back. You are right on the money. [03:01:15]So I’m just going to reformat these a bit, and then here I’m just going to say total sales amount. [03:01:20]So that’s column one for SUM, [03:01:25]and let me write SUM in all caps just to be consistent once again, [03:01:30]and then I’m going to say average sales amount. [03:01:35]Then we say lowest sale amount, [03:01:40]and highest sale amount. [03:01:45]All right. Now this is a snapshot view of what’s in the database, [03:01:50]what we have done, all the business that has been conducted up until now, [03:01:55]and some executives somewhere in the organization might just find this useful. [03:02:00]Most importantly, we know how to get these values. [03:02:05]Now when we come back, we’re going to take this a step further, [03:02:10]and then we’re going to start looking at more advanced concepts [03:02:15]with our aggregation and summation, because right now we’re just looking at all of the sales. [03:02:20]But what if we wanted to actually see all of the sales [03:02:25]that were conducted by a particular salesperson, and then relative to that salesperson, [03:02:30]we wanted to see what was their highest sale, what is their lowest sale, and what is their average sale amount. [03:02:35]So when we come back, we’re going to take it up a notch with our grouping and joining, [03:02:40]and look at how we can properly see insights in our data. [03:02:45]All right, welcome back. So this, this lesson is going to be more like a workshop than me teaching, [03:02:50]because now we’re going to combine some of the skills that we already know, [03:02:55]and do some deep analysis to make sure that we’re getting about the right data. [03:03:00]So now what we want to do is per salesperson see their, their stats on, you know, [03:03:05]the different amounts of money that they have brought in for the company. [03:03:10]So we also need to look at the salesperson table. So let’s take a quick look at the salesperson table to see [03:03:15]what data is available to us here. All right. [03:03:20]So in our salesperson table, we see that there’s an attempt to capture a year-to-date value for their sales, [03:03:25]but I don’t trust that. [03:03:30]I want us to build out our own reports, because we don’t know what system is updating this. We don’t know if it’s stale data. [03:03:35]We want to be able to pull a report that sees the data as it is at the time it is being pulled. [03:03:40]So salesperson gives us a business entity ID, [03:03:45]which simply means to me that to see their additional details, you know, [03:03:50]their salespersons, which makes them a person, and their person details will be in the person table. [03:03:55]All right? So that means we need to run a query that will join our person table [03:04:00]onto our salesperson table, and in our salesperson table [03:04:05]onto our sales order header table, and then from here, [03:04:10]after we’ve combined all of that, then we can start manipulating our data to bring back our stats. [03:04:15]So let’s get right into it. So let me comment out our previous query, [03:04:20]and I’m not even going to write the scenario. [03:04:25]I’m not going to bother to do that now, because we’re going straight into the action. [03:04:30]So let us select star from, and we can start off with salesperson, right? [03:04:35]So we want to select star from salesperson, [03:04:40]and that salesperson table, sorry, let me just find it and drag it over. [03:04:45]All right? So we’re selecting star from that table. [03:04:50]That’s no problem. Then I’m going to inner join this table on… [03:04:55]Um, sorry, inner join it with the person dot person table, [03:05:00]and let me just call this P and call this S. [03:05:05]So sometimes you may see persons use aliases as just letters. It’s fine. [03:05:10]It’s just that as the query gets bigger, it becomes less readable, because P really means less than per, [03:05:15]and per really doesn’t mean anything. It doesn’t mean what person means, right? [03:05:20]But just a little tip there. So person aliased as P, [03:05:25]we’re joining on business entity ID being equal to S dot business entity ID. [03:05:30]Now when we do that, we can see for each salesperson, [03:05:35]we can see their first name, last name, and that kind of stuff. All right? [03:05:40]So I think that’s good. Now we need to join [03:05:45]onto the sales order header table. So I’ll just copy this since I’m already there, [03:05:50]and of course you could have, you could drag it over, [03:05:55]but we need another inner join, and then we have our sales order header. [03:06:00]So I’m just going to call this SOH, sales order header, and we’re joining that on SOH dot [03:06:05]sales person ID [03:06:10]being equal to S dot salesperson ID, [03:06:15]and there’s no salesperson ID here, which means that clearly I need to use the business entity ID. [03:06:20]All right. So remember that little assessment that needs to happen, [03:06:25]because business entity ID is our resident ID to identify the person in person, [03:06:30]in the person table. So it’s kind of the obvious choice for the salesperson ID, [03:06:35]but not really. So make sure you do your due diligence. [03:06:40]Now that we’ve joined all of these together, [03:06:45]we’re still selecting star, we can see everything from left to right about any one person. [03:06:50]Notice that the person start doubling up now, because I’m now joining the person onto the sale. [03:06:55]So that means this Michael Reiter person has a sales order ending 59, [03:07:00]and another one ending 60. All right? [03:07:05]And for those two sales, I can see the total amounts that they have collected, [03:07:10]or he has collected rather. All right? [03:07:15]So you know, of course, obviously the data is going to duplicate, because whatever order that this person put in, there’s going to be a row. All right. [03:07:20]So now what we need to do is kind of refine the columns that we’re looking at. [03:07:25]So I definitely want to see first name and last name, [03:07:30]and I’m going to just break line and start typing that out. [03:07:35]So P dot first name, comma, P dot last name. [03:07:40]What else do we want to see? Maybe for all purposes, [03:07:45]for now we only need the total due. So S dot total due. Is it S? [03:07:50]No, it’s S-O-H dot total due. There we go. [03:07:55]So now we can cut this down now to see each person and the sale amounts [03:08:00]that they have brought in. So Jose has brought in these two, [03:08:05]Svee has brought in these two, Jose appears several times. [03:08:10]So Jose is working hard. All right? So now what we want to do is kind of group them, [03:08:15]because I don’t need to be seeing Svee all the time, and I don’t need to be seeing Jose all the time. I want to group them. [03:08:20]While grouping them, I also want to see the aggregated values for the total due. [03:08:25]So let us start off with the sum. [03:08:30]If I say give me the sum, I want to see for each salesperson [03:08:35]the total amount of sales that they have in the system. [03:08:40]I can now say, give me the first name, give me the last name, and sum total due. [03:08:45]All right, so instead of individually selecting these, [03:08:50]just sum it and tell me. Now when I do this, you’re going to see an error saying that [03:08:55]it is not contained in an aggregate function or the group by clause. [03:09:00]So in this situation, sum will not work because I have other values. [03:09:05]Unlike previous where all I was doing was selecting sum alongside other aggregations against the entire dataset. [03:09:10]In this case, we have a more vested interest where we have the first name, the last name. [03:09:15]I know you’re asking me to sum, but what am I summing? [03:09:20]Well, I can only sum after you group. So you need to tell me [03:09:25]that I need to group by the first name and last name of everybody. [03:09:30]And after I have grouped them, I can now sum [03:09:35]the values that I am attempting to group. So every time you see Svee Reiter, [03:09:40]I think that was the name, then go ahead and sum or add to the summation. [03:09:45]Every time you group him, add that total due value to the summation. [03:09:50]All right? So I’m going to call this total sales. [03:09:55]Now when I run this query, look at what happens. We have a much shorter list. All right? [03:10:00]Now we… I think we’re coming from 3,000 and so on rows. [03:10:05]Now we’re down to 17, as is correct because there are really only… Let me go back, there are only 17 salespersons. [03:10:10]There were many more sales, right? [03:10:15]This is select top 1,000, but I mean if we remove that, [03:10:20]then I’m sure there would be far more sales than just 1,000. Now we’re down to 17. [03:10:25]So now we’re seeing each sales agent and I’m able to see their total sales. [03:10:30]All right? Now what if I wanted to know their average sale? [03:10:35]Well, it’s about the same thing. So here’s what I wanted. I’m just going to copy these lines that we wrote already [03:10:40]and uncomment them. So I don’t have to write them again, [03:10:45]but the fact is now they will work relative to the grouping. [03:10:50]So relative to the grouping, we’ll see the sum. We’ll see each person’s average, [03:10:55]each person’s lowest sale amount and each person’s highest sale amount. [03:11:00]And then when I run this, now we’re seeing everything. [03:11:05]So Syed has this much in sales. That’s his average sale amount, his lowest sales for $62. I guess this is when he was an intern, right? [03:11:10]I know he’s a superstar where his highest sale amount was $65,000 [03:11:15]and the list goes on. And that is how grouping and aggregate functions work. [03:11:20]One more useful metric I think would help [03:11:25]would be to add the number of sales. So I can say count [03:11:30]and count the same column, right? [03:11:35]And then we’ll just say number of sales. Because it’s kind of hard to say well somebody’s average sales is X amount when they’ve only sold one thing, right? [03:11:40]So at least we get a little context that Syed [03:11:45]has sold only 16 things and he has amassed that amount of money. [03:11:50]Whereas Michael Blythe has 450 sales [03:11:55]and that’s how much money he’s clocking. All right? [03:12:00]So those are once again useful metrics that give a snapshot view of how your sales [03:12:05]reps are working. And you can of course apply these concepts [03:12:10]to other parts of your system. Now one thing I can appreciate is that [03:12:15]these values are not very clean to look at. So when we come back we’re going to look at how we can manipulate them. [03:12:20]Right now what they’re called strings because they’re really coming back as text. [03:12:25]So we’ll look at string manipulation [03:12:30]and how we can use string manipulation to clean up our data as it is displayed. [03:12:35]All right. Welcome back. In this lesson, we’re going to be looking at string manipulation. [03:12:40]So what we’re going to be doing for this one is formatting the previous query to have [03:12:45]a full name column. And we will also want to format our dollar values [03:12:50]to look more like currency. So string manipulation. [03:12:55]SQL has a lot of built-in functions that allow us to determine what we want to do with our string value. [03:13:00]So in this case a string is a word. Frankly once it is being selected, [03:13:05]it is being seen as a string at that point. [03:13:10]So what we need to do is actually manipulate it and format it how we want it formatted. [03:13:15]So the first one would be to have a full name column instead of first name and last name. [03:13:20]So I’m going to start by taking a copy of our previous query [03:13:25]and I’m going to uncomment. [03:13:30]And now we’re going to look at how we join two values from two different columns into a single column. [03:13:35]And SQL’s function for that is CONCAT. [03:13:40]Now there are two ways to do it. [03:13:45]You have, well, the concept of joining strings is called concatenation. [03:13:50]So you could actually say p.firstname and then plus. [03:13:55]So that’s the joining right there. So it’s like doing math, right? Concatenation. [03:14:00]So let us look at what we get when we do this. Let me just comment out the two original columns [03:14:05]and then do the select. And here you see that we have no column name [03:14:10]because we didn’t give it an alias. But we have what seems to be a full name. [03:14:15]But then everything is kind of joined or Camel cased or Pascal cased. All right? [03:14:20]So how do we get a space in between the values? [03:14:25]So that means now I have to add a space. So after first name I need to plus [03:14:30]and then create a space. All right? And then plus back last name. [03:14:35]So all of that. So we’re adding first name, adding a space [03:14:40]and then adding last name. And then when we do that, that’s all going to help us to concatenate. [03:14:45]Now an alternative to that form of concatenation is to use the built-in CONCAT function. [03:14:50]So you’ve had experience with functions before. [03:14:55]All right? So CONCAT is just another function [03:15:00]that we can put in the different things that we want to concatenate. [03:15:05]So we want to concatenate p.firstname. And I want to concatenate [03:15:10]and I just comma separate all of the things I want to concatenate. [03:15:15]I want to concatenate a space and I want to concatenate p.lastname. [03:15:20]Now I’m not going to stay here and tell you which one is easier and which one is better to use. [03:15:25]That’s more up to you. Generally speaking for the longer strings I find using the CONCAT function to be easier. [03:15:30]But for short ones like maybe just a full name operation [03:15:35]I’ll probably just use this format. So it’s up to you. [03:15:40]But you see that we have two columns with the same full name values coming out. [03:15:45]So going forward, I’m just going to comment this one out and leave it there for reference. [03:15:50]But we can leave this one for our query. And of course we need to alias it. [03:15:55]So this is full name. Then let us look at formatting our dollar values. [03:16:00]So right now, well, count isn’t a dollar value. So I don’t have to worry about that one. [03:16:05]But some average min max, all of those, they’re just numerals. [03:16:10]So we can’t, it’s hard for us to read it. And especially since it’s not formatted with commas [03:16:15]and the appropriate decimal points. Well, the decimal point is there but the number of decimal places [03:16:20]that we usually see with money, we definitely want to have that kind of formatting. [03:16:25]So we’re going to wrap this value inside of another function. [03:16:30]And this function is going to be called format. [03:16:35]So format is going to… Once again it’s a function, [03:16:40]notice the color and we have to have our parentheses. [03:16:45]Then it takes the value that you want to format. And then we say comma. [03:16:50]And then the next parameter would be how do you want to format it. So we can simply use a string called C [03:16:55]which is short for currency. All right? [03:17:00]So and I just did that around the wrong column. [03:17:05]You guys should have stopped me. I’m sorry. So we should be formatting sum and not count. [03:17:10]So let me just move of that new code down to the sum. So let’s do that again. [03:17:15]Format and they were putting the sum of total due inside of the format function comma [03:17:20]and then C to indicate currency. [03:17:25]Now look at the total sales value now and then look at it after the query. [03:17:30]And we see here that we have our dollar sign, we have our comma and our two decimal places. [03:17:35]And now it’s much easier to read what this total sales value might be. [03:17:40]Once again another form of string manipulation. [03:17:45]So now I can do this to all the other columns that I would like to have formatted to look like currency. [03:17:50]There we go. So now we have total sales, average sales, lowest sale amount, [03:17:55]highest sale amount all of them formatted and looking like money. [03:18:00]Now in general this is the tip of the iceberg. [03:18:05]We have several other functions that you can use. You have trim [03:18:10]which means that you give it a string or like a value from the database and it will eliminate the spaces around it. [03:18:15]All right? You have L trim and you have R trim which means [03:18:20]you want to trim all the spaces to the left of the string or do you want to trim all the spaces to the right of the string. [03:18:25]The string, right? So you have several string manipulation functions [03:18:30]and it’s very difficult to go through all of them in one lesson, let alone one course. [03:18:35]That could be a course by itself because SQL is very powerful. [03:18:40]So I would encourage you now that you appreciate how string manipulation works and that there are built-in functions for them. [03:18:45]Go ahead and research the function that is needed for the task at hand. [03:18:50]You don’t have to memorize them all. Just know which one can come in handy [03:18:55]for which purpose. Now we’ve come to a very vital operation and that is exporting our data. [03:19:00]Now why is this important? [03:19:05]Well, as a data analyst, you are going to be working in the, in the Management Studio. [03:19:10]You’re going to be writing all the syntax. Chances are your manager, [03:19:15]your supervisor is not going to be interested in this. So you need to be able to get this data [03:19:20]after you’ve extracted it and formatted it and made it presentable with your column [03:19:25]headings and respective formatting options. [03:19:30]Now you need to take it and send it by email. You need to send it, [03:19:35]put it on a shared drive wherever but you need it in a format that it can be opened on somebody else’s computer [03:19:40]when they don’t have the Management Studio. So now what do you do? [03:19:45]Well, there are several options for that. The easiest one would be to right click here [03:19:50]and say so, save result ads. By doing that, it’s actually going to export it and create a CSV file. [03:19:55]So you can find the appropriate folder, give it a name, [03:20:00]let’s say salesperson reports and save. [03:20:05]Now after saving when I open it, you see it will just open up nice [03:20:10]and easy inside of Microsoft Excel and that would be our CSV file [03:20:15]and of course a CSV file is more than just a spreadsheet. [03:20:20]You can use it for other things like parsing in another system, etc. [03:20:25]However for reporting purposes notice there is no heading, right? [03:20:30]So that means I would probably need to come in here again and then insert a new row and then put in the different column headers [03:20:35]which is not very efficient. So that is one option, that’s the easiest option but it might not be the best option. [03:20:40]So what I like to do is actually click right here in that box [03:20:45]that’s between the first column header [03:20:50]and the first numeral for the row just clicking in there highlights the entire grid. [03:20:55]Then once that grid is highlighted, I can copy with headers. [03:21:00]So once I do that, I now open up Excel and I’ll just go to a new sheet and paste. [03:21:05]And just by doing that now I have each column [03:21:10]with this header and that’s a much cleaner and easier way to get the data into Excel [03:21:15]with the headers and the formatting. And then, of course, [03:21:20]from here you format as you need to and you save your spreadsheet [03:21:25]and then you send it to whomever. [03:21:30]So that is the easy way to export data from your Management Studio [03:21:35]to Excel for reporting purposes.
[03:21:40] Emar Morrison In this video, we’ll be taking a look at sub queries. [03:21:45]So as the name suggests a subquery is a query within another query. [03:21:50]So you could look at it as a Select statement within a Select statement, right? [03:21:55]It is also called an inner select or an inner query and is typically enclosed in a parentheses. [03:22:00]So in the human resource schema we have the employee table. [03:22:05]So now let’s do a Select 1000. Now within the employee table [03:22:10]we have a column called vacation hours. So let’s say we want to find employees [03:22:15]with vacation hours more than the average vacation. [03:22:20]Then we can find the average vacation hours and then filter the records based on the average we found, right? [03:22:25]So here I have a simple Select statement that finds the average vacation hours. [03:22:30]So when I execute this I get an average hour of 50. [03:22:35]This statement just select from the employee table. [03:22:40]Now I can add a where clause and say vacation hours is greater than 50. [03:22:45]But as you know over time the number of vacation hours will change as employees utilize their vacation hours. [03:22:50]So hard coding the value of 50 here is not a good idea. [03:22:55]So what we can do to achieve the same result is replace the 50 with a query. [03:23:00]Now this query will become the inner query or the subquery. [03:23:05]So I’m going to replace the 50 and get the Select statement from above. [03:23:10]Let’s copy this or should I say cut. Now let’s space it here. Now let’s close the bracket. [03:23:15]Now let’s execute the statement and as you can see we got the same result. [03:23:20]You can also use sub queries in join statements. Basically you’re deriving another table. [03:23:25]For instance, if we want to know which employees [03:23:30]have more vacation hours than the average for their job title, [03:23:35]we can achieve this by using subquery to derive another table. [03:23:40]So let’s take a look at a query that you can use to achieve this. So the first thing you need to do to achieve this is that you need to write a separate query [03:23:45]to achieve the average vacation hours for each job title. [03:23:50]So this query has returned the result for each job title. [03:23:55]So as you can see the accountant has an average hour of 58, account manager’s 57 [03:24:00]so on and so forth. Now what you need to do is visualize this result as a table, right? [03:24:05]So now you need to join this result set [03:24:10]from the subquery with the employee table. [03:24:15]So you will be joining on the job title. From the outer query you can access values from the inner query. [03:24:20]So you specify the alias for the table [03:24:25]and then the column that you want to access. So here we are accessing the average vacation column [03:24:30]that was calculated within this subquery. [03:24:35]Now when we execute this statement you get the result set with the accountant, the vacation hours which they have [03:24:40]and the average vacation hours for that job title. [03:24:45]So we can add another filter clause here. So we are going to say hand job title is equal to accountant. [03:24:50]Now we will see all the accountants and their vacation hours that is over the average hour. [03:24:55]So now we’re just limiting the result set to accountants, right? [03:25:00]So we should only see results for the accountants. [03:25:05]As you can see I have a red squiggly here. This is saying that the column is ambiguous [03:25:10]because now basically we have two tables, right? [03:25:15]The inner query as well as the outer query which has job title in it. [03:25:20]So to specify which job title we are using, then we need to specify the table alias. [03:25:25]So in this case we can say E1. Let’s execute [03:25:30]and here we have only one accountant within the database. [03:25:35]Now if we change it to janitor, we should get more than one rows. [03:25:40]So here we can see we have two janitors that have vacation hours higher than the average. [03:25:45]Here are a few things that you need to consider when using sub queries. [03:25:50]The distinct keyword can’t be used with sub queries that include group by. [03:25:55]The compute and inter clause can’t be specified. Order by can only be specified [03:26:00]when top is also specified. A view created by using a subquery can’t be updated. [03:26:05]It’s also important to know that there’s no performance [03:26:10]difference between statements that include a subquery and a semantically equivalent version that doesn’t. [03:26:15]In the next lecture, we’ll be taking a look at command table expression [03:26:20]also referred to as CTE. [03:26:25]In this lecture, we’re going to be taking a look at command table expression also referred to as CTE. [03:26:30]So most of the times you’ll hear individual referred to it as CTE. [03:26:35]What it does is that it allows you to define a temporary name result set that is temporarily available [03:26:40]during execution of statements such as select, insert, update, delete, or merge. [03:26:45]You can also think of it as a temporary table. You can also think of it as a named temporary table. [03:26:50]Now the difference here is that you can do a query on top of the CTE [03:26:55]which you’ll see later on in this video, right? [03:27:00]But on a temporary table you cannot do that. So it follows this simple syntax here. [03:27:05]You have the width and the expression name. [03:27:10]This is required and the name of the columns that you want to return in your result set. [03:27:15]Please note that these columns are optional. So the first step is to define the CTE expression name [03:27:20]and the column list which is optional, right? And then you’re going to specify has. [03:27:25]So this is where you define the query for the CTE. [03:27:30]This is just like your regular SQL statements. So after you define your CTE query here [03:27:35]at the outer portion of the CTE you define your outer query. [03:27:40]So this will be like your select statement. [03:27:45]So here’s where I’ll say select from and the name of the CTE. [03:27:50]So I’m just gonna put that straight here. So first you define your expression syntax. [03:27:55]Then you define your query and then here is where you’ll perform operations [03:28:00]on your name result set. So let’s take a look at an example [03:28:05]of finding the total number of sales orders per year of each sales representative. [03:28:10]So the first step in the CTE is that you’re going to define the expression. [03:28:15]Here I’m returning the salesperson ID, sales order ID, and sales year. [03:28:20]Now in this section I am defining the query for the CTE [03:28:25]which will find that result. So if I execute the statement, it will be executed. [03:28:30]However, at this point the query is only returning each sale for a person [03:28:35]and here the sale was done. So in order to achieve the total sales, [03:28:40]we need to do a count on the sales order ID. [03:28:45]So here we are defining the outer query that will reference the CTE. [03:28:50]Because remember, the CTE is like a temporary table which you can now run a query against that table. [03:28:55]So here I’m getting the salesperson ID. [03:29:00]I’m doing a count on the sales order ID. I’m saving it as total sales [03:29:05]and I’m getting the sales year as well. Now here’s the key which is the from, [03:29:10]which is selecting from the CTE. So here I have to group by the sales year [03:29:15]and then I have to group by the salesperson ID. [03:29:20]Then I’m just ordering by the salesperson ID and the sales year. [03:29:25]So if we execute this query, you should get the result. You will see the total sales for each salesperson for each year. [03:29:30]So you can see that… So here you can see that the salesperson with ID 274 [03:29:35]had four sales in, in 2011, 22 [03:29:40]in 2012 and 14 in 2013. [03:29:45]So this is how you can use CTE to execute your queries. [03:29:50]Now it’s also important to note that there are some applications that may not support CTE. [03:29:55]So you’d have to rewrite your query maybe using temporary tables or sub queries [03:30:00]to achieve that result. If we remove a column from the expression definition [03:30:05]then we’ll get an error. As you can see the CTE has more columns [03:30:10]than specified in the column list. So right away it ticks up that we are returning more columns than what is defined here. [03:30:15]However, you can get rid of this completely [03:30:20]and then the error will go away because the column list is optional. [03:30:25]So if we execute this query again, we should get the same result. It’s also important to note that you cannot execute the CTE partially. [03:30:30]So for example, if we’re supposed to execute that with CTE portion [03:30:35]only on the query, it will throw an error. [03:30:40]It is important to note that the scope of a CTE is limited to the query that immediately follows it. Once the query is complete, [03:30:45]the CTE is no longer accessible. In this lecture, [03:30:50]we’ll be taking a look at window functions. Window functions operate [03:30:55]in a set of rows and return a single aggregated value for each row. [03:31:00]The term window describes the set of rows in the database on which the function will operate. [03:31:05]We define the window, the set of rows on which function operates, [03:31:10]using an over clause. Now you can think of functions [03:31:15]as predefined programs and you use them to perform operations on data. [03:31:20]They let you do things like aggregating data, formatting strings, [03:31:25]extracting dates, so on and so forth. So windows functions are SQL functions [03:31:30]that enable us to perform operations on a window. [03:31:35]That is a set of records, right? Before we go into the syntax of windows functions, [03:31:40]let’s have a look at the categories of windows functions. [03:31:45]There are a lot of functions that exist in SQL, but they are primarily categorized in three different types. [03:31:50]You have aggregate window functions, value window functions, [03:31:55]and ranking window functions. Aggregate functions are used to perform operations [03:32:00]and set of rows in a window. They include sum, max, count [03:32:05]and other function like average. Now the rank functions as the name suggests, [03:32:10]rank window functions are used to rank windows. They include rank, dense rank, [03:32:15]row number and others. Now, value functions are like aggregate functions [03:32:20]that perform multiple operations in a window, [03:32:25]but they are different from aggregate functions. They include things like lead, lag, [03:32:30]first value and others. We’ll see their usefulness later on in this section. [03:32:35]All right. So let’s go over the syntax piece by piece, right? [03:32:40]So you have the window function, then you have over, then you have the partition by list, and then you have the order by list. [03:32:45]Now, the window function simply specify the window function. [03:32:50]Now, all is an optional keyword. When you include all, it count all the values including duplicate ones. [03:32:55]Distinct is not supported by windows functions. [03:33:00]Now, expression is simply the target column that the function operates on. [03:33:05]In other words, the name of the column for which we need an aggregated value. [03:33:10]So for example, a column containing order amount so that we can see the total orders received. [03:33:15]The over specifies the window clauses for the aggregate function. [03:33:20]Now, the partition by partition list defines the set of rows [03:33:25]on which the function operates for the window functions. [03:33:30]You’ll understand this better when we are doing the practical, right? So we need to provide a field or list of fields after the partition by clause. [03:33:35]If the partition by is not specified, [03:33:40]grouping will not be done on the entire table and values will not be aggregated accordingly. [03:33:45]Order by sorts rows within each partition. If order by is not specified, [03:33:50]order by uses the entire table. In the next lecture, [03:33:55]we’ll be taking a look at some examples using window function. [03:34:00]In this lecture, we’re going to be taking a look at windows aggregate functions, right? [03:34:05]So those are aggregate function like min and max. [03:34:10]Now let’s say we want to show the max and min unit price for heat sales order. [03:34:15]We could achieve this by using a subquery. So here we have a subquery that will achieve this. [03:34:20]So the subquery is simplifying the max and the min and executing it for each row. [03:34:25]So when we execute this query, we will see the max price [03:34:30]and the min price for each record in the table. [03:34:35]However, this can be simplified using the over function because when you use the over function [03:34:40]it will not group the data but execute it for each record in the table. [03:34:45]So now we have a second query that will be used to achieve the same thing, right? [03:34:50]So instead of using a subquery, we are just simply specifying the over function. [03:34:55]So now when we execute this query, we’ll get the same result. [03:35:00]So as you can see we have the max unit price and the minimum unit price for heat sales order, right? [03:35:05]But this is for the entire table. Now what if we want to find the maximum unit price [03:35:10]and the minimum unit price for heat sales order? [03:35:15]How are we going to achieve this? Well, we can partition the data by the sales order ID. [03:35:20]So let’s scroll down and look at the third query that we have. [03:35:25]So the over clause take two optional parameters. [03:35:30]It is the partition by and the order by. However you may use them depending on what you want to achieve. [03:35:35]So in this first scenario we did not need to use a partition by [03:35:40]because we wanted to see the max and the minimum just for the entire table. [03:35:45]Now that we have a different scenario, we want to see the max [03:35:50]and the minimum for heat sales order ID, then we have to use partition by. [03:35:55]So let me just copy this column and put in my commas. [03:36:00]Now I’m just going to call this max and I’m going to call the other one min. [03:36:05]Now I need to change the aggregate function to min, right? Remove a comma to get rid of the head row. [03:36:10]Now let’s execute this statement. Now when you take a look at the result set, [03:36:15]when you take a look at the max and the min column, you’ll see that we have different max [03:36:20]and min price being shown and this depends on the sales order ID. [03:36:25]So if you look at sales order ID 43659, you’ll see that the max [03:36:30]and the min is different when compared to that of 4366. [03:36:35]We could also do a total of each sales order ID. [03:36:40]So let’s copy this query again. Let’s paste. So I’m just gonna give this a comment as sum by sales order, right? [03:36:45]So instead of the max and min, we’re just going to use sum. [03:36:50]So I’m just gonna say total here. Now let’s execute and you’ll see the total for heat sales order ID. [03:36:55]So as you can see using windows function is a great way to eliminate. [03:37:00]It even makes your query more simple and readable [03:37:05]and allows you to perform more manipulation with your data. [03:37:10]In the next lecture, we’re going to be taking a look at ranking functions. [03:37:15]In this lecture, you’ll learn how to use functions like the row number function, [03:37:20]rank and dense rank. The row number as the name suggests [03:37:25]is used to assign numbers to records in a window. So here we have a simple query that displays the employee business entity, [03:37:30]login, job title and vacation hours. [03:37:35]Now let’s execute this query and we’ll get the results set. We can now use the row number function to assign a number to each row. [03:37:40]So let’s add the row number. [03:37:45]Now we need to add the over clause, right? So I’m going to say has row count, right? [03:37:50]Now unlike when we’re using the aggregate function, [03:37:55]we use the over clause without specifying a parameter. However, in this case if we do execute it then [03:38:00]it’s going to fail because a row number must have an order by within the over clause, right? [03:38:05]So now I need to specify a column [03:38:10]which I need to use to order the result set. So let’s say order, order by, [03:38:15]and then specify the column that we want to use to order the dataset. [03:38:20]So I’m going to say login ID. Now let’s execute this and a row count was added. [03:38:25]Now let’s say we want to rank each employee by their vacation hours [03:38:30]by the department which they are in. What we can do is utilize a rank function. [03:38:35]So let’s copy this query. Now let’s paste. So instead of using the row number, [03:38:40]we’re going to be using the rank function, right? [03:38:45]So specify the rank, and we need to be partitioning by and we need to be partitioning [03:38:50]by the department table. So instead of order, we’re going to have partition. [03:38:55]So the partition is like breaking up the data. So we’re going to partition by the job title, [03:39:00]not the department like I mentioned earlier. The job title, right? [03:39:05]And then we’re going to order by vacation hours. [03:39:10]And we’re going to call this column rank. Now let’s execute this statement. [03:39:15]So I have a typo here. So it should be vacation hours not V. Let’s execute again. [03:39:20]So if you observe the dataset, it’s ranking the employees by their job title [03:39:25]and then by their vacation hours. Send account department. [03:39:30]Barbara has the more vacation hours with 58 and has a rank of one. [03:39:35]Now what a rank function does is that it allows you to rank observations in a window with gaps. [03:39:40]Meaning that, if there are ties within the dataset that you are ranking, [03:39:45]then you’ll see a gap in the data. So far we don’t have any gap in the data. [03:39:50]So I’m going to demonstrate that show you using the job title account receivable specialist, right? [03:39:55]So if you look carefully, you’ll realize that we have three account receivable specialists [03:40:00]all having a vacation hours of 60, 61, and 62 respectively. [03:40:05]Now what I am going to do is that I am going to be updating off one of these records [03:40:10]so there’s a tie in the data so you can see what the rank does. [03:40:15]So I’m going to write the update statement. Update human resource employee. [03:40:20]Set vacation hours equal 60 [03:40:25]where where login ID is equal to copy and paste the bora zero. [03:40:30]So I’m going to change it from 60 to 61. [03:40:35]Now let’s execute the statement. Now let’s run the wrong statement again. [03:40:40]Now if you observe the data carefully now you’ll see that when we have a tie, [03:40:45]it skips rank number two and then jump to number three. [03:40:50]So this is where dense rank come in handy. Dense rank solve this problem. So let’s copy and paste this statement. [03:40:55]Now when we use the dense rank function, the NSC under square, [03:41:00]you’d see that it solves this problem, right? So let’s execute. [03:41:05]So when there’s a tie in stuff having a gap in the data, then it goes to the next rank. [03:41:10]So remember if we execute the first statement again and look, execute, [03:41:15]you will see that in the accounts receivable specialist when there was a tie, it just jumped to number three. [03:41:20]Now in the dense rank, it stayed at number two. [03:41:25]Now let’s say you are supposed to find the employee for each job title that has the highest vacation hours. [03:41:30]How will you go about that? Now the first thing you maybe think is the right away clause here, right? [03:41:35]And then say rank equal to one. But this will not work. [03:41:40]But remember from previous lectures you learned about CTE [03:41:45]that you can use as name result. So we can now convert this result set to a CTE. [03:41:50]So first we specify the width and then we have a name for the CTE. [03:41:55]You can name anything. Remember, the columns are optional, right? [03:42:00]So I’m going to say has and then now I need to define my query for the CTE. [03:42:05]So now I’m just gonna paste the query from above. [03:42:10]Let’s get rid of the where clause. Now we can do a query on the result set of the CTE. [03:42:15]So I’m going to say asterisk from CTE where rank equal one. [03:42:20]Now let’s execute. As you can see, from the results set, [03:42:25]we have only the job titles with the rank equal one. In the next lecture, [03:42:30]we’ll be taking a look at functions such as lead and lag. [03:42:35]In this video, we’ll discuss the lead and lag windows functions. [03:42:40]The lead function is used to access subsequent row data along the current row data. [03:42:45]Now the lag function is used to access previous row data along the current row data. [03:42:50]The order by clause is required while the partition by clause is optional. [03:42:55]The offset parameter tells the number of rows to lead our log by. [03:43:00]The default value is the default value to return if the number of rows to lead our log goes beyond the first row or the last row [03:43:05]in a table or partition. If the default value is not specified [03:43:10]then null is returned. Now to see how this work we’re going to be using the product table. [03:43:15]So I’m going to write a simple select statement [03:43:20]asterisk from production dot product table. So let’s execute this. [03:43:25]Now for simplicity let’s say for the current product we want to find out the next average stock level [03:43:30]that will be coming up. We can use the lead function to achieve this. [03:43:35]So my expected result is that for the first product, right, [03:43:40]it will show the next safety product as 1,000. For the second one, it will show it as 800. [03:43:45]So now let’s make a small change to the query and include only the columns we want in the result set. [03:43:50]So I’m going to say a product ID, product name, [03:43:55]product number and I’m going to grab the safety stock level. [03:44:00]So we’re gonna just grab the lead syntax. So it’s lead and we want the column that we want it to lead by, right? [03:44:05]So it’s a safety stock level. For now we’re not going to specify any offset value or default value. [03:44:10]So let’s remove this parameter and we’re going to be ordering by the product ID, [03:44:15]and I’m going to give this a column alias as next stock level. [03:44:20]Now let’s execute this statement. As you can see for each row it shows the subsequent value. [03:44:25]So for the first row, it has a 1,000 and the next one was 1,000. [03:44:30]So the 1,000 is here. In the second row, we have a safety stock level of a 1,000 [03:44:35]and the next level is 800. And as you can see, the next level is 800 here. [03:44:40]Now if you scroll down to the end, right, [03:44:45]you’ll see that there is a null value for the last record. [03:44:50]This is because it is leading forward by a one. So there will always be one that is left out. [03:44:55]So the default offset is one. Now if we change the default offset from one to say five, [03:45:00]you will see what happens to the result. So let’s change it to five. [03:45:05]Now let’s execute this. Now the next stock level is offset by five rows. [03:45:10]So if you count one, two, three, four, five, you’ll see that it starts at the fifth row from the first record. [03:45:15]If you scroll down to the end of the result set, you’ll see that. So this is where the default value comes in handy. [03:45:20]The default value takes care of these null records. [03:45:25]Say we’re supposed to specify the comma and set the default value to say zero, [03:45:30]then those null values will be replaced with zeros. So if we scroll down and check the result again, [03:45:35]you’ll see that these values start with zero. So the lead looks ahead and the lag looks behind. [03:45:40]So let’s copy this. Now let’s paste. So instead of next, [03:45:45]we are going to say previous and instead of lead, we are going to change the function to lag. [03:45:50]So this is saying look five rows behind for the next result, right? [03:45:55]So based on this result set, if we were supposed to look five rows behind, right, or in the past there’s no data. [03:46:00]So the first five rows will be null, right? So let’s execute this again. [03:46:05]So the null values here will replace with a zero [03:46:10]because I specified zero here, right? So it doesn’t start looking forward until the sixth row, right? [03:46:15]So here we are in line six and then the previous record [03:46:20]would be the record in line five. The previous stock level here would be a 1,000. [03:46:25]We can also use the partition by clause with the lead and lag functions. [03:46:30]So to summarize, the lead function looks ahead and the lag function looks behind. [03:46:35]There are various window functions available out there. [03:46:40]There are a lot of window functions available out there so we won’t be able to cover all of them in this course. [03:46:45]So I’ll leave a link to additional resource in the resource section of this lecture. In this lecture, we’re going to be taking a look at the difference [03:46:50]between ISNULL and COALESCE. So far, you would have seen that [03:46:55]when you query the database, you’ll realize that some records return null for some columns. [03:47:00]When you’re presenting data, you need to be presenting meaningful data to the end users. [03:47:05]So this is typically when you’re creating reports, right? [03:47:10]So when there’s a null value, for example, title like mister or miss, right? [03:47:15]And the title is not specified for a record, you could say title not applicable, right? [03:47:20]So this is where the ISNULL and COALESCE comes in handy. [03:47:25]So the ISNULL function is a built in function in SQL Server that takes two parameter, [03:47:30]the expression to be evaluated and the value to be returned if the expression is null. [03:47:35]So the expression is a value or column to be checked for null. [03:47:40]The value is a replacement value returned if the expression is null. Here are some key things to note about ISNULL. [03:47:45]ISNULL is specific to SQL Server and is not a part of the ANSI SQL standard. [03:47:50]So this means that if you check a database like Postgres or MySQL, [03:47:55]you may not find the ISNULL function. It can only handle two parameters at a given time. [03:48:00]COALESCE is also a function built into SQL Server [03:48:05]that takes multiple parameters and returns the first non null expression from the parameter list. [03:48:10]Expressions are values or columns to be evaluated for null. [03:48:15]The function returns the first non null expression from left to right. [03:48:20]It’s important to know that Coalesce is a part of the ANSI SQL standard [03:48:25]and is supported by multiple database systems. So if you’re going to an Oracle database or MySQL database, [03:48:30]you can find this function. It can handle multiple parameters [03:48:35]allowing more flexibility when compared to ISNULL. [03:48:40]The data types of the expression can be different, but there should be implicit or explicit conversion rules. [03:48:45]So let’s head over to Management Studio now and take a look at an example of how you can use both Coalesce and ISNULL. [03:48:50]So here I have a query that returns the top ten results [03:48:55]from the person table. If you observe the data within the title column, [03:49:00]middle name column, suffix and additional contact info, [03:49:05]we have null values being returned. Now, this doesn’t necessarily mean the person [03:49:10]does not have a title or say a suffix or a middle name. [03:49:15]This means that the value is just not present and the null is just a placeholder. [03:49:20]Now let’s say a regular user ran this report. They get the results for Ken, Terry, Robert, etc, right? [03:49:25]But when they look at the data, they see that Ken and Terry has a middle name. [03:49:30]But what happened to Roberta and Rob, right? [03:49:35]They now must be wondering what is null. Now to fix this, we can use the ISNULL function. [03:49:40]So for title we’re going to say ISNULL open brackets. [03:49:45]Remember, it takes two parameter. The column that it needs to check for null and the replacement value. [03:49:50]So here we can put two strings to represent the null, right? [03:49:55]And now we need to have a alias for the column because if we execute like this, [03:50:00]then the column will not have any name. So you’re going to say has title. [03:50:05]Now let’s execute this again. And as you can see, the null values were replaced. [03:50:10]We can also achieve the same thing with COALESCE. So to fix the null issue with middle name, [03:50:15]we’re going to use COALESCE. Say it takes more than one parameter, [03:50:20]but in this case we only need one parameter. Say it’s middle name [03:50:25]and the value that we are replacing it with. So for now, we can say not applicable. [03:50:30]So we’re gonna say NA, right? Now let’s close this and add an alias for the column [03:50:35]and say middle name. Now let’s execute. And that took care of the middle name. [03:50:40]Now for the ISNULL, instead of specifying an empty string, [03:50:45]we could also specify a value like NA, right? [03:50:50]So let’s execute this and now instead of an empty string, we have NA. [03:50:55]We could also specify an integer. Now let’s execute this and it will return one as an integer. [03:51:00]However, there is something very important to note. Now let’s take a look at the data type for the title column. [03:51:05]So expand table, view columns, and as you can see that for the title type [03:51:10]it’s VARCHAR. Even though it’s VARCHAR, [03:51:15]we’re able to specify one and ISNULL still returned one. [03:51:20]So basically, the ISNULL returned the value as the expression data type, right? [03:51:25]So the expression is title and the data type for the title is in VARCHAR. [03:51:30]So the ISNULL returned the value as the data type of the expression. [03:51:35]Rephrase that whatever it is about the color mix, that is what ISNULL will return. [03:51:40]So even though it looks like an integer, it is a VARCHAR. [03:51:45]So that’s something that you have to bear in mind when you are working with ISNULL. [03:51:50]Now, let’s try the same thing with the COALESCE. So we’re going to change the not applicable and specify an integer. [03:51:55]Now let’s execute. And as you can see, the query failed [03:52:00]because what happened here is that, so what happened here is that COALESCE is returning the data type of the value. [03:52:05]So as you can see, conversion failed [03:52:10]when converting the NVARCHAR value to data type int. [03:52:15]However, if we are supposed to put this in a quotation, then it will work [03:52:20]because now we have literally converted the one into a string. [03:52:25]A very important thing that you need to keep in mind for ISNULL is that you have to be aware of silent truncation [03:52:30]because it returns the data type of the expression. So here I have a simple example [03:52:35]where I’m declaring a string, a VARCHAR tree, right? [03:52:40]So I’m just gonna do a COALESCE to check if the string is empty, and if the string is empty I’m going to return longer. [03:52:45]And I’m doing the same thing for the ISNULL. [03:52:50]So let’s execute this statement and here we can see that the reason for the COALESCE we have longer while ISNULL [03:52:55]we have long. Well, not long but hello hint, right? [03:53:00]Because what’s happening is that the ISNULL is returning the result based on the data type of the expression [03:53:05]which is this, while COALESCE is returning the data type based on the value. [03:53:10]See we’re supposed to put a one here again. [03:53:15]Let’s say not one but 90. Now let’s execute. It will fail because the value here is actually a string [03:53:20]and COALESCE is trying to return an integer. So that’s another big difference you have to be aware of. [03:53:25]You have to be aware of the silent truncation.
[03:53:30] Trevoir Williams So in this lesson, we’re going to look at the full insert, and I’ve kind of already written out the template [03:53:35]for what that insert statement needs to look like. And we have our scenario. [03:53:40]So let us take a look at the template first. Here we say insert into and then schema dot table name. [03:53:45]So especially in a database with multiple schemas like this one, [03:53:50]you definitely want to precede the table name with the schema name. [03:53:55]And then we list out all of the columns. Now the order of the columns doesn’t quite matter at this point. [03:54:00]Meaning, if I look at the currency table and I drop down columns [03:54:05]and I see them in this particular order, [03:54:10]I don’t necessarily have to write them back in that exact order, [03:54:15]but I do want to have a full representation of all the columns. So make sure you list all the columns [03:54:20]and then we say values and then state the different values that would go in. [03:54:25]So here, val 1, val 2, etcetera, these values have to match back into, [03:54:30]to the same order that the columns are listed in, [03:54:35]so that you don’t end up putting the name value per se in the currency code column [03:54:40]or vice versa, right? So whatever order columns appear in value should appear in as well. [03:54:45]So let us get started with our very simple scenario [03:54:50]and our simple table where we’re going to insert a new currency, which is the Cayman dollar [03:54:55]and the code for this, the currency code would be KYD. [03:55:00]So anytime you’re about to insert new data, especially in a database that already has data, [03:55:05]it’s always good to look at what the data appears like, right? [03:55:10]Before you try to do anything. So in this table, when we do a select top 1,000, [03:55:15]we’re going to see here that we have the currency code, we have the name of the currency and then we have a modified date. [03:55:20]So these are the columns that we want to represent in the insert statement [03:55:25]and definitely want to put in the appropriate values. So let us get started with that activity. [03:55:30]So we’re going to follow the template above. [03:55:35]We’re going to start off with our insert into and then I can just drag over the table name. [03:55:40]You could type it out, of course, and then we list all the columns. [03:55:45]So the first column here is currency code. [03:55:50]And once again, you can actually just drag over the columns so that you don’t have to type them manually. [03:55:55]So whichever one you find easier to do, go ahead and do it. But I’m just going to drag them all over, right? [03:56:00]And then remember that SQL can be written, um, [03:56:05]from left to as far right as your screen or your query window allows. [03:56:10]Now what I’m going to do, however, for formatting and readability is break the line here. [03:56:15]So the parenthesis in a new line, and then I’m just going to tab out the columns, [03:56:20]so we can see them all and then break line and then shift tab to bring those back. [03:56:25]So now we have the table name, open parenthesis, [03:56:30]the list of columns, and then close parenthesis. [03:56:35]Now what do we need? We need values. So we save values [03:56:40]and then we do the same thing with the parenthesis and I’ll just put those both there and then break them out and tab. All right? [03:56:45]So the currency code here needs to be the short code [03:56:50]which in this case is KYD that represents the Cayman dollar, [03:56:55]and then we’re going to insert the name, which is Cayman dollar and then the modified dates. [03:57:00]Now, you can try and look at the date on your computer right now [03:57:05]and try to put it in. But SQL has a built-in function for that. [03:57:10]And we’ve seen that SQL has several functions that work for us. [03:57:15]So get date actually looks at the time stamp on whatever computer the database server is on [03:57:20]and retrieves the date and time [03:57:25]for that particular moment when the script is run. [03:57:30]So this is a nice easy way to just get whatever date and time it might be. [03:57:35]So for that now, we have KYD for the currency code. [03:57:40]We have Cayman dollar for the name, and then we have get date for modified date. [03:57:45]So when I execute this, we see that one row was affected. [03:57:50]So we can be confident that this script ran properly. So if I go back over and do the select top 1,000 [03:57:55]from the same table and scroll carefully, [03:58:00]I will now see that there is KYD Cayman dollar [03:58:05]and there is that updated time stamp for modified date. [03:58:10]And that’s so simple and inserts are simple insert can be. Now, now that we know how the full insert works with one record [03:58:15]and with explicitly listing the columns, [03:58:20]let’s look at another variation of it. Now let us enter another currency code. [03:58:25]This time we’re going to kind of go digital and we’re going to use some crypto. [03:58:30]So let’s just say that we wanted to insert a new currency [03:58:35]and this time it’s supposed to be Bitcoin, [03:58:40]which is going to have the short code of BTC. [03:58:45]So another way that the full insert can look is that [03:58:50]we just have the insert into table and then we just have values. [03:58:55]So notice now I’m actually skipping [03:59:00]the listing of the columns, right? [03:59:05]So you don’t necessarily have to list the columns. If you do list the columns, you have to have just as many values as you see the columns. [03:59:10]And remember that the order matters when you list the columns. [03:59:15]However, in this situation where I don’t list the columns, I just start stating the values. [03:59:20]The values definitely have to be in the same order [03:59:25]as the columns would naturally appear in the table. [03:59:30]So I don’t have the liberty of mixing and matching in this situation like I could with this version of the full insert. [03:59:35]In this case, I have to be specific. So I can say BTC as a short code, [03:59:40]and then let us say I made a mistake [03:59:45]and said get date here as the name, right? [03:59:50]And then over here, I’m going to put in Bitcoin. [03:59:55]Now when I try to insert this, I’m going to get an error. Why am I getting an error? [04:00:00]Because Bitcoin is not a valid value for modified date. [04:00:05]So once again, the order definitely matters here. [04:00:10]The values must be in that specific order. So if I switch get date and Bitcoin around, [04:00:15]then I should have no problem because now everything should be a valid value [04:00:20]for the different data types. [04:00:25]So let me execute that again. And now we see that we inserted Bitcoin successfully. [04:00:30]Now the third variation of this full insert would be that and it’s not really a variation. [04:00:35]It’s more like an extension to either one of these [04:00:40]is the fact that if I have multiple values I want to insert in one statement, [04:00:45]I can actually just repeat this line for as many rows as I want. [04:00:50]So whether I list all the columns or not, I can have multiple values, [04:00:55]all comma separated, representing the new rows that I wish to insert. [04:01:00]So I just hit pause and I went ahead and created a few more lines. [04:01:05]And I think earlier I said you would repeat the values line, not the values line, [04:01:10]just the actual values. So let me, let me say that again, just to be clear. [04:01:15]So when you have multiple values that you want inserted in a single insert into statement, [04:01:20]you would say insert into whether you list the columns or not, the values, [04:01:25]and then you have the different sets of values. [04:01:30]So here we’re entering Ethereum. That’s one value, that’s one row. [04:01:35]Then we comma separate that from the next row and comma separate that from the next row, [04:01:40]and it goes on and on. And, of course, there’s no comma for the last one, right? [04:01:45]So now if I execute this one, I should see that I have four rows affected. [04:01:50]So remember that one row got affected this time, one row got affected this time. [04:01:55]Okay, fine. But this time I put in four new rows and four rows got affected. [04:02:00]And then, of course, if we go back and look, we’re going to start seeing the new value. [04:02:05]So there’s BCH and BNB, BTC and F, right? [04:02:10]So all of these new values are going in. [04:02:15]So as far as the full insert goes, these are your three options that allow you to just go ahead and put in values. [04:02:20]If you don’t like splitting up the values like this, you can always just have as many insert into statements [04:02:25]and then you change the rows according. [04:02:30]It would be the same effect, but, of course, much less typing because you have fewer insert into lines to write. [04:02:35]So that’s it for the full insert. [04:02:40]You can go, go ahead and play around with that. Um, choose a simple enough table that doesn’t have any foreign keys because [04:02:45]we’re going to look at how you insert related data coming up in this section. [04:02:50]Next, we’ll look at the partial insert. In this lesson, we’re going to be looking at the partial inserts. [04:02:55]Now the partial insert is not too different from the full insert. [04:03:00]It’s just that we can take a bit more liberty with the data, [04:03:05]but that also needs to be gauged. And I’m going to kind of walk you through this the different things [04:03:10]that you need to be aware of before we start looking at the syntax. [04:03:15]Now partial insert basically means that you can actually [04:03:20]choose exactly what you want to provide a value for. [04:03:25]With the full insert, we were forced to provide a value for each column. [04:03:30]And you see here, even if you didn’t list the columns, even if you didn’t list them, [04:03:35]you still had to provide the values for all, right? So that’s a full insert. [04:03:40]With the partial insert, it could be that you just wanted to put in the currency code [04:03:45]and not necessarily have to provide another value, like maybe the modified date. [04:03:50]So when you want to do a partial insert, it’s important to understand the data [04:03:55]and the different constraints that exist on the columns and understand the different liberties that you can actually take. [04:04:00]So if I expand the column definitions for the same table, sales currency, [04:04:05]we’re going to see that none of these columns is allowed to be null. [04:04:10]So that means even if I’m trying to do a partial insert, [04:04:15]I technically have to provide a value for all of these columns. [04:04:20]However, if I look in the constraints, I can see here that there’s a default constraint. [04:04:25]If you remember when we set up our default constraints earlier in the course, [04:04:30]there’s a default constraint on the modified date. [04:04:35]So even though it’s not allowed to be null, it means that if no value is provided by the insert, [04:04:40]then it will default to its own date. So let us take a look at the partial insert now. [04:04:45]So I can say insert into following the same syntax, [04:04:50]we’re going to use the same table once again. [04:04:55]This time I’m going to list out some of the columns. So I’m only going to insert into currency code [04:05:00]which there’s no default constraint on and it’s not allowed to be null. [04:05:05]And I’m going to insert into name which follows similar rules, [04:05:10]but I’m not going to list the modified date. [04:05:15]So I’m only going to provide values for these two columns. [04:05:20]And since this is a short query, I’ll just leave it like that. [04:05:25]And I’m going to say values and only provide the values for these two. [04:05:30]So here I’m putting in LTC and Litecoin. [04:05:35]That’s another cryptocurrency, right? So insert into this table only providing values [04:05:40]for these two columns and these two values. [04:05:45]So once again, I’m leaving out the modified date. So that’s why it’s partial [04:05:50]because I’m partially providing the data that needs to go in. And then the more columns that have defaults, [04:05:55]the fewer values that you are obligated to put in. So when I execute this query, [04:06:00]you’ll see one row affected. There was no error. [04:06:05]And if I go over and choose to look in that table again and look for Litecoin, [04:06:10]you’ll see here that the value for get date was automatically put in. [04:06:15]So I didn’t put it in, but then the default constraint here more than likely [04:06:20]would tell it that if there is no value provided by whoever is inserting the data, [04:06:25]then go ahead and do a get date by yourself. All right? [04:06:30]And that is how you can set up a default constraint, and that’s really it for the partial. [04:06:35]So once again, the partial update, sorry, the partial insert [04:06:40]really means that you can partially provide some values for some columns. [04:06:45]But once again, in doing that, it’s important for you to assess the table, [04:06:50]look at the constraints and understand the liberties that you can take in terms of leaving out some values [04:06:55]and what values you have to provide. So now that we have a better understanding [04:07:00]of the partial insert and the full insert, next, we’re going to look at working with related data. [04:07:05]So we’re going to go to another more complicated table [04:07:10]and look at the different things that we have to be aware of when inserting values that are foreign keys. [04:07:15]Welcome back. So here, we’re going to be looking at inserting related data. [04:07:20]Now, this is not anything that is too out there [04:07:25]based on what we’ve learned early. The syntax for the insert statement [04:07:30]basically follows the same format that we’ve been looking at. [04:07:35]Once again, what’s important is that we understand the constraints and the liberties that we can take when inserting the data. [04:07:40]So here we’re going to be inserting a new region currency, [04:07:45]and we’re going to be putting in that Cayman Islands as a country region currency. [04:07:50]So we already have the currency. And if we look at the table column definitions, [04:07:55]we’re going to see here that we need the country region code as well as the currency code. [04:08:00]So here’s where it’s important to understand what our primary keys [04:08:05]and foreign keys and look at the different constraints or keys rather, right? [04:08:10]So here you see that there’s a primary key set on both of them and they’re both foreign keys as well. [04:08:15]Now, what does this mean? It means that there can only be one combination [04:08:20]of the two at a time. So that’s why they’re both primary keys, right? [04:08:25]So you can’t have, say, JMD and Jamaican dollar and another entry of JMD [04:08:30]and Jamaican dollar. The, the pair can only exist once in the table. [04:08:35]So that’s why they are both primary keys. I will call that a composite key. [04:08:40]Now, they’re both also foreign keys, which means that the table doesn’t naturally have them. [04:08:45]They are both just values referencing values from another table. [04:08:50]So the currency code is a foreign key to the currency table. [04:08:55]See, currency code matches to currency code, [04:09:00]which means that country region code is coming from somewhere else. [04:09:05]So before we can go ahead and insert a value that, well, [04:09:10]we don’t know if it exists or not. We have to make sure that it exists in the primary key table. [04:09:15]So if we wanted to add Cayman Islands as a country region currency, we already inserted KYD as a currency. [04:09:20]So now we need to make sure that the actual country exists [04:09:25]before we can put in the country region code. So we can look for that country region table, [04:09:30]which is person dot country region. There we go. [04:09:35]We can do our select top 1,000 and that’s the wrong tab. Let me do that here. [04:09:40]So when we select top 1,000, we can just look through the list to see if Cayman Islands actually exists, right? [04:09:45]So we can do a manual scan. That’s 200 rows. [04:09:50]We can also just see where and let’s use up some of our select skills now where name is like [04:09:55]and we can just say Cayman modulus, right? [04:10:00]That’s Cayman modulus. So this is our wild card. [04:10:05]So once it starts with Cayman, it should come back. And then when we look, [04:10:10]we see here that we do have KY, Cayman Islands as a country region code. [04:10:15]So that’s excellent. So we have the country region code already and we just inserted the currency not too long ago, right? [04:10:20]The currency wasn’t there. The country was there. [04:10:25]The currency wasn’t there. Now the currency is here. [04:10:30]So now we can go ahead and put in the new country region currency. [04:10:35]And that’s what we mean by inserting related data. The primary key has to exist before we can enter the foreign key. [04:10:40]All right? So let us do this. So we say insert into [04:10:45]and our table is country, region, currency. [04:10:50]I notice the red squiggly lines, the red squiggly because we need the schema name. [04:10:55]So sales dot country region currency [04:11:00]and we say values and now we’re going to put in. [04:11:05]So remember that if we don’t list all the columns, [04:11:10]we have to provide all the values. So I can actually just do something like a partial insert here [04:11:15]where I’m just going to provide the… Let me do this the right way. [04:11:20]So open parenthesis after the table name, [04:11:25]and then we’re saying I’m providing a value for the country region code, and I’m providing a value for the currency code [04:11:30]and not for modified date because if I look on the constraints, [04:11:35]I see that modified date will get a value regardless, so that’s fine. [04:11:40]And then I’m going to say that I want KY as the country region code [04:11:45]and KYD as the currency code. [04:11:50]Now, once again, related data. So these two have to exist in whatever tables these two are referencing. [04:11:55]However, I’m confident that they do at this point [04:12:00]because I did my preliminary checks and I can run and I see here one row affected. [04:12:05]So that means if I look in this country, region, currency table, [04:12:10]I should now see that there is a KY to KYD mapping. [04:12:15]And there we go, KY to KYD. [04:12:20]So now the Cayman Islands is listed as a country region code. [04:12:25]And here we mixed and matched. We did a partial insert coupled with related data being inserted. [04:12:30]So let’s look at a bigger table. We want to insert a new sales territory [04:12:35]called Jamaica, right? So let us once again go [04:12:40]and look at our sales territory table, [04:12:45]so I can do a top 1,000 just to get an idea of what kind of data is there. So you have the territory ID, the name, [04:12:50]the country region code, the group sales, and row GUID [04:12:55]and modify date. [04:13:00]Okay. Now if I look at the column definitions, I’ll see here what is our foreign key is the country region code, [04:13:05]which definitely means that if I’m entering Jamaica here, [04:13:10]I must make sure that this exists. So I’m just going to say where the name is like Jamaica. [04:13:15]Does it exist? It does. So I’m good on that front. [04:13:20]So I do have something that I can use as that foreign key, [04:13:25]then group sales year to date, etcetera, all of those are dollar values and then the row ID, [04:13:30]this is what we call a GUID or a unique identifier, that’s another data type, [04:13:35]and then we have the modified date. [04:13:40]And if I look at the constraints so that I get an idea of what liberties I can take, [04:13:45]I see that there are several default constraints, right? So I have a default constraint [04:13:50]on most of the dollar value columns on the row GUID on the sales last year, [04:13:55]the modified date. So that means and that’s good because [04:14:00]if I’m just entering the territory, then obviously, I won’t have any values for these, [04:14:05]and this would be auto generated for me as well and modify it. [04:14:10]So really and truly, all I need to provide would be the name, the country region code, [04:14:15]and the group. Now why don’t I need the territory ID? [04:14:20]Well, I don’t need the territory ID because that’s a primary key. And if this table was designed with the primary key here [04:14:25]to be an identity column like we had done previously in the DDL section, [04:14:30]then this would auto increment. So all I really need to provide to get started would be the name, [04:14:35]the country region code, and the group. So let us get started on that one. [04:14:40]So I’m just going to say [04:14:45]insert into and this time it says territory. [04:14:50]I’ll just drag it over and then values. [04:14:55]Now, note, if I try to do this partial insert, I have to list all the columns [04:15:00]that I intend to enter data into, right? I’m sure you probably tried it [04:15:05]and saw that you got an error. So I can say name. I’m providing a name. [04:15:10]And then I’m going to say the country region code, [04:15:15]and then after that I need the group. Now once again looking at the values [04:15:20]that are already in the table, I see that for name I would actually put the word Jamaica. [04:15:25]So the name of the region is Jamaica, [04:15:30]and let me type that properly. Then for the country region code, [04:15:35]we can always double check with that region table and the country region code is JM. [04:15:40]So once again, that has to match entering related data. [04:15:45]And then for the group, I’m just going to introduce a new group [04:15:50]because the company has expanded into the Latin America region under which Jamaica falls. [04:15:55]So I’m just going to comment this one out and then let us execute this. [04:16:00]And here we see one row affected. [04:16:05]Now notice, notice how many columns were in the table and how few columns [04:16:10]I actually provided values for. But if I look in the table now, [04:16:15]I’m going to see that Jamaica is there. Here’s that auto incrementing ID, [04:16:20]so I didn’t have to provide that value. Jamaica, JM is in LatAm, and all of these are zero values. [04:16:25]The row ID is there, and we have a new modified date. [04:16:30]Now if I wanted to provide a row ID, [04:16:35]there is actually a built-in function for that as well. So I could have said row, row GUID. [04:16:40]Sorry. Let me just break the line and then I would provide new ID. [04:16:45]So that would be the function that generates a GUID [04:16:50]for that column. So we have get date for dates and we have new ID [04:16:55]for row GUID. All right? So this is basically what is being used on that default constraint for that row GUID. [04:17:00]That’s what’s providing that value. [04:17:05]So let me see if I can put in another one. Let me put in the Cayman Islands, [04:17:10]and let me, let me do that in a different activity. All right. So I just made a new comment, [04:17:15]insert new sales to sales territory with generated row GUID and Cayman Islands. [04:17:20]And then here we’re saying insert into sales territory name, [04:17:25]country region code group and row GUID. [04:17:30]And now I’m putting in the values Cayman Islands, KY LatAm, and the new ID. [04:17:35]So in case you’re not sure where the Cayman Islands are, [04:17:40]they’re a group of islands not too far away from Jamaica, so they’re actually in the same Latin America region, geographically speaking. [04:17:45]So when I execute this, I’m going to see one row affected, [04:17:50]and we’re going to expect to see similar results. [04:17:55]We have a new territory ID value, and we have a row GUID [04:18:00]because this time I generated it. But once again, the default constraint, [04:18:05]um, made it easy for me to have left that out. [04:18:10]So that’s basically how you go about inserting related data. [04:18:15]Those are the things that you have to be aware of. Always check with the original table to make sure [04:18:20]that the corresponding value is there. So you usually want to insert values [04:18:25]into the simple tables with no foreign keys first. [04:18:30]And then by the time you get to the ones with foreign keys, the values that they will depend on [04:18:35]are already in the original tables as the primary keys. [04:18:40]So now that we understand how we manage our data across tables with regular inserts, [04:18:45]partial inserts, or, you know, related data inserts, let’s now look at a situation [04:18:50]where we might want to create a new table and want to fill it with data [04:18:55]from another table, even possibly from another database, [04:19:00]and we’re going to look at that next. All right, guys. So in this lesson, [04:19:05]we’re going to be looking at the select into statements. Now this one is going to be a little fun and we’re going to go through different variations of this statement [04:19:10]and why you may use them. [04:19:15]Now generally speaking, select into statements are used to make copies of existing tables. [04:19:20]That’s maybe the most common use of them. [04:19:25]And the reason you may want to make copies could be that you want an empty table that’s identical to an existing one. [04:19:30]You don’t want to have to sit down and write out that create script from scratch, [04:19:35]or you want to make a backup of an existing table in another table so you can probably delete the previous one [04:19:40]and you have the backup and you can start the other one fresh. [04:19:45]There are several reasons that you may want to actually use this select into. [04:19:50]So let us look at a simple example of a select into. [04:19:55]And what we’re going to do is take a backup of, let me find one of these big tables. [04:20:00]Let’s use the purchase order details. So I’m going to just take a cursor look at the data. [04:20:05]This is top 1,000. And I think this… We’ve looked at this table for it had [04:20:10]a few 1,000 rows, right? So there are 8,845 rows in this table alone. [04:20:15]So once again, [04:20:20]you’d probably want to just make a backup of this table, probably truncate this one [04:20:25]or delete everything in it and let this one start from fresh. [04:20:30]And sometimes that’s done when a table grows too big. So you, make a backup, [04:20:35]truncate it, and then the software continues writing new records to a fresh table, [04:20:40]and you have the backup for historical purposes. All right? [04:20:45]So that is the kind of, um, scenario that we’re going to look at. So I select into is quite simple. [04:20:50]All we have to say is select star and that should be familiar, [04:20:55]but then we say into and then we state the name of the new table. [04:21:00]So let us say that I wanted to select into a table called same purchasing, [04:21:05]and I’m going to give it a different name, purchase order, [04:21:10]sorry, purchasing schema, and I’m going to call it purchase order detail, [04:21:15]backup 2023, right? [04:21:20]So for the year 2023, I’m going to be making that back up. I notice that that red squiggly has gone away [04:21:25]because it was saying you can’t select into an existing table. It has to be a new table. [04:21:30]So I have to give it a new name, but I’m selecting into that from [04:21:35]the original purchasing dot purchase order detail. [04:21:40]So when I execute this, you’re going to see 8,845 rows affected. [04:21:45]So let’s refresh the list of tables here in the explorer, [04:21:50]and then you’ll see that there’s a new table in town, [04:21:55]which is now a backup of the old table. And there we go. [04:22:00]Purchase order detail backup, 2023. So when I select top 1,000, [04:22:05]then we’re going to see all of our records matching the same records [04:22:10]that were in the original table. [04:22:15]And that’s how easy it is whenever you want to take data from one table and put into a new one. [04:22:20]So you don’t even have to go and create the new table first. It will automatically take the data, take the columns, take the data types, everything. [04:22:25]It’s pretty much identical, but it will not replicate the constraints, right? [04:22:30]So it will not indicate what is the primary key, what is a foreign key, [04:22:35]and what is computed. It just wants to look at the data, [04:22:40]make sure that it’s replicating the specific data types as needed, [04:22:45]and then it will just migrate that data. So that’s a nice and easy way to use that select into. [04:22:50]Now what if you only wanted some columns? So I’m going to switch over from the purchase order detail [04:22:55]and look at purchase order header. [04:23:00]And here, what if we only wanted maybe the purchase order ID, [04:23:05]the employee ID and the total view [04:23:10]and our motive and order date. All right. [04:23:15]So let’s get it. Let’s get our story straight. So on the purchase order ID, [04:23:20]we want the employee associated with the purchase order. We want the order date and total view. [04:23:25]Those are the only things that we want to replicate to a new table. [04:23:30]Well, just like with a regular select, [04:23:35]we can select exactly what we want as opposed to selecting star, right? [04:23:40]So here I can actually say select order. Oh, well, first of all, I’m going to change this from order detail to order header so that the IntelliSense will work with me. [04:23:45]So let’s try that again. So I want the… to select, [04:23:50]and I’ll just drop this down so I can get my columns. [04:23:55]So I want the purchase order ID. Let me just drag over. There are so many ways to do this that sometimes I get caught in analysis paralysis. [04:24:00]So I’m sure you can understand why sometimes I hit on these things, right? [04:24:05]So we want the purchase order ID, we want the employee ID, [04:24:10]wanted the order date, and finally wanted just the total due. [04:24:15]So that’s all we want to make a backup of, right? [04:24:20]And I’m going to call this one purchase orders, 2023, right? [04:24:25]I just want that. So I don’t want all the data. [04:24:30]We can still keep the main table with all the noise, [04:24:35]but we just want a snapshot of who sold how much on what date [04:24:40]and what purchase order that was. And we just want that snapshot for 2023. [04:24:45]Now please note before I even execute this, we can also say where, right? [04:24:50]So the same kind of filters that we can add to our regular select clause, [04:24:55]we can add them here. So it’s just a regular select query. [04:25:00]The only difference is that we’re not seeing from, we’re seeing into, [04:25:05]and we’re stating another table name here from the original table. And then we can do our where clause. [04:25:10]We can do our inner join, our group, everything that you would have done in a regular select query, right? [04:25:15]You can do all of those, and then all you are doing is putting all of the results into a brand new table. [04:25:20]So now that we have done, gone through that scenario, [04:25:25]let us execute this. We’re going to see down that we have purchase orders for 2023 [04:25:30]as a brand new table. So when I refresh and then go back. [04:25:35]I now see purchase orders for 2023 [04:25:40]and the specific columns that we selected will be present, right? [04:25:45]So that’s a nice, clean way to just get some data into a brand new table. [04:25:50]Another scenario, what if we wanted an empty table? [04:25:55]So I want another table that looks just like the purchase order detail, [04:26:00]but I don’t want any data in it, right? So right here, we can replicate this query. [04:26:05]I’ll just copy and paste and uncomment. [04:26:10]Of course, I’m just going to say purchase order detail. [04:26:15]Let’s just say new. And what I’m going to do here is [04:26:20]add on that where clause, and I’m going to put a condition that can never be equal to true. [04:26:25]All right? So this is going to be a weird condition [04:26:30]because all I’m saying is where one equals zero, select star. So this is never true. [04:26:35]So that means nothing will ever come back. So since nothing will come back and I’m selecting star into, [04:26:40]what it’s going to do is go ahead and set up the structure for this new table [04:26:45]based on the structure of this old table. And then it’s going to look at the work clause and say, okay, [04:26:50]where does one ever equal to zero in this table? That never happens even in real life, [04:26:55]and so nothing will be brought over. And the end result of this will be zero was affected. [04:27:00]However, I will have a brand new table available to me [04:27:05]called purchase order detail new. So that is a nice and easy way to create a brand new table based [04:27:10]on the structure of an old one with nothing in there. All right? [04:27:15]So there are several, like I said, several scenarios [04:27:20]where you may want to do something like this. Now, let us look at one final scenario, [04:27:25]and this is going to be like a bonus scenario as well, where we’re going to look at creating a new database [04:27:30]and then selecting into a table from the current database. [04:27:35]So I already wrote the script. I’m going to walk you through it, and it’s going to feature things that we’ve seen before [04:27:40]and everything can be put into context as we go along. So here, I’m going to switch over to the master database, [04:27:45]and from there I’m going to create a new database called AdventureWorks 2023. [04:27:50]Then I have the go keyword. So generally in SQL, [04:27:55]when you want to write a script from start to finish like this, [04:28:00]you have to put in the go keyword after you create the database, then you can switch over to whichever database. [04:28:05]Now, note, I have created this database, but I’m not going to use that database afterwards. [04:28:10]I’m using this original AdventureWorks 2019 database [04:28:15]that we are working with. But what I’m going to do is select into [04:28:20]and notice how fully qualified this name is. [04:28:25]So up until now, we’ve been working with the schema name dot table name. [04:28:30]However, every database has a default schema of dbo. And you’ve seen that previously in the course [04:28:35]where you have the dbo schema and you would have to actually go and create schemas for yourself [04:28:40]for outside of the dbo one. So here we select star into the new database [04:28:45]dot its default schema [04:28:50]just to keep things simple. And once again, casing doesn’t really matter. [04:28:55]But generally speaking, dbo is lowercase. So let’s just keep that form factor [04:29:00]and then the new table name. So we’re seeing select into this database [04:29:05]dot default schema dot this new table, because after I create the database, [04:29:10]I am not creating any table. Notice, there’s no create table [04:29:15]with the name and the columns. There’s none of that here. [04:29:20]But I’m just going to select from our purchase order detail table [04:29:25]into a new table for this new database. And what this will do is transfer all 8,000 records directly [04:29:30]from this existing database into the brand new database and table. [04:29:35]So when I execute this, you’ll see that 8,000 rows were affected. [04:29:40]So when I refresh my list of databases, I’m going to see one, my new database. [04:29:45]Then when I expand that, I’m going to see that I now have a new table. [04:29:50]And then when I look in that table, I’m going to see all of the data that corresponds [04:29:55]with the data from the old table. So in the same vein, [04:30:00]if it is that you needed to create another database and model it off of an existing database, [04:30:05]but you don’t want to sit down and write the queries manually and so on, [04:30:10]then you could actually use, you know, mix and match with the where clause [04:30:15]and the new database and table and just create the empty tables to match the existing ones. [04:30:20]So I think that’s it for our workshop on how select into works. [04:30:25]I can’t wait to see how you mix and match these scenarios [04:30:30]and make them work for yourself. But when we come back, we’re just going to do a quick review of everything that we’ve learned in this section. [04:30:35]So let us do a quick review of some of the scenarios that we looked at [04:30:40]and what are some of the things that we need to pay attention to when writing our insert statements. [04:30:45]So we started off by looking at the full insert and by extension, the overall, uh, [04:30:50]syntax of the insert statement. [04:30:55]So we have insert into and then we have the table name. [04:31:00]Sometimes it’s preceded by the schema. If it’s a default schema, you don’t need this. [04:31:05]So if it’s dbo, then you don’t necessarily need to specify that. But let us just say schema name dot table name [04:31:10]and sometimes the database name as well. [04:31:15]But, we can leave out the database name once we have the cart using statement at the top of the script or we make sure that we’re working with the correct database, right? [04:31:20]So we insert into schema dot table name. [04:31:25]We list out our columns, the values and the keyword value, sorry, [04:31:30]and then the list of values that correspond with the order that the columns appeared in. [04:31:35]So we looked at an example here where we inserted a new currency [04:31:40]and we listed all the columns and listed all the values relative to each column, right? [04:31:45]Then we went on to look at the fact that for the full inserts, [04:31:50]we actually don’t need to list the columns. But if we don’t list the columns, [04:31:55]we have to one, adhere to the specific order that we would see if we were to look at the description of the columns in the table itself. [04:32:00]We have to follow that exact pattern, [04:32:05]and then what we also need to do is make sure that we provide values for every column. [04:32:10]So even though I’m not specifying the columns here, [04:32:15]if I only provide two values, it will give an error saying that there’s an invalid number of values relative to the columns. [04:32:20]So you have to make sure you’re aware of that. [04:32:25]Then we also looked at the fact that if you wanted to insert multiple records in one insert into statement, [04:32:30]you can actually just list out each row and comma separates the group. [04:32:35]So open parenthesis, list out all the values, close parenthesis, and then comma, [04:32:40]and then you do that for as many. And then the last one, of course, has no comma. [04:32:45]All right? So here we inserted four new rows with one insert statement. [04:32:50]The alternative would be to write out several insert into statements like this. [04:32:55]So you can decide whichever one is easier slash cleaner for you and your purposes. [04:33:00]Then we looked at the partial insert. So the partial insert, [04:33:05]we can actually take liberty with which columns we actually want to provide values for. [04:33:10]So unlike previously where we didn’t list the columns and had to provide all the values, right? [04:33:15]Or pre or even before that where we listed some or all the columns rather and provided all the values, [04:33:20]here we can list some columns and provide some values. [04:33:25]But, of course, in doing so, we have to be comfortable with the constraints [04:33:30]and restrictions surrounding what values can actually be left out. [04:33:35]So we were able to leave out date modified here because by default the date modified will put in its own get date value. [04:33:40]So we don’t have to necessarily provide that. [04:33:45]But once again, do your background checks on the standard data before you attempt this. [04:33:50]Then we looked at inserting related data where it’s the same insert principles. [04:33:55]The only difference here is that whatever is a foreign key, we have to make sure it’s present in the original table. [04:34:00]So here for countries and currency, we had to make sure that we had KY [04:34:05]as a value in the table with the country region codes and KYD [04:34:10]as a value as in the currency code tables. [04:34:15]And that was the first one that we inserted. So once again, when inserting, always make sure you start off inserting into tables [04:34:20]that have zero foreign keys so that when you get to the ones with foreign keys, [04:34:25]your values are present already, and you don’t have any referencing conflicts. [04:34:30]We also looked at mixing a partial insert with related data inserts [04:34:35]and how looking at the default constraints helps us to make better decisions [04:34:40]and to write the cleanest and minimalistic code [04:34:45]as needed for an insert. Then we looked at our select into statements. [04:34:50]So select into is used to make a copy [04:34:55]of a table from another table, and it’s really just that simple, right? [04:35:00]So here we just said select into this brand new table from this other table. [04:35:05]And it’s a regular select statement where we can add where clauses [04:35:10]and inner joins and group buys and all these things, but whatever it is that is being selected [04:35:15]will go into the new table. So here you can select specific columns into the new table. [04:35:20]You just select star into the new table. You can also filter out records [04:35:25]if you just want an empty table that looks like the original table [04:35:30]by adding a where clause that would never be true. And then as a bonus, [04:35:35]we looked at creating a brand new database and then inserting from the old database into a table that didn’t exist in the new database, [04:35:40]and we saw how that went ahead and created that. So that’s it for this section. [04:35:45]I hope you enjoyed it, and I can’t wait to see [04:35:50]what you’re able to do once you’re comfortable with these concepts.
[04:35:55] Emar Morrison In this section, you learn about update statement and delete statement in SQL Server. [04:36:00]The update statement is a fundamental component of SQL that allows you to [04:36:05]modify existing data within a table, while the delete statement [04:36:10]allows you to remove data from the table. At the end of the section, [04:36:15]you’ll be able to use update statement to modify rows, update data using joins, [04:36:20]update data through table expressions, and delete data from the table using the delete statement. [04:36:25]So let’s head over to Management Studio and dive in. [04:36:30]The update statement follows this simple syntax, right? So you have the update clause, [04:36:35]then the table that you want to update, and the set specify the columns to be updated, right? [04:36:40]So you can have more than one columns being updated at the same time [04:36:45]and the value that it needs to be updated to. So you have the column and then the value that you are setting it to. [04:36:50]And the where clause that specify the condition that has to be met before [04:36:55]the update is done. To update specific rows in the table, we must specify the where clause.[04:37:00]Only the rows that meet the specified condition will be updated. [04:37:05]If the where clause is omitted, all the rows in the table for that column will be updated. [04:37:10]So let’s take a look at an example using the person table. [04:37:15]So now I’m going to write a select statement to query the person table. [04:37:20]Now I’m just displaying the data which is in the person table, right? [04:37:25]So if we observe the data carefully, we have our email promotion column. [04:37:30]Now what we want to achieve is to set the email promotion column to zero, so all the values must be zero for each record. [04:37:35]So we can write an update statement to achieve this. [04:37:40]So remember, it’s update. Let me push this down. The table name that you want to update which is person. [04:37:45]Now we are going to use set the column that we want to update, right, [04:37:50]which is email promotion, and then we are going to specify the value that we want to set. [04:37:55]So let’s execute this statement. The query has been executed successfully. [04:38:00]Now let’s do a select on the person table again. Now you can see that all the email promotion [04:38:05]has been updated. But what do we do if we only want to set the value for one record? [04:38:10]This is where the where clause come in handy [04:38:15]because not all the time when you need to do an update, you will need to update all the records for a column. [04:38:20]So here in the dataset, Rob doesn’t have a title, so we are going to give Rob a title of mister, right? [04:38:25]So what we need to do now is use our where clause [04:38:30]and we need to use ID that uniquely identifies Bob. So only Bob record gets updated. [04:38:35]So here I am going to use where, [04:38:40]we’re going to use a business entity ID because that uniquely identifies each person [04:38:45]within the person table. So we’re going to copy the statement and paste, right? [04:38:50]So this time the column that we are updating is the title column. [04:38:55]So we have to change the column from email promotion to title [04:39:00]and we are setting the value to mister which is a string. If we update this, [04:39:05]it will update all the rows for the title column but we don’t want that. [04:39:10]So now we have to filter the data based on a value that is unique, which is the business entity ID. [04:39:15]So we are going to say where business entity ID is equal to four. [04:39:20]So if we do not use a column that has a unique value, then more than one title will be affected. [04:39:25]Now if you want to be sure that you’re not making any mistake [04:39:30]and you’re ensuring that only one record gets updated, then you can always write a select statement [04:39:35]to check before you run the update. So now let’s execute the statement. [04:39:40]Now let’s square the person table again and we can see that Rob now has the title as mister. [04:39:45]Now if we look at our dataset again, Michael doesn’t have a middle initial [04:39:50]or middle name and he doesn’t have a title, right? So based on the two previous example, [04:39:55]if we’re supposed to update the title for Michael and the middle name, [04:40:00]you may be thinking right to update statement but you can achieve this in one update statement, right? [04:40:05]So let’s copy this statement. Let’s paste, right? So the column we’re updating is the title. [04:40:10]So we’re gonna keep the title as mister and then for additional columns [04:40:15]that you want to update, you’re gonna separate it by a comma and then specify the column name. [04:40:20]So in this case, it’s middle name and then you specify the value that you want to set. [04:40:25]So I’m going to give him a middle initial of B. Now we have to change the where clause, right? [04:40:30]And change the ID to that of Michael which is 10. [04:40:35]Now let’s execute this statement. Let’s query the person’s table again. [04:40:40]Now if you check row number 10, you can see that Michael now has a title of mister [04:40:45]and has a middle name of B. Now, let’s say we want to change the promotional email [04:40:50]to two for all the persons who lives in the city of Bothell, right? [04:40:55]But when we check the persons table, we can’t identify [04:41:00]the city of Bothell within the person table. So what we have to do to achieve this is to join the person table [04:41:05]to the business entity address and then join that table to the person address [04:41:10]which is this table. So let’s scroll down to the person table. [04:41:15]So the person table will join with the business entity ID with, [04:41:20]within the business entity address table and the business entity address table [04:41:25]will join with the person address table based on the address ID. [04:41:30]So let’s look at this query. So first, we want to do a query to ensure our query is working correctly before we do the update. [04:41:35]So here I have a query that is going to check the list of person who lives in the city of Bothell. [04:41:40]So let’s execute this statement to return all the persons who live in the city of Bothell. [04:41:45]Let’s execute. As you can see, we have a promotional email of one. [04:41:50]So we want to change this to two for all the persons who live in Bothell. [04:41:55]So let’s look at what the update statement will look like. [04:42:00]So the syntax doesn’t really change much. The only thing we add in here is from clause to make the joins with the other tables. [04:42:05]So it’s the same update, right? [04:42:10]You’re gonna specify the table that you want to update, the value that you want to set. [04:42:15]In this case, I am going to be setting it to two. Now, this section is where I am joining the person table [04:42:20]to the business entity address and then to the address to get the address of the persons [04:42:25]who live in Bothell. Without this join, I will not be able to update [04:42:30]the persons who live in Bothell. So I have to make this join because the Bothell column [04:42:35]is not in the person table. So let’s execute the statement. [04:42:40]So our statement was executed successfully. Now, let’s run the query again [04:42:45]to check for those who lives in Bothell to see if the email address [04:42:50]was updated, right? Not email address, the email promotion. [04:42:55]The email promotion was updated to two. So let’s go back to the initial query. We will query the persons table. Now let’s execute [04:43:00]and when we scroll down you can see that we have some columns equal to in the dataset, right? [04:43:05]So that’s how you can update records using join statements. All right. [04:43:10]So let’s look at another example using the join statement. [04:43:15]So here we have the sales table, right? Within the sales table, [04:43:20]we have sales persons but these sales persons belong to a different region. [04:43:25]So our goal is to increase the bonus of the salesperson in the United States by 50%. [04:43:30]We can check the sales territory table to see the list of territories [04:43:35]that are actually available. So I’m gonna do a select Astrid from sales territory. [04:43:40]Now let’s execute and we have US, CA, France, DE, AU, and GBP, right? [04:43:45]So now we have a select query that gets that data. [04:43:50]So let’s execute this. So based on this result, we have a couple salesperson [04:43:55]who are from the US region. So we have 14 records here. [04:44:00]Now let’s double check the salesperson table again to ensure we have the same record [04:44:05]while we have 17. However, we have three null territories so that’s fine. [04:44:10]So now we need to write an update statement that will update only the sales persons [04:44:15]who are in the US region. So first, we need the update command. [04:44:20]Then, we need a table that will be updated which is the salesperson table. [04:44:25]Then we have the set clause and we need to specify the column that we are going to set which is bonus. [04:44:30]However, in order to set the bonus we need to do a calculation. [04:44:35]But how are we going to do this? Right? So first we need to get the existing bonus, [04:44:40]then increase it by 50 and then update the column with the new value. [04:44:45]So we’re going to have equal bonus right, so we’re going to say plus, [04:44:50]now in bracket we are going to have bonus times 0.05, [04:44:55]so we are finding 50% of bonus adding it to bonus [04:45:00]and then setting it back to bonus. Now if you’re familiar with programming, [04:45:05]this can be rewritten a shorter way, right? So the next step is to include our where clause, [04:45:10]but in order for us to get to the where clause we have to join, [04:45:15]we have to join the salesperson table to the sales territory in order for us to add the country region of US in the where clause. [04:45:20]So we need a from statement. I’m going to copy this existing information which is here. [04:45:25]So it’s from the salesperson, right? [04:45:30]I’m aliasing the table as SP, and I’m inner joining on the sales territory. [04:45:35]Now I can add my where condition. So I’m going to say where country code [04:45:40]is equal to US. Now let’s execute. [04:45:45]Now let’s square the salesperson table again. Now we can see that there has been some increase in the values, [04:45:50]but I did not note anyone that was specifically in the US region, right? [04:45:55]So we’re going to do this again and give them another 50% increase. [04:46:00]So what we’re going to be doing this time is that we’re going to be noting the business entity ID of an individual who is in the US region. [04:46:05]So I’m going to use this query here and filter for US as well [04:46:10]as I’m going to add a column for the business entity ID. [04:46:15]Now let’s re-execute the statement. So business 275 [04:46:20]is in the territory of the United States, right? So now let’s execute the statement again to give the persons [04:46:25]who are in the US region another 50% increase must be nice. [04:46:30]Now let’s execute the statement again and we can see that [04:46:35]the bonus has increased by another 50%. So this command here can be shortened, right? [04:46:40]So we can say plus equal [04:46:45]and then get rid of the brackets and just keep the .05. Now let’s execute the statement again. [04:46:50]Now let’s execute the top query [04:46:55]and you can see that the bonus has moved from 9,000 something to 13,000. [04:47:00]SQL also allows us to update tables using expressions like command table expressions [04:47:05]or derived tables. So this query here could be rewritten using a CTE. [04:47:10]So if you remember from the previous lecture, [04:47:15]it goes by the syntax with the name of the CTE optional columns, right? [04:47:20]And then you see it has. Now for the add section, we’re going to be putting the select statement [04:47:25]that find the result that we want to update. [04:47:30]So in this case it will be the select statement, right? So I’m just going to copy this [04:47:35]and put it in the CTE. Now I’m going to have my outer expression. [04:47:40]So instead of giving them a 50% bonus this time, I’m going to be giving them a 50% decrease in their bonus. [04:47:45]So I’m going to say update CTE set [04:47:50]and I’m going to get the bonus instead of add I’m going to say minus. [04:47:55]Now let’s execute a statement. Now let’s run the select portion of the query [04:48:00]to see the results of the salesperson in the US region. [04:48:05]So if you remembered this was about 13,000. Now it’s down to 6,918, right? [04:48:10]Now let’s execute again and give them a 75% decrease in bonus this time. [04:48:15]Sounds a bit harsh right? Now let’s execute. [04:48:20]Now let’s execute the select statement again and it has decreased to 17,229. [04:48:25]So as you can see, using the CTE is more readable [04:48:30]than using the regular update statement with the join statement. [04:48:35]So to summarize, we use the update statement to change data within a table. [04:48:40]We can update a single column, multiple column. [04:48:45]We can filter the data using a where clause to set a criteria as to what we want to update [04:48:50]and we can also update data using joins as well as command table expressions. [04:48:55]In the next lecture, we’re going to be taking a look at the delete statement. [04:49:00]In this lecture, we’re going to be taking a look at how you can remove data from a table. [04:49:05]T-SQL supports two statements that you can use to delete rows from a table, [04:49:10]delete and truncate. The first one we’re going to be taking a look at is the delete statement. [04:49:15]With the delete statement, you can delete rows from a table. [04:49:20]You can optionally specify a predicate to restrict the rows to be deleted. [04:49:25]A typical delete statement look like this one here. You have the delete keyword [04:49:30]from the table that you want to delete the records from. [04:49:35]So you have the where and then the predicate. If you don’t specify a predicate, all rows from the target table are deleted. [04:49:40]As with unqualified updates, you need to be especially careful about accidentally deleting all the rows [04:49:45]by highlighting only the delete part of the statement [04:49:50]and forgetting to highlight the where part. So here I am creating a demo table [04:49:55]in the person schema called person demo. So I’m using a select statement to select from the person table [04:50:00]to create this table. [04:50:05]So I’m just gonna add a job table here first because it was already created, right? [04:50:10]So let me execute that. Now let’s execute to recreate the table. Now I’m just gonna do a select from the demo table, [04:50:15]and it’s a full copy of the person table. Now let’s scroll down. [04:50:20]Now our goal is to delete all the persons from the person table [04:50:25]who has an email promotion of two. So here I have a statement that achieved that delete from person demo [04:50:30]where email promotion equal to. Now let’s execute the statement. [04:50:35]Now let’s query from the demo table again. [04:50:40]Let’s scroll down see if we have an email promotion which is equal to two. So all the persons with email promotion two was deleted. [04:50:45]So our goal is to delete the other person from the table [04:50:50]that has a middle name of C, right? So we are going to have the delete [04:50:55]from specify the table which you want to run the delete from, the where clause, [04:51:00]and the column which you want to have in your expression. So it’s in this case it’s middle name [04:51:05]and the value is C. So here we have Patrick and Daniel with middle name C. [04:51:10]Now let’s execute this delete command. Now let’s do a query under person demo. [04:51:15]So all the users were deleted and our total roll count down as well. [04:51:20]So if you’re supposed to make a mistake and just execute this portion of the delete statement, then guess what? [04:51:25]All your data will be gone from the table. [04:51:30]So let’s go execute on the demo table and as you can see it’s empty. [04:51:35]So you have to be careful when you are running the delete command. [04:51:40]So far the tables that we have been using in this course are very small, [04:51:45]but in a more realistic production environment where the volume of data is likely to be much bigger, [04:51:50]a delete statement is fully logged. Now what do I mean by this? [04:51:55]The database of what is called a transaction log, right? And this is for recovery. [04:52:00]Now this is assuming the database is in full recovery model. [04:52:05]So all of what’s taking place is logged to the transaction log. So as a result of this, [04:52:10]large deletes can take a long time to complete. Now, such large deletes can cause transaction log [04:52:15]to increase in size dramatically. They can result in lock escalation [04:52:20]meaning that SQL Server escalates fine-grained locks like row locks [04:52:25]or full blown table lock. Such escalation may result in blocking access to all the table [04:52:30]by other processes. So the solution to this if you want to get rid of [04:52:35]all data out of your table is to use a truncate statement. [04:52:40]The truncate statement follows a syntax. Truncate table and the name of the table. [04:52:45]So if we want to truncate the person demo table, all we need to do now is write truncate table [04:52:50]and the name of the table that we want to truncate. [04:52:55]Now let’s do a query on the table to ensure that data is in it, right? [04:53:00]Now let’s execute the truncate statement. Now let’s query the table again [04:53:05]and as you can see we have no data within the table. So the truncate is way faster than the delete statement, [04:53:10]and this is mainly when you’re dealing with a lot of data in a table. [04:53:15]So the truncate statement is really an all or nothing approach. [04:53:20]The delete and truncate statements have a number of important differences between them. [04:53:25]The delete statement writes significantly more transaction log compared to the truncate statement. [04:53:30]For delete, SQL Server records in the log the actual data that was deleted. [04:53:35]For truncate, SQL Server records information only about [04:53:40]which pages were de-allocated. [04:53:45]As a result, the truncate statement tend to be tremendously faster. The delete statement doesn’t reset an identity property. [04:53:50]So if an identity property is associated with a column in the target table [04:53:55]by the delete, however, the truncate statement does. [04:54:00]Like with the update statement, we can delete using command table expression. [04:54:05]So I’m going to recreate the table and I’m going to write a CTE to delete the top ten records. [04:54:10]So it’s with the name of the CTE, I’m going to say CTE delete, [04:54:15]You see as open brackets. [04:54:20]Here select statement. [04:54:25]So I’m going to paste this here [04:54:30]and I’m going to say top 10. Now I’m going to say delete from CTE [04:54:35]underscore delete. [04:54:40]Now let’s execute this. Now let’s query the person table. [04:54:45]The total record count is 1,900,962. Now let’s do a query on the person table. [04:54:50]And as you can see for the person table, [04:54:55]it’s 1,900,972. Let me remove that. So just like with update, you can delete using joins and CTE. [04:55:00]So anything that you can do with the update statement, [04:55:05]you can pretty much do it with the delete statement as well. Now I’ve left the delete [04:55:10]and join statement for a good reason. So if we scroll down and try to do a delete using a join, [04:55:15]we are going to run into some problems, right? So let me change this to delete. [04:55:20]So in this case, we don’t need any set because we’re not updating. [04:55:25]So it’s delete from person, right? And we are going to try and delete [04:55:30]other persons from the person table who lives in the city of Bothell. [04:55:35]Now let’s execute the statement and you can see that it failed. [04:55:40]The delete statement conflicted with the reference constraint and the name of the constraint, right? [04:55:45]And it goes on to say the person address table and it also gives a column [04:55:50]which it has a conflict with. So this is because the constraints are enforced in referential integrity. [04:55:55]So if we try to delete a person, the person has a reference [04:56:00]in the person email address table, right? [04:56:05]So if we try to delete a person from the person table and there’s a reference in the person email address table, [04:56:10]then it will show on here because now we need to delete the data that is in the person email address as well. [04:56:15]So what I’m going to do now is that I’m going to create a database diagram [04:56:20]for you to get a clear understanding of this. So we’re going to need the address. [04:56:25]We need a person. We need a business entity. [04:56:30]I need a person from the person’s schema. [04:56:35]I need the business entity address, right? So let me select those here. [04:56:40]So this is the relationship between all of the tables. So let’s assume this [04:56:45]all of this information you are seeing here is one record. Now, if I delete this record from the person table, [04:56:50]I now need to go and delete the same record from the business entity person. [04:56:55]I then need to go and delete the record from the business entity address [04:57:00]and then as well as the address table, [04:57:05]and this will help to enforce our data integrity because if we delete the record from here [04:57:10]and the associated record from these tables are not deleted, [04:57:15]then basically we end up in a situation where we have missing data and then this data is [04:57:20]not of high integrity, right? So this is where the cascade statement come into play [04:57:25]which we’ll take a look at in the next lecture. In this lecture, we’re going to be exploring the cascade [04:57:30]and delete a bit more. What it does is that it helps to maintain the data integrity [04:57:35]by automatically deleting related records when a parent record is deleted. [04:57:40]In simple terms, it ensures there is no orphan [04:57:45]or invalid data remains in the database. So to get a better understanding of this, [04:57:50]let’s look at two tables. We have table one, which is departments and table two, [04:57:55]which is the employees’ table. Whenever we delete a record from the department’s table, [04:58:00]we want every employee that is associated with that department to be deleted. [04:58:05]So for example, if we delete the accounting department, [04:58:10]we need all the employees in the employees table that is in the accounting department to be deleted. [04:58:15]Now here’s the important thing to note. [04:58:20]The department ID in the employees table is a foreign key [04:58:25]which references the primary key ID in the department’s table. [04:58:30]When a row is deleted from the department’s table, we want all the associated rows in the employees’ table [04:58:35]to be deleted and this will be done based on the primary key [04:58:40]and foreign key relationship. Now the correct way to enforce this is enabling cascade and delete. [04:58:45]So let’s head over to Management Studio now to take a look at how we can achieve this. [04:58:50]So here I have a demo database which I’ll be using for this tutorial, right? [04:58:55]And I have a script that will create the department’s table, [04:59:00]the employees’ table, some insert scripts that will insert data in the department’s table [04:59:05]as well as the employees’ table, right? If you look at the employees’ table, [04:59:10]it has a department ID, [04:59:15]which is a foreign key, which references the department’s ID column, right? [04:59:20]So this is the relationship between the two tables. The ID in the departments is a foreign key in the employees’ table. [04:59:25]So let’s execute the script. Now I’m going to open a new session to the database. [04:59:30]So I’m going to do a select all from both tables. [04:59:35]So let’s execute both queries and let’s examine the data. [04:59:40]So here we can see that employee James and Marvin is both in the accounting department. [04:59:45]So what we’re going to do now is that we are going to be deleting the accounting department. [04:59:50]So it’s delete from department where ID equal to. [04:59:55]Now let’s execute this statement and as you can see we got arrow. [05:00:00]The statement conflicted with the reference constraint F key employee department, [05:00:05]random name, right? Conflict occurred in the database demo, table employees, [05:00:10]and the column department ID. The statement was terminated. [05:00:15]So basically, this error makes sense. What it is doing is that it is, [05:00:20]it’s preventing you from deleting the accounting department because it have associated data [05:00:25]in the employees’ table. So if we deleted the accounting department here, [05:00:30]then in the employees’ table, we’re left with employees with department [05:00:35]that has no reference in the department’s table, and this would mean that we have our fund data [05:00:40]or the data has lost its integrity. Because basically, [05:00:45]we’ll be saying James is in department two or say accounting, but when we check the department’s two, [05:00:50]there is no accounting. If that is the case, so if the delete add went through, [05:00:55]we would not be able to validate the department of James and Marvin. [05:01:00]So to resolve this, we enable cascade on delete. [05:01:05]So the first thing that we need to do is drop the constraint. [05:01:10]So it goes by the command alter table, employees drop constraint, constraint name. [05:01:15]We can take the constraint name from the arrow as well as we can double check this by expanding the database name, [05:01:20]expanding tables, expand the tables with the constraint, expand the keys folder. [05:01:25]Now let’s bring this across. And as you can see that [05:01:30]we have the foreign key employs the par 26 and the random name, right? [05:01:35]So let’s just copy this name. Now let’s execute this. [05:01:40]Now when we refresh the keys column, we are no longer seeing the constraint because it has been dropped. [05:01:45]Now we need to add the constraint back, but this time we need to include the cascade and delete. [05:01:50]So this is the command to achieve that. [05:01:55]So I’m gonna give it the same name and its department ID. Now let’s execute this. Now let’s run our delete statement again. [05:02:00]Let’s execute. Now when we do a select from both tables, [05:02:05]we’ll see that the department was successfully deleted, and the two employees that were in the accounting department [05:02:10]were also removed from the table. So what we did is that we altered the employees’ table, [05:02:15]add the constraints, specify the constraint name. The name can be anything read it, right? [05:02:20]And we’re adding a find key, which is department ID, which references the department’s table ID, [05:02:25]and this is the important piece which is undelete cascade. [05:02:30]Now when we refresh the keys again, we will see that the key was recreated. [05:02:35]So to summarize, using the delete and cascade clause [05:02:40]is a great way to enforce data integrity on your database when you perform delete operations.
[05:02:45] Trevoir Williams In this lesson, we’re going to take a look at views [05:02:50]and how they can be used and by extension designed by us. So because we’re using AdventureWorks, [05:02:55]which has some data available to us already. If you expand the database, [05:03:00]you’ll see a folder here called views. And then if you expand that, you’re going to see several table like, um, [05:03:05]objects listed under this folder. [05:03:10]Now let us just right click one of them and you’ll see that there are similar options that you would see when you right click a table. [05:03:15]And we’re going to just select top 1,000 rows. [05:03:20]Now when we select top 1,000 rows from this particular view, [05:03:25]which is called human resources dot v employee, [05:03:30]this view is showing us a snapshot of every employee’s information. [05:03:35]Now, if you remember from the tables, there are several places [05:03:40]that all of this information is actually found. [05:03:45]This information is not actually available in any one table because for the names we had to go to person, [05:03:50]for their job title, we had to go to human resources dot employee, [05:03:55]for their email address, we had to go to person dot email address, [05:04:00]for their address, we had to go to person address. And I think you get what I’m trying to say, that the information [05:04:05]about a person was actually spread across several tables. [05:04:10]Yet this view is allowing me to see everything in one literal view. [05:04:15]So what is so special about a view and why is it able to show me information [05:04:20]from several sources in one central place? So a view is basically just a wrapper [05:04:25]around a glorified select statement, right? [05:04:30]So we already looked at writing simple select statements from one table, [05:04:35]and then we looked at how we can use join statements to get information from different tables. [05:04:40]And the more and more complicated your select statement gets to get the information you want is the more and more [05:04:45]you want to actually preserve it. Now you don’t want to preserve it by saving the SQL file all the time [05:04:50]and then reusing the SQL file. Instead, what you can do is create a view, [05:04:55]which is now a database object that you and anybody else can now reuse going forward. [05:05:00]So let’s just right click on this view, the one that we just did. [05:05:05]And I’m going to go ahead and say script view as and create. [05:05:10]So now you’re seeing some shortcuts on how you can actually generate SQL [05:05:15]to show you how this object looks in SQL. [05:05:20]So I’m just going to say a new query editor window and it’s going to take a while to generate the script to show us. [05:05:25]And it’s going to have a few more things that we don’t necessarily use [05:05:30]or I didn’t necessarily highlight when we’re creating our objects. [05:05:35]And that’s just to say that they are technically optional. They’re kind of defaults, [05:05:40]but SQL, the SQL engine will take precautions to make sure that they’re there before it proceeds. [05:05:45]If we don’t explicitly state them, then it’s fine. [05:05:50]So, of course, we use AdventureWorks 2019 or the appropriate database. [05:05:55]We have our go keyword. These are optional, but they’re there anyway. [05:06:00]We don’t have to erase them. What I want to pay attention to is the query below. [05:06:05]And don’t worry, we’re going to write our own. I just wanted to give you a preview of what the syntax looks like in practicality [05:06:10]before we go off to create our own. And here you’ll see that [05:06:15]you have the key words create view and then it’s given [05:06:20]a schema name dot and the view name. So it’s not too unlike, [05:06:25]too much unlike the creative and create database, right? [05:06:30]We create the objectives of view. We give it a name and then you see as [05:06:35]and then look at that. This is just one big, one big select query. [05:06:40]It’s not even that complicated. It looks complicated [05:06:45]because now you’re seeing E and P, but I know that right now you’re saying, [05:06:50]oh, but those are aliases. And that’s exactly right. So the tables are aliased. [05:06:55]Some of the columns are aliased. So here PNT dot name is, is kind of abstract. [05:07:00]So it is specifying that is a phone number type, SP dot name is the state province name, etcetera. [05:07:05]So aliases are added to both tables and columns in this particular view. [05:07:10]And then it’s from the employee table, right? [05:07:15]Same employee table that we mentioned earlier, [05:07:20]human resources dot employee. And that is just going to be alias as E. [05:07:25]Then it’s going to join to person alias as P on the business entity ID [05:07:30]being equal to each other. So what I’m getting at is these are just a bunch of inner joins between the different tables [05:07:35]and our human resources employee table. [05:07:40]And some of them are joining between each other. But this is something that we have looked at. [05:07:45]This is not anything that is brand new. [05:07:50]So once again, a view is just an object that represents a select query that you don’t want to write over and over and over again. [05:07:55]That’s basically all it is, right? [05:08:00]So this huge select query, we don’t want to have to write every time we want to see the all the employees. We don’t have to write this [05:08:05]and try and find it in our files. So we just create a view to represent it. [05:08:10]Now let’s jump over to our new query window. [05:08:15]Once again, you can always click new query or use control N. And we’re going to… [05:08:20]I’m going to go back for one of the previous select queries that we had from our example, especially one that was kind of complicated with aggregation. [05:08:25]And that was the one where [05:08:30]we selected all of the sales persons and their totals for, [05:08:35]you know, since they’ve been with the company. [05:08:40]All right? So this is a query that I don’t want to have to every time I want to see this information [05:08:45]or a manager wants to see this information, I have to go and find the SQL file [05:08:50]that I save this query as. Instead now, I want to just add it to the database as a view, [05:08:55]and then I can tell my manager, hey, just go ahead and select from the view whenever you need to. [05:09:00]So I’m going to precede this script with my using statement, use the appropriate database, [05:09:05]and then I’m going to follow the syntax that was laid out for me [05:09:10]in the example that we looked at. [05:09:15]And here I’m going to say create view. So right above the select statement, [05:09:20]all I have to say is create view, give it a name, [05:09:25]and I’m going to put this one under the sales schema. [05:09:30]And I’m going to call it, uh, let’s call it sales, persons, totals. [05:09:35]Now, um, [05:09:40]I don’t… caps locked at me. Do that again. Now, in terms of, uh, [05:09:45]best practices, let’s look at the naming convention. [05:09:50]So, you know, I’m a very strict about that. [05:09:55]So here, you’ll notice that each one of these after the schema name is preceded by a small v. [05:10:00]That V is used to represent that it’s a view. All right? [05:10:05]Now, there’s no strict rule that you must use this. [05:10:10]You must prepend the name with a V. Some people use V, personally, [05:10:15]I use VW underscore, right? So that is how I name my views. [05:10:20]Within the context of this database, they use a V. [05:10:25]So what, what I’m getting at here is that this V or the VW underscore, [05:10:30]whatever it is, that prefix that you want to use is really there to get to, to, [05:10:35]to declare that this is a view. So anybody who looks at this will deduce all this is from a view, right? [05:10:40]If they looked at the results set from the data, [05:10:45]this is all they were looking at initially, right? And then they’re like, which table is that coming from? [05:10:50]And then they looked at the statement. They can easily tell, oh, it’s coming from a view. So they don’t spend hours trying to find it in the tables list. [05:10:55]So that’s all I’m trying to say, that, you know, those little things are important. [05:11:00]So I’m just going to follow the convention as set by AdventureWorks [05:11:05]and use a V to prefix it. So I’m saying create a view in the sales schema called [05:11:10]salesperson’s total and then the as keyword. And then I have the select query. [05:11:15]Now we can run our query and I am missing the go keyword here. [05:11:20]So the error here is that the create view must be the only statement in the batch, [05:11:25]this command. So I need a go keyword here. [05:11:30]Once again just following the example from the, [05:11:35]from the preview that we looked at after the use statement to use go. [05:11:40]So there are certain statements that you have to use go, go kind of resets the context of the script, right? [05:11:45]So as scripts get more complicated, I start working with certain types of objects, [05:11:50]realize that is the keywords start creeping in. So that’s fine. [05:11:55]We use go, and then now we’re saying create the view in that database. So when we execute this [05:12:00]command completed successfully and then if we refresh our views, we will now see, [05:12:05]I don’t remember the name. There we go. [05:12:10]Sales dot fee salesperson’s totals total. [05:12:15]And then if I select the top 1,000 [05:12:20]without me needing to know how complicated the query was, what syntax was used, the manager, [05:12:25]whoever is looking at this data doesn’t need to know or care. [05:12:30]They don’t have to look at all of this aggregation and whatever. They’re just looking at the data from a simple select statement. [05:12:35]So this could have easily been select star from that view [05:12:40]and it would give back the data. All right? [05:12:45]And notice that the columns have the aliases. They don’t have the original column names, [05:12:50]but they have whatever column names I would have specified when creating that view. [05:12:55]So that’s how views work. So I want you to go ahead and experiment with some of the other [05:13:00]more complicated, uh, select queries. It doesn’t have to be complicated select queries. [05:13:05]It’s just very convenient when the select query is very complicated, right? [05:13:10]So go ahead and experiment with the different select statements you have. [05:13:15]Create other views that you deem would be necessary or useful for your context. [05:13:20]Welcome back, guys. In this lesson, we’re going to be looking at managing the views. [05:13:25]So we went through several scenarios of why we would want to create a view. [05:13:30]But then after the view creation, of course, we might need to maintain the view. Maybe new data needs to be displayed and, you know, [05:13:35]just general maintenance. So now we’re going to look at how we manage the view after creation. [05:13:40]So on screen, [05:13:45]I would have gone to the view that we created just now and I right clicked it, [05:13:50]went to view script as create to and created this in a new query window. [05:13:55]Now, once that create view is the keyword, if I try to execute this again, I will get an error [05:14:00]because there’s already an object with that name in the database. [05:14:05]And I think we know by now if you try that create statement with the same object name [05:14:10]more than once you’ll get that error. So how do I modify this view? [05:14:15]Well, the easy answer is to change create into alter. [05:14:20]So if I say alter the view and that name and then maybe change something here, maybe, [05:14:25]let me say that, um, [05:14:30]first name and last name, I needed to alias those. [05:14:35]So first name right now is Pascal case. Let me just alias it to no longer be that. [05:14:40]And this one is now last name with a space. [05:14:45]Now, when I say alter view and run, you see commands completed successfully. [05:14:50]If I do a select top 1,000, now you’re going to see first name [05:14:55]and last name appearing with the alias names that we just set. [05:15:00]So that’s how you can simply make a change to a view. [05:15:05]You just need to say alter view and then change up your statement. [05:15:10]So they’re adding a new column, whatever it is you’re doing to your select statement. [05:15:15]That is how easy it is. Now, I went the route of right clicking script view as and said create tool. [05:15:20]But look at that, you could say alter tool. You could even say create or alter tool. [05:15:25]So if you’re not sure if the view exists already, you could actually generate a create or alter statement. [05:15:30]So if it doesn’t exist, create it. If it exists, then alter it according to whatever is here. [05:15:35]So there are several variations [05:15:40]of how you can manage the view after the fact. [05:15:45]Now, similar to when we want to get rid of a database or a table, [05:15:50]we would say drop table, drop database, etcetera. [05:15:55]To drop the view, we’ll just say drop view and call it by name. [05:16:00]And that’s how simple it is to remove the view. So remember that the view does not inherently store the data. [05:16:05]It is not where the data is going. The view is just an object that represents, [05:16:10]uh, probably complicated or tedious [05:16:15]select query that you don’t want to have to type every single time. [05:16:20]That’s what I view really is. So I just wanted to share those tips on how you can manage views [05:16:25]outside of the creating. You can alter it, you can drop it, [05:16:30]and you could also just right click and, you know, just delete from here. [05:16:35]But this is an SQL lesson. So we’re… I’m trying to limit, um, showing you how you can use the UI to accomplish certain things [05:16:40]and focusing more on how we can use SQL syntax to accomplish these things. [05:16:45]In this lesson, we’re going to be looking at variables. Now, what is a variable? [05:16:50]A variable is a temporary object that is used to store data during the batch execution period. [05:16:55]So that’s just a fun so way of saying that we have a temporary location [05:17:00]where we are storing maybe off the beat values, maybe non data related values [05:17:05]during the execution of a script. Now, why would that become useful? [05:17:10]Maybe we needed to store a static value [05:17:15]that we use for calculations throughout and we don’t want to repeat the value [05:17:20]because when we edit the script, we want to edit it in one place, which is at the variable level instead of in the script. [05:17:25]There are several ways you may use them and that when you get into using [05:17:30]stored procedures and functions and you’re definitely going to see [05:17:35]how these variables become absolutely necessary. [05:17:40]But we’re going to keep it simple right now. We’re just going to look at the like a basic, a few basic examples [05:17:45]of how you can create and use variables. Now, to create a variable, [05:17:50]you need a declare keyword and then you use the at sign [05:17:55]and then you give the variable a name. [05:18:00]So let us, let us say, uh, temp message. That is my variable. [05:18:05]Then I’m going to say as and define its data type. So if it’s temp message, [05:18:10]then more than likely it would be a string or a VARCHAR. [05:18:15]So I’m going to set that to VARCHAR, maybe 100, [05:18:20]and then I’m going to assign a value to it right now. So I can just say, um, testing variables. [05:18:25]All right? So once again, declare at sign [05:18:30]and the name and that sign is not optional. [05:18:35]So make sure you put on the at sign and then as and once again, no spaces. [05:18:40]So you can say temp space message and just camel case it to make your life easier, [05:18:45]really and truly, instead of trying to wrap it in braces [05:18:50]and put in spaces. [05:18:55]And that doesn’t seem to work either, right? So really and truly is just at sign and Camel case [05:19:00]or Pascal case block of text that’s appended to that at sign [05:19:05]as and then VARCHAR 100 in this case is our data type. [05:19:10]But whatever data type you deem necessary, whether it’s an integer or double, [05:19:15]whatever it is at the time you use that and then it’s equal to [05:19:20]and then we have our value here. Now, if I execute this, it does nothing. [05:19:25]It just says commands completed successful, which is just a way of saying, well, [05:19:30]I executed the command and there was no error, but there’s nothing here that is useful, right? [05:19:35]So what if we wanted to actually see something? I can use a print keyword here [05:19:40]and I can say print out what is intent message. [05:19:45]Now, if I execute this, you’re going to see testing variables. [05:19:50]All right? So that is [05:19:55]what we printed out of this message variable. [05:20:00]Now, another way that we could actually initialize or set a value in the variable instead of doing it in that one line [05:20:05]is we could use the set keyword and say at temp message [05:20:10]is equal to and I will place the same. [05:20:15]I’m going to say testing set variables, right? [05:20:20]And then when I run that, there’s a value set. All right? [05:20:25]Another way that you might see done or you might end up doing it rather, [05:20:30]is that we select and then we see the variable. So this is a select statement, [05:20:35]but we’re selecting the variable with its value. [05:20:40]So testing select variable, variable. There we go. Right? [05:20:45]There’s no from, notice, no from or anything. [05:20:50]So we’re just doing a select variable equals that value. [05:20:55]And then if we print, we see that it was, it also set the value. [05:21:00]So now that we understand how to create and set values, [05:21:05]let us take this up a notch. And we’re actually going to write a full select statement now [05:21:10]and see how we can actually, um, use it in a select statement to store [05:21:15]maybe a value that we want to use later on. [05:21:20]So I’m just going to comment all of this out and then let’s start off with a fresh variable. [05:21:25]So I want to declare a variable. I’m going to call it, let’s say, highest sale, [05:21:30]uh, figure. [05:21:35]And this one is going to be a decimal. [05:21:40]And with decimals, you want to state the size. [05:21:45]So 10 comma 2 to say 10 digits and 2 decimal places. [05:21:50]So that’s our decimal data type. So now that we have this highest sale figure, [05:21:55]I wrote this query. I wrote it already. So I’ll just walk you through what it’s doing. [05:22:00]It’s saying I want to select, I want to select the top one. So we have seen select top and that number already. [05:22:05]We haven’t seen one. We always see 1,000, maybe 200, [05:22:10]but we’re selecting the top one this time. And all I’m selecting is the max total view, [05:22:15]which is the highest sale amount [05:22:20]from our salesperson stable and inner joining. So this is very similar to the, [05:22:25]the query that we used for the view in the previous lesson. [05:22:30]But I’m just modifying it a bit to only get the max and to order by the max total view descending. [05:22:35]So that means we want the highest total view at the top going down. [05:22:40]And then that is why I’m selecting the top one. [05:22:45]So if you’re wondering how would I get the highest value of something? [05:22:50]This is a way you could do it or the lowest value or something. You could always just say, uh, select top one. [05:22:55]So out of all of the results, I would come back from here. [05:23:00]I’m ordering by the highest and then selecting that highest. [05:23:05]And that’s basically all it’s doing. But what I want to do is put this value inside of the variable, right? [05:23:10]So I don’t necessarily want it to print out the table [05:23:15]because it would print out the one value here. [05:23:20]That’s fine. But I don’t want it to do that. I want it to just store it in this variable [05:23:25]because maybe I want to use that value in another query somewhere else, right? [05:23:30]So I’m just going to say highest total figure here [05:23:35]is equal to the data that is coming back. [05:23:40]And then I don’t need to alias the column anymore. [05:23:45]So look at this now. It’s the same select query. And that’s why I showed you the select query first. [05:23:50]And then all I’m saying is variable is equal to the value that is in this column, right? [05:23:55]So when I execute this, it will tell me, okay, [05:24:00]will tell me I need to declare the variable because I only highlighted this area. [05:24:05]So if I execute all of this and I think I don’t need to highlight it. So let me just do that again. [05:24:10]So execute everything. Commands completed successfully. [05:24:15]Notice, no results came back and no results were printed here. Just told me everything is okay. [05:24:20]So now I want to see did this variable actually get that value? [05:24:25]So what do I do? Print that and then I can execute this by itself. [05:24:30]And of course, once again, must be declared because it’s, it’s temporary within the statement. [05:24:35]So that’s why I keep on making that mistake, just to make it clear that this variable exists [05:24:40]for the duration of this execution and that execution. [05:24:45]And once it is done, that variable is done, right? So every time the script executes, [05:24:50]it has to declare, has to set the value and use the value. [05:24:55]And once that is done, that’s done. So let’s do that again. [05:25:00]And here you see that we have our value. All right? And then, of course, [05:25:05]we know that we can format it as currency for once. I can leave you to do that. [05:25:10]But what I’m getting at here is this is how you would select into the variable a value from an actual SQL statement. [05:25:15]Now let’s go through one more scenario and then we can move on. [05:25:20]And in this scenario, I went back for that original query. [05:25:25]So this is the one that we use just now to create the view. If you want to retrieve it, [05:25:30]you can go back to the reference files for a select section [05:25:35]or of course you can always just right click on the view that we created together [05:25:40]and you can just see script view as creative and you will get that query as part of it. However, let us proceed with this. [05:25:45]So this time I want to check [05:25:50]or I want to be able to manipulate the values. What if I wanted to do like a calculation to say, hmm, what would the numbers look like [05:25:55]if they were twice as much or thrice as much, something like that? [05:26:00]So here I can declare a variable. [05:26:05]Let us say, uh, multiplier. You know, just something. [05:26:10]And then as and I’ll just say int and let me just give it a value right now. [05:26:15]So let’s say two. So now I have a variable called multiplier [05:26:20]and its value is two. So remember I said that it’s a nice, [05:26:25]easy way to set a value one time without needing to change, because now if I wanted to say, [05:26:30]all right, what would count times two look like? I would have to say count times two hear [05:26:35]count times two here, right? And then if I said, what does three look like? I have to change every two into three. [05:26:40]Now when using a variable, I can set the two one time here and then I say, [05:26:45]what would it look like times that multiply our value? All right? [05:26:50]So as I do this and then execute and I commented on the previous query, [05:26:55]so that’s fine when I execute. [05:27:00]Now you’re seeing the numbers as twice as much. I said, what would they look like if there were 10 times as much? [05:27:05]Look at this 10 and then execute. [05:27:10]And sorry about that. Let’s try that again. There we go. [05:27:15]So now 10 times more. All right? So just having a variable makes calculations slightly [05:27:20]more efficient because I don’t have to change that value manually in several places. [05:27:25]I can do it in one place. So these are just some ways that you can start using variables [05:27:30]maybe in your little calculations, [05:27:35]in your reporting, and they are very useful for [05:27:40]quickly storing values in between SQL statement operations. [05:27:45]Now we’re going to move on to looking at functions. And then when we’re doing functions, then you’re going to see [05:27:50]why these variables actually can serve a more useful purpose in a bigger, [05:27:55]more advanced SQL object type. [05:28:00]So see in the next lesson. Now we’re going to look at the concept of functions. [05:28:05]Now functions can be very fun, and it’s important that we understand [05:28:10]and appreciate them for how they work. [05:28:15]Before we look into creating our own functions, however, let us review the fact that there are functions that are built into SQL [05:28:20]that help us to accomplish certain things. So if we in our database expand programmability [05:28:25]and then we’ll see functions and you see here that I was already kind of looking at some of them, [05:28:30]but you’ll see that you have the table value functions [05:28:35]and you have scalar valued functions, both of which have some functions [05:28:40]coming with us, um, coming to us from the AdventureWorks database. [05:28:45]And we can look at those later on how they work. But before I get into those that came with the database, [05:28:50]I want to look at those that come with SQL Server, any SQL Server instance, [05:28:55]regardless of the database you’re working with. And to see those, [05:29:00]you can actually expand system functions and then you see categories of functions. [05:29:05]Now we have looked at functions before, namely aggregate functions. [05:29:10]We have looked at some date time and string functions as well. [05:29:15]So I did mention that there are several functions that are built in. [05:29:20]And here you can actually see the name of the function. And if you expand it, you can see the parameters that it takes. [05:29:25]So it takes for average. It expects an exact or appropriate number [05:29:30]or numeric value, and then it’s going to return an integer decimal money [05:29:35]or float kind of value, right? So in using functions, [05:29:40]sometimes you’re not sure how they work. You can always look here in the system functions. [05:29:45]Probably have to do a bit of digging to find out exactly where that function might be. [05:29:50]So like in the date time functions, we have the month, year functions. [05:29:55]We also have get dates. We have used get date before. [05:30:00]So what we can do here is do a little example. [05:30:05]And these are all examples of scalar valid functions, [05:30:10]which is why we’re going to use the built in ones to see what a scalar valid function is. [05:30:15]And then we’re going to look at how we can build our own. So let us say that I wanted to select… [05:30:20]Um, I wanted to see the month [05:30:25]as a value different from the year as a value [05:30:30]and the day as a value, but all of that coming from a particular date, right? [05:30:35]So let’s use a variable. All right? So we looked at variables [05:30:40]and I’m going to say date value. Let’s just call it that as date time. [05:30:45]Let’s call it date time too. All right? Now we can always set the value here [05:30:50]and I’ll just say get date. We know get date from before [05:30:55]because get date returns the current timestamp. How do I know? [05:31:00]Well, I can always go down here and hover over, get date and look at the description [05:31:05]returns the current system, date and time, and it takes no parameters [05:31:10]and returns a date time. So that’s what I’m saying, that all of that information is available to us. [05:31:15]So, now I can do a select statement and I’m going to call the month function. [05:31:20]Well, let me do a year first. So I’m going to call the year function [05:31:25]and then I’m going to give it the date value. So the year function [05:31:30]is designed to take a parameter, a date time parameter, [05:31:35]and it returns an integer so I can give it the date value variable, right? [05:31:40]And I’ll just alias it as year. [05:31:45]Now, notice year is a keyword because it’s the name of the functions, so I’ve to wrap it there, right? I think we are past all of that already. [05:31:50]And then month, I’m going to give it date value as well as month. [05:31:55]And then final one is day. [05:32:00]So all of these need a date time value [05:32:05]in order to carry out the operation. [05:32:10]And I am here mixing and matching my casing for the as keywords. [05:32:15]So let me just fix that. Remember being consistent. All right. [05:32:20]So when I execute this, I’m now going to end up with three printouts, right? [05:32:25]Three columns, one for year, one for month, one for day. And that is what we mean by a scalar value. [05:32:30]It took a value and it returned a discrete value. So here year is giving us back one value. [05:32:35]Month is giving us back one value. Day is giving us back one value. [05:32:40]That’s a scalar valued function. So now that we have an understanding of what a function is [05:32:45]and how our scalar valued function works, let us go ahead and create our own. [05:32:50]So I’m just going to clear this out and I’m going to walk you through the syntax to create a function. [05:32:55]So as with most objects in SQL, when we want to create them, [05:33:00]we start off with the create and then the object name, and then we give our functions a name. [05:33:05]Now if you look in the list of scalar value functions that already come with the database, [05:33:10]you’ll notice that the naming convention here is the pre… they prepend [05:33:15]the function name with UFN. So once again, [05:33:20]this is important for easy identification of the object type. [05:33:25]UFN, I’m sure here means user defined function. [05:33:30]Um, generally speaking, personally, I just use FN. So once again, it doesn’t really matter. [05:33:35]You can come up with your own prefix just as long as you’re consistent. [05:33:40]So I’m going to say get average sales, uh, for a year. All right? [05:33:45]So we’re creating a function that when given a year, we want to tell, [05:33:50]or return rather what the average sales for that particular calendar year was, right, [05:33:55]based on the data in the database. So, of course, [05:34:00]I’m naming my function accordingly. Then after we have this, [05:34:05]we’re going to follow it up with a pair of parentheses. And then in these parentheses, [05:34:10]we’re going to define the parameters that we want, right? [05:34:15]So here we want to add the parameters to the function. [05:34:20]Now, parameters once again would be the value that this function receives. So in the case of month, day, year, [05:34:25]just like we saw, the parameter they received was a date time. [05:34:30]So in this case, I want to define a variable called year [05:34:35]and it should be a data type of integer. So I’m telling this function [05:34:40]that it should expect an integer value that we’re going to call year. [05:34:45]Then we’re going to tell you what data type it should return. [05:34:50]So after accepting a value of type integer, which represents the year, [05:34:55]it is expected to return a decimal. So why am I using decimal? [05:35:00]Because it’s average sales. It’s money. So obviously we’re going to have decimal places. [05:35:05]So you just say what data type it’s expected to return. All right? [05:35:10]Then we say as and then begin and write as a type of begin, [05:35:15]I’m just going to type end so that I don’t forget at the end of this entire typing episode, right? [05:35:20]So we begin and end, so here in between begin and end is where [05:35:25]we actually put in the logic for the function. [05:35:30]So the first thing that we want to do is declare the return variable. [05:35:35]So the return variable basically means what is that variable that is going to store that scale our value [05:35:40]after the operation or during the operation. [05:35:45]And that’s the value that we’re going to be returning. So once again, we need a variable. [05:35:50]So we just looked at variables and we know how to declare them. [05:35:55]So this variable is going to be called average sales amount. [05:36:00]Remember that we prepend the variable name with an at sign and then we give it a data type. [05:36:05]And this data type, generally speaking, should match the data type [05:36:10]that is going to be returned because we’re actually returning [05:36:15]whatever value goes here. Now, you’re not restricted to one variable. [05:36:20]You can have several variables and then, you know, you do your operations, maybe have some math in between, [05:36:25]whatever it is your function needs to do. But the reality and the end result is that whatever data type you declared here, [05:36:30]that should be the data type that is ultimately returned. [05:36:35]So that means you always need a variable as many variables as you may have. [05:36:40]You will always need a variable that represents the same data type [05:36:45]as the one that you said is going to be returned. So now that we have at least one variable, [05:36:50]which is going to store our scalar value, we’re going to add our T-SQL statements [05:36:55]to compute the return value. So let’s just write this query out quickly. [05:37:00]And it’s not going to be a difficult query. We’re just going to select. [05:37:05]And then we looked at the fact that we can select from the database directly into our variable, right? [05:37:10]So we’re going to select into our variable called average sales amount [05:37:15]and we’re finding the average for total use. [05:37:20]I’m just writing this query, um, total view. [05:37:25]And then we’re selecting from [05:37:30]the table for sales order detail, not details, sales order header, right? [05:37:35]So I’m listing to drag that over. So we know that we’re looking in sales order sales, [05:37:40]that sales order header, and we’re averaging the total view column. [05:37:45]And then we’re going to add our where clause where the year and look at this, [05:37:50]we can use our another scalar function inside of the one that we’re defining, right? [05:37:55]So we’re looking for the year value associated with order dates [05:38:00]and we want where that is equal to [05:38:05]the incoming year value as our variable, so you see. [05:38:10]Uh, let me fix my typing. There we go. So let’s go through this again. [05:38:15]I think these two, at least this part is straightforward [05:38:20]because we know about aggregation. We’ve worked with this table before. [05:38:25]So this table has all of the header information for the sales, and we just want the average of the sales. [05:38:30]We’re storing that value inside of our local variable called average sales amount, [05:38:35]and then we’re going to filter relative to the year. [05:38:40]So we’re saying given any year 2020, 2010, 2015, [05:38:45]once a year value is provided, come here, square this table, filter it by that year value. [05:38:50]So that’s why we did year of the order date [05:38:55]is equal to that year that we got. And then once you have filtered it, [05:39:00]go ahead and get the average and store that average here. [05:39:05]So now that we have filled our variable with the result of the query, [05:39:10]what do we need to do? We need to return the results of the function. Now, remember, you might have several queries, [05:39:15]you might have several operations. So as many T-SQL statements as you need, [05:39:20]you define all of them in that space. But the end result is that you’re going to return [05:39:25]that variable that now stores the value that corresponds with the return data type [05:39:30]and the actual value that should be returned by your function. [05:39:35]So that is how we go about creating a function, right? Create function, give it a name, define the parameter or parameters. [05:39:40]If you have more than one, you comma separate them. That’s fine. [05:39:45]And, and their data types, of course, what it returns as begin. [05:39:50]And then we define our function and then we end. [05:39:55]Now we complete all of this with our use statement and go directive at the top of the script [05:40:00]so that we know we’re targeting the correct database for this function [05:40:05]and we are going to do the go. [05:40:10]So when I execute, you see commands executed successfully or completed successfully. [05:40:15]When I refresh, then we see that we have our new user defined function [05:40:20]that we can also expand and see that it’s accepting that integer parameter called year. [05:40:25]So now let us take it for a spin. So I’m going to open up a new query window. [05:40:30]And quite frankly, this is a scalar valid function. So it’s going to work the same way that would have used month [05:40:35]and year and average and so on. So we can use a select query. [05:40:40]And what I’ll do is select. Let me just start by selecting star [05:40:45]from our sales order header table. [05:40:50]Let’s make sure that we get back our results here. All right? [05:40:55]And then what I’m going to do is precede the star with or let me, [05:41:00]let me just say total of, total view, right? [05:41:05]I’m going to proceed total view with a value that represents our function value. [05:41:10]So if I see, uh, [05:41:15]I can actually drag over the name of the function, so let me just do that. [05:41:20]So I’m selecting and then the function name and then the function takes that parameter of 20 of a year, [05:41:25]which I’m going to put in 2011. [05:41:30]And I’m also going to add a filter. This, this query is not very well laid out, so work with me a little. [05:41:35]So we’re selecting the average, get average sales for year 2011, [05:41:40]and then we have the total due. And then I’m going to say where year [05:41:45]of order date [05:41:50]is also equal to 2011. So what this should do is bring back for the year 2011, [05:41:55]all of the total view and also show me the average sales for that year. [05:42:00]And here we have it. So this is the function value coming back [05:42:05]and then this would be the different total due, um, for the year 2011, right? [05:42:10]So, of course, I can alias this now to see average sales, right? [05:42:15]And there we go, [05:42:20]average sales total due. And there are several things [05:42:25]we could have done here. We could also have declared [05:42:30]a variable so I could say declare. And now I’m just putting a little swag on it. [05:42:35]So declare at year as an integer, right? [05:42:40]And I’m going to initialize it to have some value, let’s say 2011. And then instead of putting in the raw 2011 value here, [05:42:45]I can just use that year variable. So like I said, it does help us to reduce the repetition, right? [05:42:50]So by changing this one time, [05:42:55]I can make this now 2010 [05:43:00]and, okay, there are no average sales for 2010, 2012. There we go. So average sales of 2012 [05:43:05]and showing me the differences. So I’m just showing you that this is how you would really use the scalar valid function. [05:43:10]Now, there is a template, so you don’t necessarily have to commit all of this to memory. [05:43:15]The fact is in SQL survey, you can actually right click scalar valid functions [05:43:20]and click scalar valid function. And it literally gives you that template outline. [05:43:25]It has a few things that I didn’t put in, but once again, these are, generally speaking, optional. [05:43:30]You can go ahead and state who the author is and give it a description, [05:43:35]But the layout is the same. All it’s saying here is create function and then give it the function name. [05:43:40]So anything that is in a… an angle bracket, you’d want to replace with your text, right? [05:43:45]Here, the parameter name and the parameter data type. [05:43:50]Exactly what we did, the function data type. What is it returning? [05:43:55]Right? Be clear. Here’s your result variable and its data type. And then here’s a T-SQL statement [05:44:00]and then return to result VAR that you declared here. [05:44:05]So you can use that, that template if you don’t necessarily want to commit all of this to memory. [05:44:10]But the fact is it’s the same thing. So go ahead and create some functions [05:44:15]and get some practice with that. So we just looked at scalar valued user defined functions. [05:44:20]Now in this lesson, we’re going to look at table valued user defined functions. [05:44:25]Now the difference between the table valued function and the scalar valued function [05:44:30]is that the table valued function is actually going to bring back a tabular structure worth of data, [05:44:35]whereas a scalar valid one only brought back one value. [05:44:40]So for this exercise, what we’re going to do is bring back a set of products [05:44:45]that are over a certain number in terms of inventory. [05:44:50]So as usual, we start off by assessing the different tables and the data that’s available to us, [05:44:55]and then we formulate how we’re going to approach the scenario. [05:45:00]So we have a product table. And in that product table, it’s just a list of all the products, their names [05:45:05]and their numbers and other maybe relevant details. [05:45:10]There’s also a product inventory table which shows for each product by ID, [05:45:15]its location and the quantity. [05:45:20]So what we’re going to do is create a table valued function [05:45:25]that we’re going to put in a certain quantity. Let us say that we want all products [05:45:30]that are greater than a 100 in quantity, and then we’re going to write a query that’s going to bring back all of the inventory numbers [05:45:35]as well as relevant product details, all as the result of the function. [05:45:40]So let’s get started with that. [05:45:45]So I’m going to open up a new query window. [05:45:50]And, of course, we start off with our use statement and that’s, and that’s followed by our go. [05:45:55]And then we’re going to say create function and then give it the name. So it’s the same layout, [05:46:00]at least in the first line, create function. And then we’re proceeding with the UDF [05:46:05]just to keep the naming convention consistent. And then I’m calling this one get products with inventory greater than. [05:46:10]So that’s kind of a mouthful, but I think it’s clear [05:46:15]what we’re doing with this function. And then I can tell it’s that it should receive a variable. [05:46:20]So I’m going to say, uh, count. Let me just call it count. [05:46:25]And this will be an integer data type. Then I’m going to say as… [05:46:30]Sorry, not, I was going to say returns table. [05:46:35]So remember, with the scale that we have to see, it returns whatever data type. [05:46:40]In this case, the table is the data type because it’s expected to return a tabular structure worth of data [05:46:45]as opposed to one value of one data type. [05:46:50]And then we say as and then return. [05:46:55]Then we define a query that will meet the needs of the function. [05:47:00]So in this case, we’re going to select and let’s just start off by selecting star. [05:47:05]And when building out this query, it’s really just a select query. [05:47:10]So you want to test it and make sure that it meets your requirements before you proceed. [05:47:15]So we’re selecting star from production dot product. [05:47:20]And, of course, that is not the only table that we need, [05:47:25]we also need product inventory. So I need to do what? I need to inner join [05:47:30]the product inventory. So I’m going to call this one. [05:47:35]I’m going to alias this as P and I’m going to alias this one as PI. And I kind of use PI. Let me say PIV. [05:47:40]So inner join production, sorry, [05:47:45]product inventory on P dot product ID being equal [05:47:50]to PIV dot product ID. [05:47:55]All right. So remember, this is your inner join stuff [05:48:00]that we did in the select section of this course and it’s coming right back. [05:48:05]So if I run this statement, notice I just highlighted the query area and run it. [05:48:10]Now I’m seeing that, yes, my join is working. I’m seeing all the data points. [05:48:15]And then I can now say which exact columns I need because I don’t need to return all that data. [05:48:20]So I would probably want to bring back P name. [05:48:25]I would want to bring back P dot product number. [05:48:30]Let’s see what other data point might be necessary. [05:48:35]I don’t think I need more than the name and the product number. [05:48:40]And then let’s just say that I want to bring back the location. [05:48:45]So the location could also be important because this would say that at this branch there’s 100, [05:48:50]but at this branch there’s 300, right? So I think it would be worth bringing back the location name, [05:48:55]not just the ID, right? But before I go into location, [05:49:00]let us just add PIV dot quantity. [05:49:05]And now let us inner join the location. [05:49:10]so we can actually state the location that this quantity is found at. [05:49:15]So that’s just another inner join. So I can just do inner join [05:49:20]and the location table is right above. So I can just drag over location. [05:49:25]I’ll just call this LO on and look at this now. I have to join these two tables. [05:49:30]So, I mean, sometimes it is that you inner join the table directly on the table that’s been selected from. [05:49:35]But remember that we’re always going to join based on what two tables have in common. [05:49:40]So product has nothing in common with location of our product inventory [05:49:45]has a location ID and location obviously would also have a location ID. [05:49:50]So I can inner join on PIV dot location ID [05:49:55]being equal to LO dot location ID. [05:50:00]And then I can bring back the location name, so I can say LO dot name. [05:50:05]Now, I have two columns just called name, right? [05:50:10]So remember, that’s why it’s important to prefix with the, with the alias of the table. [05:50:15]But I’m just going to alias these columns. I’m going to call this product name [05:50:20]so that we’re clear that this name refers to the product name. We’re going to alias this one as location. [05:50:25]All right? [05:50:30]And then let us look at this query. I notice I’m only selecting the select. [05:50:35]So we haven’t created a function yet. Instead, we’re building the query and refining the query. [05:50:40]And now we see here that we have just the columns that we want. All right? [05:50:45]Now, let us say that I want to filter this query [05:50:50]based on the incoming parameter so I can see where PIV dot quantity [05:50:55]is greater than or equal to [05:51:00]whatever count is. And I made a mistake earlier. [05:51:05]The location is not the branch. It’s just the area within the space. All right? [05:51:10]So that’s why location is. Well, that’s fine. It’s still useful. [05:51:15]Now, working with the PIV dot quantity is greater than or equal to at count. [05:51:20]At this point, we definitely need to create a function because count will not exist unless it is coming in through the function. [05:51:25]So let me go ahead and press F5 and just execute this entire construct. [05:51:30]And I have completed that successfully. [05:51:35]So now if I go back and refresh or at least look in my table valued functions, [05:51:40]refresh that. Now I see that I have the function ready for use. [05:51:45]So how do I use this? Let’s open up a brand new query window. [05:51:50]And at this point, the table value function [05:51:55]will act like a table or like a view. So I can simply say select star from [05:52:00]and then reference this functions. I’ll just drag it over. [05:52:05]So that is our user defined function that we just created. [05:52:10]And then, of course, it takes our parameters. I have to provide a value. So let us say that we wanted all items with an inventory over 800. [05:52:15]So if I put that in and press F5, look at that, [05:52:20]it’s bringing back the table. So that’s all it really is. It’s just a wrapper around an SQL statement [05:52:25]or a select statement. And you’ve… At this point, you know, [05:52:30]that is not the only construct that allows you to kind of abstract [05:52:35]and make a select statement reusable. We’ve seen it with views. [05:52:40]Um, we’ve seen it even with stored procedures. But at this point, [05:52:45]it’s kind of easier to manipulate the data a bit more because here we can do a bit more with what we select. [05:52:50]So I could actually select here and I could put this into a temp table, [05:52:55]run calculations, embellish the data a bit, and then return another dataset. [05:53:00]So the fact is that the function creates a wrapper that allows me to still manipulate the data in ways that I probably could not [05:53:05]with a regular view. [05:53:10]So these are little things that you can pay attention to when you’re creating your user defined functions and in this case, the table valued ones. [05:53:15]So go ahead and practice that [05:53:20]and make some other functions that you think would be useful for your purposes in this database.
[05:53:25] Emar Morrison In this video, you learn how to use the beginning and end statement [05:53:30]to the opposite of T-SQL statement into a statement block. [05:53:35]Begin and end statement define a statement block. [05:53:40]A statement block consists of a set of SQL statements that execute together. [05:53:45]A statement block is also known as a batch. In other words, if statements are sentences, [05:53:50]the beginning and end statements allows you to define a paragraph. [05:53:55]It follows the syntax of using the begin keyword, right, then the statements that you want to execute [05:54:00]and then the end for termination of the block statement. [05:54:05]So let’s head over to Management Studio for a demonstration. So here I have a simple block statement. [05:54:10]Here you have the begin, which is the start of the block, [05:54:15]and here is the body of the block, or we can call it the paragraph, which is the multiple statements to be executed [05:54:20]and here we have the end which signifies the end of the block. [05:54:25]So all I’m doing is that I’m declaring an integer ID, [05:54:30]I’m selecting the max business entity ID from the person table [05:54:35]and assigning it to the ID variable and the print statement is displaying the ID that we found, right? [05:54:40]So the print is a function which takes a string parameter to be displayed. [05:54:45]So if we execute this, you’ll see that we have a person ID of 20777. [05:54:50]Then it’s important to note that [05:54:55]you could also have nested blocks, that means block within a block. [05:55:00]So here we could have again begin and we have an end for the end of the block, [05:55:05]and here in the body we’ll have the statements that we want to be executed. [05:55:10]So let’s copy and paste this again. So instead of finding max, [05:55:15]we’re going to find the min. So I’m gonna say min person ID here [05:55:20]and max person ID. Now let’s execute this. [05:55:25]You can see that the min person ID is one and the max person ID is 20777. [05:55:30]So to summarize, we can use the begin keyword in SQL [05:55:35]to mark the starting point of a logical block of statements and we use the end keyword [05:55:40]to specify the closing point of the logical block in SQL. [05:55:45]In this video, you’ll learn how to use the if else statement to control the flow of a program. [05:55:50]The if else statement is a control flow statement [05:55:55]that allows you to execute or skip a statement or statement block based on a specified condition. [05:56:00]So the following illustrate the syntax of the if statement. [05:56:05]If the Boolean expression evaluates to true, then the statement block [05:56:10]in the begin and end block is executed. Otherwise, the block statement is skipped [05:56:15]and the control of the program is passed to the statement after the end keyword. [05:56:20]Note that if the Boolean expression contains a select statement, [05:56:25]you must enclose the select statement in a parentheses. On the condition in the if clause evaluates to false [05:56:30]and you won’t execute another block, you can use the else clause. [05:56:35]The following illustrate the if else statement. Each if statement has a condition. [05:56:40]If the condition evaluates to true, then the block statement in the if clause is executed. [05:56:45]If the condition is false, then the block code in the else clause is executed. [05:56:50]SQL Server also allows you [05:56:55]to nest an if else statement within another if else statement. [05:57:00]So let’s head over to Management Studio to get practical. [05:57:05]In order to demonstrate the use of the if else statement, I’ll be starting out with a simple program. [05:57:10]So this program will simply check if our number is greater than 10, [05:57:15]and if that is the case, then it prints yes. [05:57:20]So I’m going to start with begin my end statement. I’m going to declare a variable. [05:57:25]I’m going to call this variable num, and this is of type int. [05:57:30]And here I can say equal to 10, right? So I’m initializing the variable right away. [05:57:35]Now the semicolon is not required. However, I’m just putting it there. [05:57:40]So the next line is if I have to check my expression here, [05:57:45]which will evaluate a true or false. So this is where I am putting the condition. [05:57:50]So if number is greater than 10, right, we’re going to print yes. [05:57:55]Now let’s execute this. So basically, we did not get a result. The program executed successfully [05:58:00]because here we are checking if the number is greater than 10. [05:58:05]However, the number is exactly 10. So let’s change this and put 12. [05:58:10]So now, we have yes being displayed. So you may be wondering, [05:58:15]where’s the begin and the end for the if statement? If you’re using a single statement after the if, [05:58:20]then you don’t have to use the begin and the end. [05:58:25]However, if you want multiple statements to be executed after the if statement, then you have to specify the begin and the end. [05:58:30]So let’s demonstrate this, right? [05:58:35]So I’m going to copy and paste a print, yes, And I’m going to say yes, yes, yes, exclamation, right? [05:58:40]So if we execute this, both statements will be printed, right? [05:58:45]Now let’s change the number to 10 and see what happens. [05:58:50]Let’s execute. Now we are getting yes, yes. [05:58:55]Why is this so? This is because like I explained earlier, without the begin only the first statement [05:59:00]will be controlled by the if statement. So to fix this, [05:59:05]we need to specify begin and end. Now let’s do a little tab to format this. [05:59:10]Now let’s execute the program again and you can see that we did not get any output this time. [05:59:15]So now you should be seeing the importance of the begin and the end statement, [05:59:20]or in other words the importance of the block statements. [05:59:25]So let’s make this program a little bit more useful or smarter. [05:59:30]So the first condition, we are checking if the number is greater than 10. However, if it’s not greater than 10, [05:59:35]we are going to say the number is not greater than 10, right? That’s all we’re going to say. [05:59:40]So this is where we’re going to use the else statement. So for the else statement, [05:59:45]because we’re going to be using a single line of code, we could simply say print [05:59:50]the number is not greater than 10. Now when we execute this, [05:59:55]we should get our result. The number is not greater than 10. [06:00:00]However, if we’re using multiple statements in the else block, [06:00:05]then we would need to specify the begin and the end just like we did in the if section of the statement, right? [06:00:10]Now remember, we can also have nested if. [06:00:15]So I’m just going to copy this block of code and I’m going to get rid of this. [06:00:20]I am going to change the variable to number two, right? [06:00:25]So here we could simply say, let’s give that some space, if number equal 10. [06:00:30]So here, I’m just gonna simply print the number is 10. [06:00:35]So let’s go over this from the top. So here we have the begin, here we have the end for the block, right? [06:00:40]Another way we could do this is use the set command. [06:00:45]So we could say, set num2 equal to 10, right? [06:00:50]That works as well. So this is another way to initialize our variable. [06:00:55]So here we are checking if a number is greater than 10. [06:01:00]So we’re in the begin section of that block and here is the end of that block. [06:01:05]Now this line of code is checking if number is greater than 10, right? [06:01:10]So I’m going to change this to greater than or equal to 10, so this block will get executed. [06:01:15]So here we are saying yes, the number is greater than or equal to 10. [06:01:20]Now here I am going to check if the number is equal to 10, [06:01:25]then I am going to say hey the number is 10. Now let’s execute this block of code. [06:01:30]So yes, the number is greater than or equal to 10 [06:01:35]and the second line is saying yes it is 10. But what if we change this number to 11? Right? [06:01:40]What will happen? Now let’s execute and find out. So it’s only saying yes, [06:01:45]the number is greater than or equal to 10. This block of code, [06:01:50]which is checking if number two is equal to 10, did not evaluate to true. [06:01:55]So this line of statement did not get executed. So now let’s look at a practical example using our query. [06:02:00]So I’m just going to copy this block of code again. [06:02:05]I’ll be getting rid of these statements, and I’ll be keeping this else statement here. [06:02:10]So what I’m going to do now is that I’m going to modify this block of code to find a person [06:02:15]with a specific business entity ID. So if this business entity ID is not found, [06:02:20]then we’ll print the error message saying the person was not found. [06:02:25]So let’s change this here. So I’m going to change the variable to be ID [06:02:30]for our business entity ID. So here I’m going to write a select statement that return the person [06:02:35]with the specified business entity ID. This is just a select statement that find a person [06:02:40]based on the provided business entity ID [06:02:45]which I’m using as a variable. So now in the if expression, we need to check if we found the result. [06:02:50]However, if we check the BID, then definitely we will have a value in that, [06:02:55]in that variable. But what if no record was found, right? [06:03:00]What will the result be? Statement will still evaluate to true, right? [06:03:05]So we have a system variable called row count. What row count does is that it returns the number of rows [06:03:10]affected by the previous statement, right? [06:03:15]So here I’m going to check if row count is greater than zero. [06:03:20]So if row count is greater than zero, that mean we have found some data, right? [06:03:25]So here in the begin block once record is found, [06:03:30]I’m going to print a statement that says record of person with business entity ID [06:03:35]has been found. So here we need to print the business entity ID. [06:03:40]Now in order to achieve this, right, [06:03:45]we have to now do a concatenation of the business person ID [06:03:50]which is stored in the variable, right? So in order to do this, we have to end the original string, [06:03:55]use the plus, which is used to concatenate strings, right? [06:04:00]So we’re gonna say a plus and here we need to specify the variable that we need to be concatenated to this string. [06:04:05]So I’m going to see at BID. [06:04:10]So now I need to add the rest of the string which is has been found. [06:04:15]Otherwise, we could see that person with the business entity ID was not found, [06:04:20]so let me copy this print statement here and I’m just going to put it in the L section. [06:04:25]So we’re going to say has not been found, right? Now if we execute this block, it will fail. [06:04:30]Conversion failed when converting VARCHAR value, right, [06:04:35]to data type int. So the BID is an integer [06:04:40]and before we can pass it to the print function, we have to cast it or convert it to a VARCHAR. [06:04:45]So here we’re going to use a cast function [06:04:50]and I’m going to say cast BID as int. So let’s do the same thing for the second print statement. [06:04:55]Now let’s execute this again. So my bad doesn’t be int, but VARCHAR. [06:05:00]Now let’s execute the statement again and we can see that the result was returned successfully. [06:05:05]Now let’s check the message section. You can see one row was affected. [06:05:10]Record of person with business entity ID was found. [06:05:15]Now a space need to go here. Now let’s set a business entity ID [06:05:20]that does not exist. So let’s say a negative 21. Now let’s execute this statement again [06:05:25]and no record was returned. Now let’s check the messages. [06:05:30]Record of person with business entity ID 21 was not found. [06:05:35]So using if else statement is a great way to manage the flow of your program [06:05:40]and manage errors within your transactions. The SQL Server while loop [06:05:45]is used to repeat a block of statements for a given number of times [06:05:50]until the given condition is false. The SQL Server while loop starts with the condition [06:05:55]and if the condition result is true, then the statement inside the begin and end block will execute, [06:06:00]otherwise, it won’t execute. [06:06:05]So basically, it suggests that a while loop may execute zero or more times. [06:06:10]So let’s take a look at the syntax. So first, the condition in the while loop is tested, right? [06:06:15]If the condition is true, the statement or query [06:06:20]inside the begin block will be executed. If the condition is false, [06:06:25]it will skip the begin and end block and execute other statements outside of it. [06:06:30]So with this graphical representation, you should get a better understanding, right? [06:06:35]So if the condition is true with that is in the diamond, then it will continue [06:06:40]and execute the code, right? And while that condition is true, [06:06:45]it goes back again and check the condition. If it is true, then it goes back inside the block of statement [06:06:50]and then execute it. Only when that condition is false, [06:06:55]then it will exit from the loop. So within the loop, [06:07:00]we must have an arithmetic operator to increment or decrement the value. [06:07:05]So let’s head over to Management Studio to take a look at an example. [06:07:10]So here I have a script that will print the sum of all the numbers 1 through to 10. [06:07:15]So here I’m just declaring two variables, number one, num, and total. [06:07:20]Here is my while condition. [06:07:25]Here I’m checking if number is less than or equal to 10. [06:07:30]If number is less than or equal to 10 then I go on to the begin block, right? [06:07:35]And within the begin block, all this code will be executed. [06:07:40]So here I’m just setting the total by adding total plus num. [06:07:45]This line is basically the counter or the control for the loop. So this line [06:07:50]will gradually increase num until it reaches 10. When it reaches 10, [06:07:55]that’s when the loop will break. So let’s execute this. And here, I have a total of 55. [06:08:00]Now we can also put a print within the loop. So each time it runs, it displays the total. [06:08:05]So let’s execute, and here we have the result. [06:08:10]So what happens in the while block is that each time it prints the current total, [06:08:15]while outside of the while block, it wait until everything is aggregated and then it prints the total. [06:08:20]Now if we were supposed to remove this line from the while loop, [06:08:25]then the while loop will just continuously run without stopping so I executed it just now. [06:08:30]And as you can see, it’s just executing, executing, executing. [06:08:35]So this is because we no longer basically have a counter variable to control the while loop, right? [06:08:40]So currently, num is one, right? So it goes into the while loop, print total, [06:08:45]goes around again, check num is still 1, it is less than 10, so it continues to run. [06:08:50]Why? Because num is not being incremented here. [06:08:55]So num will continuously cover one, and this program will not end. [06:09:00]You have to stop it manually. So as you can see, if we look at the result, [06:09:05]it went up to a pretty decent value. So without any form of control to break the loop, [06:09:10]you’ll end in a situation where you have an infinite loop. [06:09:15]There’s another way we can exit a while loop and that is by using a break statement. [06:09:20]So the syntax for the break statement is really straightforward. It goes by the syntax break, right? [06:09:25]And then you have here a semicolon, and that’s literally how you’ll use a break statement. [06:09:30]Anything that comes after the break statement in the loop will not be executed, right? [06:09:35]So in this original loop, let me copy and paste this. [06:09:40]So within this loop, we are incrementing num by one, right? [06:09:45]So in the previous example, when we commented this line, we ended with an infinite loop. [06:09:50]So now I’m going to replace that statement with the break. Now let’s execute this and our output is only one. [06:09:55]So what happened was that once the condition here was evaluated to true, [06:10:00]we went directly into the while loop. We set the value of total [06:10:05]and we set total plus one. But immediately, we break, [06:10:10]so the total here was not executed. [06:10:15]The one that executed was the one which is outside of the loop. [06:10:20]So to confirm this, we can say outside and we’re going to put the same statement inside [06:10:25]and replace outside with inside. Now let’s execute this just to confirm [06:10:30]which one of the statement was executed. So as you can see, [06:10:35]it is the one that said outside because the break stopped the loop here [06:10:40]and immediately exit. We can also couple the break with the if statement to exit the loop. [06:10:45]So only when a condition is met, we exit the loop. So in this while loop, [06:10:50]what I’m going to do is that I’m going to check if num is equal to five, [06:10:55]and if num is equal to five, then we exit the loop, right? So this is just for demonstration purposes only. [06:11:00]So if at num equals five, we are going to break. [06:11:05]Now let’s execute this. We also need to uncomment this line here [06:11:10]that is doing the set. Let’s put in some space here to make it more readable. [06:11:15]So now let’s execute this block of code and let’s see what happens. [06:11:20]So based on the output, the inside statement got executed three times and then it break. [06:11:25]And then once it break, it jump exactly to the end, right? [06:11:30]And then print this line here. So that is how we got outside 10. [06:11:35]So once you can understand the simple queries, there will be no challenge in understanding the more difficult queries. [06:11:40]In this lecture, we are going to be taking a look at the SQL case statement. [06:11:45]The case statement in SQL Server is similar to the control flow statement if else. [06:11:50]This statement evaluates a series of conditional expressions [06:11:55]provided in when and returns a result set. So let’s take a look at the syntax. [06:12:00]Input expression is an expression you want to check. [06:12:05]So for instance, it could be a column that you want to operate on or even a variable. [06:12:10]The when clause tests multiple expressions, the query will compare the value of the expression [06:12:15]against the input expression. If it is true, the result expression is returned. [06:12:20]The result expression is returned if the test expression is equal to the input expression, right? [06:12:25]And if they are not equal, [06:12:30]then the default expression will be returned. So here I have a query [06:12:35]that returned employee job title, birth date, marital status, hire date, and gender. [06:12:40]So let’s execute this query and examine the result. [06:12:45]So when we take a look at the marital status column and the gender column, [06:12:50]both of them are initials. [06:12:55]However, let’s say we wanted to present the data and say if there’s a M, then we want the result to show male [06:13:00]or if there’s a F, then we show gender. [06:13:05]Then we can rewrite this query using the case statement. So here we have the case, [06:13:10]the expression to be checked, which can be like a column or a variable, right? [06:13:15]And then we have the when clause and the value to be evaluated, right? [06:13:20]So when the gender is M, then output male. When the gender is F, then output female, else, not applicable. [06:13:25]And to end the statement, we use the end and we have the alias [06:13:30]as gender, right? So if we execute this, [06:13:35]you’ll notice that you are no longer seeing M, but instead you are seeing male [06:13:40]and female in the result set. We could also do the same for marital status. [06:13:45]So let’s copy this. But instead of gender this time, we’re going to check marital status. [06:13:50]So if the marital status is S, [06:13:55]then we’re going to say single. If the marital status is M, then we’re going to say married. [06:14:00]So instead of end as gender, we’re going to end as marital status. [06:14:05]Let’s remove this one from the initial output. Now let’s execute. And now that you can see that [06:14:10]we have single and married representing marital statuses. [06:14:15]So using the case statement is a great way to present data in a more meaningful way. [06:14:20]T-SQL code can be stored within Microsoft SQL Server databases using T-SQL routines [06:14:25]such as stored procedures, triggers, and functions. [06:14:30]This helps to make your T-SQL code more portable because it stays within the database and these routines [06:14:35]can be restored from a database backup. In this chapter, you’ll learn about creating reusable T-SQL routines, [06:14:40]install procedures and triggers, and we’ll also be taking a look at cursors. [06:14:45]In this lecture, we’re gonna be taking a look at stored procedures. [06:14:50]Stored procedures are a type of database object in Microsoft SQL Server [06:14:55]that allows you to encapsulate a sequence of SQL statements [06:15:00]and procedural logic into a single unit. [06:15:05]They are precompiled and stored in the database, which can improve performance [06:15:10]by reducing network traffic and enhancing code reuse. This is because your execution plan is cached, [06:15:15]so when you execute the stored procedure, it will use a cached one. [06:15:20]All right. So don’t worry too much about execution plan because that’s more advanced stuff. [06:15:25]That’s more database administration, and if you’re gonna be a data analyst you wouldn’t, [06:15:30]you won’t necessarily need to understand how to read the execution plan, [06:15:35]but it is good to be aware of the benefits of a stored procedure. [06:15:40]So basically, the execution plan is the path the SQL Server take to return your result. [06:15:45]So instead of sending hundreds of lines of code, it’s better to use a stored procedure [06:15:50]so that you can call a single statement rather than writing a complex statement [06:15:55]and sending it over the network. So let’s look at a simple example of a stored procedure, right? [06:16:00]You have the create procedure clause followed by the stored procedure name. [06:16:05]Now our stored procedure can accept a parameter. [06:16:10]In this case, we’re accepting a customer ID. Now it’s important to know that a stored procedure may or may not accept a parameter. [06:16:15]It can also accept multiple parameters. [06:16:20]We’re accepting a customer ID and then if you notice all you have after that is the begin [06:16:25]and end clause which wrap the set of SQL statements together. [06:16:30]So for the stored procedure basically you have to use a begin and end, right? [06:16:35]And then within the begin and end, you specify the statements [06:16:40]that you want to execute. So the stored procedure is simply accepting [06:16:45]a customer ID and then returning all the customer information [06:16:50]based on the ID provided. Now to execute a stored procedure [06:16:55]you use the execute command. You can use a shortened form exec [06:17:00]or spell out the word execute. You specify the stored procedure name [06:17:05]and in a case where it accepts parameter, then you specify the parameter [06:17:10]and then you assign the value to that parameter. So let’s head over to our best friend, [06:17:15]Management Studio to look at a practical example. So this example is from the lecture [06:17:20]where we spoke about the begin and the end, right? [06:17:25]And all we’re doing was to find the max person ID and the minimum person ID based on the ID we specified. [06:17:30]Now all of this can be encapsulated in a stored procedure [06:17:35]and now become a reusable code. So now instead of having the ID [06:17:40]within the stored procedure, we can now pass this ID [06:17:45]as a parameter to the stored procedure, right? [06:17:50]So to begin, we’re gonna have the keyword create procedure, right? I could say create proc. Here, you’re gonna specify the name for your procedure. [06:17:55]I’m just gonna call it max. I’m just going to call it max min [06:18:00]and I will be accepting a parameter as integer, right? So I’m going to say at [06:18:05]and I’ll be accepting the ID as an integer. So here I have a squiggly. [06:18:10]This is saying hey the syntax is half, so now I need to specify my open [06:18:15]and close brackets, right? So here I have a little red squiggly at the beginning, [06:18:20]that means it’s saying my syntax is off so now I need to specify has to remove this squiggly. [06:18:25]Now here you can see that hey the variable ID has already been declared. [06:18:30]Variable names must be unique within our query but our procedure. [06:18:35]So we no longer need this ID here, [06:18:40]and in this statement what we’re doing is that we’re getting the max ID. [06:18:45]So here what we’re doing is that we’re getting the max ID from the person table and initializing the ID variable. [06:18:50]So now that we are passing in the ID, we no longer need this statement here, right? [06:18:55]So let’s take it out and just for demonstration purposes, [06:19:00]I’ll be keeping this block here. Now let’s execute this block of code. [06:19:05]Now if you expand your database, expand programmability, [06:19:10]expand stored procedures, you should be able to see the stored procedure you just created. [06:19:15]So here it’s called sp underscore maxmin. To execute this procedure, [06:19:20]you’ll use the execute keyword. You can shorten it as exec, right? [06:19:25]So I’m going to specify execute. Do a procedure name and you can specify the variable [06:19:30]and set the value of the variable here. So let’s execute this statement. [06:19:35]So we can see that it’s just saying the max person ID is 10, even though this is not logically correct because we just specify the ID, right? [06:19:40]And the second statement is saying the minimum person ID is one. [06:19:45]So this is how you will create a stored procedure. [06:19:50]Now from the application, all the application need to do is literally specify this line of code depending on the syntax of that [06:19:55]calling application. The, the stored procedure call may be different, right? [06:20:00]But essentially this is what will be executed at the database level. [06:20:05]So instead of sending all of this from the application, [06:20:10]you now only send this from the application. You could also execute this to a procedure [06:20:15]without explicitly stating the variable name. So let me copy and paste this. [06:20:20]Now let’s remove the parameter name. Now let’s just execute. As you can see we got the same result. [06:20:25]So let’s say we have 10 persons in the organization and they all want to find the max ID. [06:20:30]They instead of rewriting that code every time they just execute a stored procedure to find the max ID, right? [06:20:35]So you can execute a stored procedure using the code [06:20:40]or from the graphical user interface. So under stored procedures, [06:20:45]right click the stored procedure that you want to execute and then select execute stored procedure. [06:20:50]Here you specify the value that you want to pass as the parameter. [06:20:55]So I’m going to say 1660, right? And then select okay. [06:21:00]So no result was found for that ID. So don’t worry about this return value for now. [06:21:05]You’ll learn about it later. To alter a stored procedure, you’ll use the alter command. [06:21:10]So let’s make the stored procedure a bit more meaningful by altering it, right? [06:21:15]I’m gonna copy and paste. So instead of saying create, [06:21:20]I’m going to use the word alter. So don’t mind the name of the stored procedure now. I’m just demonstrating how to alter it. [06:21:25]So what I’m going to use the stored procedure now to do is to list the person details [06:21:30]with the specified ID. So for the print statement, I’m just gonna say the person ID [06:21:35]and print the person ID which was provided. And here I’m gonna get rid of the begin because it’s not required here, right? [06:21:40]So for the select statement, I’m going to use a select asterisk to select all [06:21:45]from the person where, where business entity ID [06:21:50]is equal to the ID parameter. Now please keep in mind that whenever you’re doing stored procedures [06:21:55]or writing queries only return the values that you want in your query. [06:22:00]This will significantly improve the performance of your query. [06:22:05]The reason why I’m using select as to it is just for demonstration purposes only. [06:22:10]But whenever you’re doing this for actual production or writing queries, [06:22:15]make sure you specify the columns that you need. So here I’m gonna out execute the script to alter the procedure. [06:22:20]Now let’s execute the stored procedure. I’m going to use this option. [06:22:25]As you can see, it returned the person with the business entity ID [06:22:30]and all their information. Now a procedure can take multiple parameters, right? [06:22:35]So what I’m going to do now is that I’m going to be creating a stored procedure that return all the persons who is an employee. [06:22:40]That means their employee type is EM and they have a business entity ID [06:22:45]that is greater than a 100. All right. So to do this, [06:22:50]we can create the structure of our stored procedure first. Create proc. [06:22:55]I’m going to call this SP person and it takes two parameters. [06:23:00]I’m going to specify the ID for business entity ID. And to specify the second parameter, you specify a comma, right? [06:23:05]So I’m going to say ID and the second one is person type. [06:23:10]So I’m just gonna say PT for person to type. [06:23:15]Now I need to say as and specify begin and then we have the end, right? [06:23:20]So we have to ensure that we end our procedure. [06:23:25]Now within the begin, we need to specify our select statement. So I’m just going to grab the square from above. [06:23:30]So it’s where the business entity ID is greater than the ID specified [06:23:35]and the person type is equal to at PT. If no record is found, [06:23:40]I want to display a statement say, hey, no record is found. [06:23:45]So how can we do this? So we have learned about the if statement. [06:23:50]So we have learned about if statement previously, and we have learned about the row count, right, which is a system variable in SQL Server. [06:23:55]So I’m going to say if at row count is equal to zero, [06:24:00]then I’m going to print no result found or should I say no record found. [06:24:05]So I’m going to print no record found. Now let’s execute this statement to create the procedure. [06:24:10]Now I need to execute the procedure. I’m gonna say EEXC. [06:24:15]Now let’s execute the procedure by typing execute command. Remember, you can shorten it as exec, [06:24:20]name of the procedure and the parameters that we want to pass. [06:24:25]So I’ll be passing 200 as the parameter and for the parameter PT, [06:24:30]I’ll be passing EM. So now let’s execute this procedure. [06:24:35]Now let’s check the messages. So no record was found. However, if we query the person table however, [06:24:40]if we do a query on the person table, we’ll see that there are data [06:24:45]matching the criteria. So let’s scroll down. So I specified the ID of 200 [06:24:50]and we have employees are business entity ID with ID of greater than 200 [06:24:55]and person type of EM, right? So that means something must be half. [06:25:00]So if you look carefully for PT, [06:25:05]I specified VARCHAR, but if you look carefully when I hover over VARCHAR, [06:25:10]it’s saying the data type is VARCHAR and in the bracket it’s saying one. So basically, when I specify EM as a parameter, [06:25:15]the data is truncated. [06:25:20]So basically, what is being passed to the stored procedure is E and not EM. [06:25:25]So you have to be mindful of this when you’re using VARCHAR. So to fix this we need to alter the procedure [06:25:30]and specify the length of the VARCHAR. So in this case, [06:25:35]I’m just gonna say five, right? And I’m going to alter the procedure. [06:25:40]Now let’s execute, and let’s execute the stored procedure again [06:25:45]and now we can see that we have data being returned. If we check the messages, [06:25:50]we are seeing and saying that 73 rows was affected. So in this example, [06:25:55]we looked at the input parameter. We also have what is called the output parameter. [06:26:00]This is used to get result or output from a stored procedure. So let’s say we want to find the maximum ID in the table, right? [06:26:05]And we want to return that to the calling person. [06:26:10]So what we can do is create as to a procedure with the output parameter. [06:26:15]So we’re going to call this procedure find max, right? So it’s SP find max. [06:26:20]So in my brackets, I’m going to specify my output parameter. [06:26:25]So, so I’m going to declare max as int and always specify that it’s an output parameter. [06:26:30]We specify the keyword output. [06:26:35]So that will be the only difference so that will be the only difference when compared to the, to a procedure with the input parameter. [06:26:40]So now that we have defined the skeleton of our stored procedure, [06:26:45]we now need to specify the queries that will find the max record in the person table. [06:26:50]So when you’re naming your procedures, it’s good to use names that are self documented. [06:26:55]So I’m just gonna say here max person, right? So I’m just gonna say select business entity ID [06:27:00]from person table. So let’s execute this portion of the query to test it [06:27:05]and ensure everything is working fine. So now I’m going to create a procedure. [06:27:10]So in order to get the value of this max variable when the procedure is executed, [06:27:15]I now need to declare a variable and assign the output parameter to that variable, right? [06:27:20]So here I’m going to say declare max. Now, the next step is to execute the procedure. [06:27:25]So we will use it just like how we use input parameter, but at the end of it, [06:27:30]we’re going to say output, right? So let’s see this in action. [06:27:35]So it’s execute SP underscore find max person, right? [06:27:40]And here I’m going to say at max. As you can see, the IntelliSense is suggesting it, right? [06:27:45]And it’s telling you the type and what you should specify for the output. [06:27:50]So this is the syntax, right? You have the execute, the procedure name, [06:27:55]the variable that you want to assign the output value to, and then you specify the output keyword. [06:28:00]Now, the last step is to print the output value and we can do this using the print function. [06:28:05]So now let’s execute all of this together and you can see that we have a result of 2077. [06:28:10]Now if you try to execute a procedure without specifying the output parameter, [06:28:15]you will get an error. So let’s try this execute. [06:28:20]You can see that procedure or function find max person, expect max parameter [06:28:25]which was not specified. So for the input parameter, you have to specify the value that you are passing into the function, right? [06:28:30]And for the output parameter, [06:28:35]you have to specify the value that you want to catch the output from that stored procedure. [06:28:40]So to summarize, stored procedures provide a way to encapsulate complex logic, [06:28:45]improve performance, and enhance security by granting permissions [06:28:50]only on stored procedures rather than individual tables or views. [06:28:55]They are commonly utilized for tasks such as data manipulation, business logic implementation, and report generation [06:29:00]within SQL databases. In this lecture, we’ll be taking a look at triggers. [06:29:05]A trigger is a special type of stored procedure that is automatically executed in response to a specific database event [06:29:10]such as insert, update or delete operation on a table. [06:29:15]Triggers are used to enforce data integrity rules, [06:29:20]perform data validation and automate certain tasks. There are two types of triggers in SQL Server. [06:29:25]They are the after trigger and the instead of triggers. [06:29:30]The SQL Server after triggers run on a table after an insert, update, or delete. [06:29:35]It means that before the stored procedures start running, [06:29:40]all the operations should be executed, and the statement must also succeed in the constraint check. [06:29:45]It’s important to note that in SQL Servers, after triggers are not supported on views, [06:29:50]so use them on tables only. The after triggers can be further divided into. [06:29:55]After insert, this will fire after the completion of an insert data operation on a table. [06:30:00]Now a good example of this would be, for example, [06:30:05]you insert a record in the person table and after the insert you send an email, right? [06:30:10]So that would be a good example where you could use an after insert trigger. [06:30:15]Now for the after update trigger, this file is after an update operation is complete. [06:30:20]So it’s after an update exactly like what it said. [06:30:25]So for example, if a user updates a salary table, you may want to log that update [06:30:30]after the update is complete in an audit table. [06:30:35]The third one is the after delete and as the name suggests, [06:30:40]it fires after the delete statement is complete. Now the other types of triggers are the instead of triggers. [06:30:45]So instead of insert, I’m going to do something else, right? [06:30:50]So you can use this to do checks before you insert data, right? [06:30:55]So if the check is failed, then the insert won’t be completed. [06:31:00]Then the second one is the instead of update. It will fire before updating records in a table. [06:31:05]Once the execution is complete, it will then start updating records in the target table. [06:31:10]If it fails, the update won’t be done. And the last one is the instead of delete. [06:31:15]As the name suggests again, instead of deleting, it executes first [06:31:20]and then it do delete after. If it checks in the procedure that you execute failed, [06:31:25]then the records won’t be removed from the table. [06:31:30]Another type of trigger that you have is a data definition and language triggers, right? [06:31:35]These triggers are fired in response to DDL events including create, drop, alter, etc, right? [06:31:40]We can use them to prevent schema changes [06:31:45]and record the events that occurred in the database schema. An example of this trigger could be a situation [06:31:50]where it gives you a warning before you drop a table. [06:31:55]So this is protecting you from accidentally dropping a table. We also have log on triggers [06:32:00]which are important for auditing user access to the database, right? [06:32:05]So as the name suggests, the SQL Server logon triggers will fire whenever a user tries to log on or establish a connection to the server. [06:32:10]So this is what the after trigger looks like in SQL Server. [06:32:15]So when you compare it with the instead of trigger, [06:32:20]you will see that the keyword changed from after insert to instead of insert, right? [06:32:25]It’s important to note that within the trigger logic, you can access the inserted [06:32:30]and the deleted tables which hold the data being inserted, updated or deleted. [06:32:35]You can use these tables to perform operations based on the changes made to the data. [06:32:40]So for this demo, I’ll be using my demo database. [06:32:45]I’ll be creating two tables, orders table and order history table. [06:32:50]So I will create in a trigger that automatically inserts record into the order history table [06:32:55]whenever an order is inserted, updated, or deleted in the orders table. [06:33:00]Trigger order history [06:33:05]which will take care of all of that. So inside the trigger, [06:33:10]we check if the inserted table exists to determine if it’s an insert or update action. [06:33:15]If the deleted table also exists, it means that it’s an update action. [06:33:20]So in the case of an insert or update, we will insert the record in the order history table [06:33:25]with the corresponding action insert or update [06:33:30]and capture the relevant information from the inserted or deleted tables. [06:33:35]So if the inserted table does not exist, that means it’s a delete action, right? [06:33:40]So in this case we are still logging the deleted information [06:33:45]into the order history table. So let’s create this trigger. [06:33:50]So my bad, I need to create this table first. They do not exist. [06:33:55]So let’s execute the trigger again. [06:34:00]So what I’m going to do now is that I’m going to insert a record in the orders table. So let’s execute. [06:34:05]One row was affected. So let’s check the order history table. Let’s select top 1,000. [06:34:10]We can see that the record was logged. So the order ID is one, action insert, [06:34:15]date the action was done, customer name, the order date, and the total amount. [06:34:20]Now to make this information more useful, you could also add a column [06:34:25]that captures the user information who executed the insert statement. [06:34:30]Now let’s do an update. Let’s execute. Now let’s check the history table again. [06:34:35]Now you can see that we have a second record in the history table with the action update. [06:34:40]Now let’s do a delete. So I’m going to delete from the orders table [06:34:45]where order ID equal one. So let’s execute and you can see that [06:34:50]we know of the delete record being logged in the history table. [06:34:55]Here I have another trigger which is the instead of trigger. [06:35:00]So what I am going to do is that I am going to be disabling the after trigger which is on the orders table. [06:35:05]To do that, expand programmability, expand the orders table, expand the triggers, [06:35:10]right click on the trigger and then select disable. [06:35:15]So now I’m going to create the instead of trigger. Now please keep in mind that you can have multiple triggers on a table, right? [06:35:20]So let me execute this. Like before here, [06:35:25]we are checking if the operation is an update or delete. [06:35:30]So like before so this section we’re taking care of the insert operation. This section is taking care of the update operation [06:35:35]and this section is taking care of the delete operation. [06:35:40]So basically instead of inserting, updating, or deleting [06:35:45]data from the orders table, that data will be logged to the orders audit log table. [06:35:50]So first, we need to create the order audit log table, right? [06:35:55]So let’s scroll down and let’s create the order log table, let’s execute. [06:36:00]Now let’s try and insert a record in the orders table, so I’m going to use the first insert statement [06:36:05]I’m going to change ID to two and instead of John Doe I’m going to say John Brown. [06:36:10]Let’s execute the statement. So here I got a hero cannot insert the value null into the column log ID. [06:36:15]So this is because I’m not passing a value [06:36:20]to the log ID column. So to fix this we can enable int identity on the column. [06:36:25]So let’s refresh. [06:36:30]Right click on other audit log table, then select design. Select the log ID column. [06:36:35]Scroll down to properties and where it says identity specification, you will now click this arrow to drop down [06:36:40]and here where it says is identity, you want to change this to yes. [06:36:45]The default value is one and the seed value is one, so that’s fine. [06:36:50]It’s gotta basically start from one and increment by one. So I’m going to select save here. [06:36:55]So let’s close that. Now let’s try and insert again. So one row was affected. [06:37:00]Now let’s check the other audit log table. Select up 1,000 and we see we have one record inserted. [06:37:05]If we check the orders table we should see we have one record as well. [06:37:10]So we’re not seeing two because we had deleted John Doe from the table initially. [06:37:15]Now let’s say for the total amount the maximum amount a user can insert in the orders table is 100. [06:37:20]So if the total amount surpasses 100 we want to fail to insert. [06:37:25]Now what we can do is alter the trigger and use a if statement [06:37:30]to check for that condition and then rule back the transaction that business rule is breached. [06:37:35]So what I’ll be doing is that I’ll be altering this procedure [06:37:40]by copying and pasting it. So this time I’m performing validation check. [06:37:45]So if the total amount is greater than a 100, I’ll be rolling back the transaction, [06:37:50]that mean I’m going to stop it and not continue with insert because the business rule has been breached, right? [06:37:55]So let’s execute this procedure. [06:38:00]It was altered successfully. Now let’s try and do an insert again. [06:38:05]First, we are going to test an insert with the amount less than a 100. [06:38:10]So I’m going to say 10. I’m going to change the ID to three. [06:38:15]Now let’s execute. Now let’s check the order table. So we are seeing John Brown [06:38:20]with ID three in the table. Now let’s change this value from 10 to say 104 [06:38:25]and now let’s run the insert and see what happens. Now, we got an hero. [06:38:30]Total amount must be greater than zero, right? And, it gave us a message. [06:38:35]The transaction ended in the trigger. The batch has been aborted. [06:38:40]So this is how you can utilize triggers to enforce business rules and ensure data integrity. [06:38:45]So to summarize, a DML trigger [06:38:50]is a T-SQL batch code similar to a stored procedure that is associated with a table [06:38:55]and sometimes a view. You can use DML triggers for auditing, [06:39:00]enforcing complex integrity rules and more. [06:39:05]Triggers execute when particular DML events such as insert, update and delete occurs. [06:39:10]SQL Server supports two kinds of triggers, DML triggers, DML triggers [06:39:15]which are the after triggers and instead of triggers. Both types of DML triggers [06:39:20]execute as part of transaction associated with insert, update or delete statement. [06:39:25]In the T-SQL code for both DML triggers, you can access tables that are named inserted and deleted. [06:39:30]These tables contain the rows that were affected [06:39:35]by the modification that caused a trigger to fire. In the next lecture, [06:39:40]we’ll be taking a look at cursors. In this lesson, we’ll explore what are cursors, [06:39:45]why and when they are used, and how to work with them effectively in SQL Server. [06:39:50]So what a cursor does is that it allows you to retrieve and manipulate data [06:39:55]providing granular control over data processing. [06:40:00]So it pretty much provides you with a mechanism to traverse through records within a query result set. [06:40:05]Cursors are particularly useful when you need to perform complex data manipulation [06:40:10]or apply business logic that is not easily achieved with a single SQL statement. [06:40:15]SQL Server supports several types of cursors. You have the forward cursors. [06:40:20]It allows only forward movement through the result set, right? [06:40:25]It cannot move in a backward direction, and it is the most efficient type of cursor. [06:40:30]You also have the static cursors. These create a temporary copy of the result set in the TempDB. [06:40:35]Changes in the underlying data are not reflected in the cursor. [06:40:40]Both forward and backward movement are allowed through the result set. [06:40:45]We also have the dynamic cursors. Unlike the static cursor, [06:40:50]the dynamic cursor reflect changes made to the underlying data. It allows both forward and backward movement [06:40:55]through the data result set. Performance can be slower when compared to static cursors. [06:41:00]And the last one is the keyset cursors. [06:41:05]This one is similar to the dynamic cursor but with improved performance. [06:41:10]Changes made to the underlying data are reflected. This one also allows forward and backward movement [06:41:15]through the result set. It uses unique identifiers to identify rules in the result set. [06:41:20]When working with cursors, there are some performance considerations [06:41:25]that you need to keep in mind. Cursors can be resource intensive [06:41:30]and may lead to performance issues. Whenever possible, [06:41:35]try to use set based operations instead of using cursors to achieve the desired results. [06:41:40]Retrieve only columns required for processing within the cursor. [06:41:45]Avoid fetching unnecessary data to improve performance. [06:41:50]You also wanna choose a cursor type that suits your requirements, right? [06:41:55]In general, forward only and static cursors are more efficient than the dynamic cursors. [06:42:00]Another thing to note is that cursors all lock on data, right? [06:42:05]Which can cause contention and affect the performance of other queries. So you wanna keep the transaction using the cursor as short as possible.
[06:42:10] Trevoir Williams Guys, in this demo, we’re going to be taking a deep dive [06:42:15]into understanding cursors, right? So here I have a simple cursor [06:42:20]that fetches the top 10 records from the products table. [06:42:25]So the first part of the cursor is to declare the cursor, right? So you specify the declare keyword, [06:42:30]the name of the cursor and the cursor type [06:42:35]and the select statement that is used to define the result set for the cursor, right? [06:42:40]All of this can be executed as one statement. So now we have successfully declared our cursor. [06:42:45]Before we can access data within the cursor, we have to now open the cursor. [06:42:50]Then use a keyword open and then the name of the cursor [06:42:55]that you want to open so let’s execute this. So the cursor was opened successfully. [06:43:00]In order to get the results from the cursor, we need to fetch the result from the cursor. [06:43:05]So here we can use the fetch command to get the results from the cursor. [06:43:10]Now when I execute this command, you are going to observe something very important [06:43:15]so let’s execute. Only one row was returned. If we go to another window [06:43:20]and execute the top 10, we’ll see that we have 10 records versus here [06:43:25]on the cursor we only have one record. [06:43:30]This is because the cursor operates on a row at a time. To get the next record from the result set, [06:43:35]we’d have to execute this command again. We can also use fetch pyre to get the previous record, right? [06:43:40]So you’ll notice that it’s step backwards because with the static cursor [06:43:45]you can move forward and backwards, right? [06:43:50]You can also fetch the last record from the table by using the fetch last, right? [06:43:55]So let’s execute this. It jumped to the last record in the result set. [06:44:00]Now to validate this, let’s take a look at the result set here, and this is the last record in the result set. [06:44:05]So it’s the same thing here. Whenever you use a cursor, you must always close the cursor [06:44:10]and deallocate it. So here I’m gonna close the cursor. [06:44:15]And then you must also deallocate the cursor using the deallocate word [06:44:20]and the name of the cursor. So let’s execute. And the cursor was successfully deallocated. [06:44:25]So if we use the fetch next from the products CR, we will not get any data returned. [06:44:30]It’s saying cursor with the name product CR does not exist [06:44:35]because we have get rid of the cursor completely. But what happens if we execute this statement all at once? [06:44:40]Let’s find out. So even though we can use all of these [06:44:45]in the cursor without running into any issues, typically you’ll just use the one that suits your needs, right? [06:44:50]So you don’t need to use all of them within the cursor. [06:44:55]So if we’re supposed to execute this as one statement, it will just return one record. [06:45:00]Now in order for you to traverse the entire result set, [06:45:05]you would have to use a while loop to get this done where we are displaying all the result set. [06:45:10]So here I have a cursor that is designed to fetch the top 50 records from the product table. [06:45:15]We are going to be looping through the result set to display all the records. [06:45:20]In order to achieve this we are going to use a while statement. [06:45:25]So the first part of the script is that we are setting no count all. [06:45:30]This will disable the message that will typically say 10 rows affected, five rows affected, right? [06:45:35]So we are disabling that. Here, we are declaring some variables to store the data that we fetch from the cursor. [06:45:40]So let’s execute this. Now here, we are declaring the cursor, right? [06:45:45]It’s the same name from before. We can use the same because we’ve deallocate it earlier, right? [06:45:50]And this is the statement that we are using to define the cursor select top 50 [06:45:55]from the product table, and I’m just selecting a few columns. [06:46:00]So let’s declare the cursor. Now the next line is just to open the cursor, right? [06:46:05]Now let’s scroll down a bit. So here we have a system variable called cursor rules. [06:46:10]Now the cursor rules simply tell you how many records are being fetched in the cursor, right? [06:46:15]So if records were fetched, then we are going to go into the begin block. [06:46:20]And within the begin block we are fetching the data from the product cursor [06:46:25]into the variables we declared because remember it operates on data row by row [06:46:30]and the variables must be in order of your select statement, right? [06:46:35]The first variable is product ID. The second variable is product name. [06:46:40]The third variable is color, right? [06:46:45]And the fourth variable is price, just like how I have it in the select statement. [06:46:50]Now if your other hardware is different, it will work, but your result will be mismatched, right? [06:46:55]If you get what I’m saying. Now the next line is where we begin the while block. [06:47:00]So the while block starts here. Let me tap this for readability. [06:47:05]So this is the beginning of the wire block and this is the end of the wire block. [06:47:10]If you notice the wire is checking the condition or the system variable fetch status, right? [06:47:15]So this is what control the loop. The fetch status can be of four values. [06:47:20]Zero meaning the fetch status was successful. [06:47:25]A value of minus one means that the fetch statement failed or the row was beyond the result set. [06:47:30]A value of minus two means that the row fetched is missing [06:47:35]and the return value of minus nine means that the cursor [06:47:40]is not performing a fetch operation. So once the fetch is successful, [06:47:45]then we’ll jump into the begin block, right? And within the begin block, [06:47:50]we will print the variable for the records fetch, right? So we are going to be printing the product ID, [06:47:55]the product name, the product color, and the list price. [06:48:00]So let’s change this to list price. So the fetch next here is getting the next record [06:48:05]until there is no record in the result set. Whenever the fetch fails, [06:48:10]that is when we’ll exit the while loop. So once we are done, [06:48:15]we are going to close the cursor and deallocate the cursor and then set low count off, right? [06:48:20]So before we execute with this statement, I am going to be putting all of the print statement [06:48:25]in one line to avoid the extra spaces. So let’s make the change. [06:48:30]When the result is returned in the message section, it is shown on one line. [06:48:35]So now let’s highlight and execute. So let’s scroll up [06:48:40]and now we can see all the results being returned. To display the results, you could also use the select statement [06:48:45]to print the values of the variables. So I’m just going to grab these variables here [06:48:50]and I’m going to put it in a select statement, right? [06:48:55]So now I’m going to re-execute this cursor. And now we have the results tab showing the records. [06:49:00]So if I was to set no count half here, let’s execute that [06:49:05]and execute without turning the no count on, [06:49:10]you will see one row affected along with the message. [06:49:15]So when you set the no count on, it does not show the rows affected. [06:49:20]So if you are in a situation where you need to operate on the result set row by row, then cursor is a good option to go. [06:49:25]To summarize, SQL Server cursors provides a way to iterate [06:49:30]and process data row by row. However, they should be used judiciously [06:49:35]due to their potential impact and performance. It’s crucial to evaluate alternative solutions [06:49:40]and consider cursor usage as a last resort. [06:49:45]The SQL Server relational database management system [06:49:50]maintains transactional control over hard changes to the database’s data. [06:49:55]The strict adherence to transactional control in SQL Server ensures that the integrity of the database data [06:50:00]will never be compromised by partial completed transaction, [06:50:05]constraint violations, interference from other transactions, or service interruptions. [06:50:10]So after this lesson, you’ll be able to define asset properties of a transaction, [06:50:15]describe and set transaction modes and types, [06:50:20]describe lock modes blocking and deadlocking, describe and set isolation levels, [06:50:25]and describe efficient transaction coding guidelines. [06:50:30]So what is a transaction? A transaction is a logical unit of work. [06:50:35]Either hardware completes as a whole unit or none of it does. [06:50:40]Transactions are common in our daily lives. For example, purchasing something is considered as a transaction. [06:50:45]When you pay for something but don’t receive the object, [06:50:50]the transaction is stopped and you expect to receive your money back. [06:50:55]Another example is paying your money and receiving what you purchase from a logical unit of work. [06:51:00]Either both steps succeed together or both must fail together. [06:51:05]For SQL Server, all changes to the database data take place in the context of a transaction. [06:51:10]In other words, all operations that in any way [06:51:15]write to the database are treated by SQL Server as transactions. [06:51:20]This includes all data manipulation language such as insert, [06:51:25]update and delete. All data definition language such as create table and create index. [06:51:30]Technically, even a single select statements are a type of transaction in SQL Server. [06:51:35]These are called read only transactions. [06:51:40]There are two terms you must be familiar with, commit and rollback. [06:51:45]These are used to control the result of a transaction in SQL Server. [06:51:50]When the work of a transaction is approved by the user, SQL Server completes its transaction changes by committing them. [06:51:55]If an unrecoverable error occurs or the user decides not to commit, [06:52:00]then the transaction is rolled back. In relational databases, [06:52:05]the ACID acronym is used to describe the properties of a transaction. [06:52:10]The ACID properties are atomicity, right? [06:52:15]This means that every transaction is an atomic unit of work. [06:52:20]Meaning, all database changes in the transaction succeed or none of them succeed. [06:52:25]The other one is consistency. Every transaction whether successful [06:52:30]or not leaves the database in a consistent state as defined by all the objects [06:52:35]and database constraints. If an inconsistent state results, SQL Server [06:52:40]will roll back the transaction to maintain the consistent state. [06:52:45]The I represent isolation. The isolation property ensures that multiple transaction [06:52:50]can occur concurrently without leading to inconsistency of the database state. [06:52:55]So basically transactions occur independently without interference. [06:53:00]Changes occurring in a particular transaction [06:53:05]will not be visible to any other transaction until that particular change [06:53:10]in that transaction is written to memory or has been committed. [06:53:15]This property ensures that the execution of transactions concurrently [06:53:20]will result in a state that is equivalent to the state achieved [06:53:25]and the default durability means that every transaction endures through an interruption of service. [06:53:30]When service is restored, all committed transaction are rolled forward [06:53:35]and all uncommitted transactions are rolled back. [06:53:40]SQL Server ensures all these asset properties through a variety of mechanisms, right? [06:53:45]To maintain atomicity, SQL Server treats every data DML or DDL command individually [06:53:50]and will not allow any command to partially succeed. [06:53:55]For consistency, SQL Server ensures that all constraints in the database are enforced. [06:54:00]If your transaction attempts to insert a row that has an invalid foreign key, [06:54:05]then SQL Server will detect that a constraint would be violated [06:54:10]and generate an error message. To enforce isolation, [06:54:15]SQL Server ensures that when the transaction made multiple changes to the database [06:54:20]none of the objects being changed by that transaction are allowed to be changed by another transaction. [06:54:25]In other words, one transaction changes are isolated [06:54:30]from any other transaction activities. If two transactions want to change the same data, [06:54:35]one of them must wait until the other transaction is finished. [06:54:40]You will see this later on when we are doing a demonstration. [06:54:45]SQL Server maintains transactional durability [06:54:50]by using the database transaction log. In SQL server, [06:54:55]there are different transaction modes that control how transactions are handled and managed. [06:55:00]First, we have auto commit transactions. In the auto commit mode, [06:55:05]each SQL statement is treated as a separate transaction and is automatically committed after execution. [06:55:10]In this mode, there is no explicit begin transaction [06:55:15]or commit transaction needed. It is a default behavior in SQL Server [06:55:20]when neither implicit nor explicit transaction are explicitly enabled. [06:55:25]So far in this course, we were pretty much operating in auto commit transaction mode. [06:55:30]The next one is the implicit transactions. Implicit transactions [06:55:35]are initiated automatically by a SQL Server [06:55:40]when there is no explicit transaction management. In the implicit transaction mode, [06:55:45]whenever you issue one or more DML or DDL statements or a select statement, [06:55:50]SQL Server starts a transaction. It increments the trans count variable [06:55:55]but does not automatically commit or roll back the statement. [06:56:00]You must issue a commit or roll back interactively to finish the transaction [06:56:05]even if you issued a select statement. It’s not the SQL Server default. [06:56:10]However, if you are familiar with Oracle databases then you will realize that this sounds familiar. [06:56:15]You can enter that mode by using the command set explicit transaction on. [06:56:20]Now the third one is the explicit transactions. [06:56:25]Explicit transactions are managed explicitly by the application or the developer. [06:56:30]You start a transaction using the begin transaction statement [06:56:35]and you can choose to commit or roll back the transaction manually based on your application logic and error handling. [06:56:40]This mode provides more control over the transaction and is commonly used [06:56:45]when multiple SQL Server statement needs to be treated as a single transaction. [06:56:50]To preserve the isolation of transactions, [06:56:55]SQL Server implements a set of locking protocols. [06:57:00]At the basic level, there are two types of general lock modes of locking. First one is shared locks. [06:57:05]This is used for sessions that read data. The second one is the exclusive locks. [06:57:10]This is used for changes to the data, so this would be like your update, your delete, or your write. [06:57:15]When a session sets out to change data, [06:57:20]SQL Server will attempt to secure an exclusive lock on the object in question. [06:57:25]These exclusive locks always occur in the context of a transaction [06:57:30]even if only in the auto commit mode and the session does not start with an explicit transaction. [06:57:35]So when a session has exclusive lock on an object such as a row, table, [06:57:40]or some other system objects, no other transaction can change that data [06:57:45]until the transaction is either commits or rolled back. [06:57:50]Except for special isolation levels, other sessions cannot even read exclusively locked objects. [06:57:55]So when a session is just reading data by default, [06:58:00]SQL Server will issue a very brief shared lock on the resource. [06:58:05]Two or more session can read the same objects because shared locks are compatible with other shared locks. [06:58:10]However, when a session has a resource locked exclusively [06:58:15]no other session can read the resource. In addition to not being able to write to the resource. [06:58:20]You will see more of this later on when we are doing a demonstration. [06:58:25]So from this lock compatibility matrix you will see that whenever we have a exclusive lock granted right [06:58:30]we cannot grant a shared lock on that resource. [06:58:35]So if we have a exclusive lock and we request a exclusive lock on that lock, [06:58:40]it is not granted. If we request a shared lock on that exclusive lock, [06:58:45]it is not granted either. Now in the second row if we have a shared lock and the exclusive lock is requested, [06:58:50]it is not granted. Though if we have a shared lock and a shared lock is requested, [06:58:55]then it is granted. So if we have two session requests and exclusive lock on the same resource [06:59:00]and one is granted the request, then the other session must wait [06:59:05]until the first releases its exclusive lock. [06:59:10]In a transaction, exclusive locks are held to the end of the transaction. [06:59:15]So if the first session is performing a transaction, the second session [06:59:20]will have to wait until the first session is either commits or roll back. [06:59:25]No two sessions can write to the same resource at the same time, so writers can block writers. [06:59:30]It’s not just two requests for an exclusive lock on the same resource that results in blocking, right? [06:59:35]An exclusive lock can also block a request to read the same data. [06:59:40]If the reader is requesting a shared lock because exclusive lock is incompatible with the shared lock, [06:59:45]an exclusive lock can also block a request to read the same data. [06:59:50]If the reader is requesting a shared lock because an exclusive lock is also incompatible with a shared lock. [06:59:55]Now in a transaction operating with the default read commit snapshot isolation level on, [07:00:00]shared locks are released as soon as the data is read, [07:00:05]and they are not held until the end of the transaction except in higher isolation levels. [07:00:10]Now we can also have what is called deadlocking right? [07:00:15]A deadlock results from mutual blocking between two or more sessions. [07:00:20]Now sometimes locking sequences between sessions [07:00:25]cannot be resolved simply by waiting for a transaction to finish, right? [07:00:30]This occurs due to the cyclical relationship between two or more commands. [07:00:35]So SQL Server detects a cycle as a deadlock between two sessions, aborts one of the transaction [07:00:40]and return an error message typically 1205 to the client. [07:00:45]So guys in this demo, we’re going to be demonstrating blocking and locking, right? [07:00:50]So before we get into that, SQL Server provide what is called dynamic management views [07:00:55]that you can use to monitor uncommitted transactions and blocking transactions within your database. [07:01:00]So here I have a script that detects blocking, right? [07:01:05]I’ll provide this in the resource section of this lecture and I have another script. [07:01:10]You don’t have to worry about writing these stuff, right, because they are provided by Microsoft. [07:01:15]So this one detects uncommitted transactions, right? [07:01:20]So to start a transaction, the first to use begin tran or begin transaction [07:01:25]and to commit a transaction, you use a commit keyword. If you want to roll back, [07:01:30]you use roll back, right? So let’s execute all of this without executing the command portion of this script, right? [07:01:35]So let’s execute. So the result was returned. Now let’s check if there are any uncommitted transactions. [07:01:40]So let’s execute this. [07:01:45]So we have one uncommitted transaction if and if you want to confirm, right, [07:01:50]you can check the speed for that session. So let’s go back to the session. [07:01:55]I’m going to do a select at that speed. Now let’s execute this and you see we have the session ID of 75 [07:02:00]which correlates to the session ID here. So basically what happened, [07:02:05]a shared lock was issued on this record here. So let’s go back to this monitoring script. [07:02:10]Let’s execute. If we open another session and try and query the same record, [07:02:15]we’ll see that the user will not be able out, the user [07:02:20]will be able to query the record, right? Let’s copy all of this. [07:02:25]Let’s open a new session. Right click on the database and do a new query window. [07:02:30]Now let’s paste and execute the first two lines. Now the result was returned. [07:02:35]Now let’s check the uncommitted transactions. [07:02:40]So now we have two uncommitted transaction. Now let’s check if we have any blocking in our database, right? [07:02:45]So I’m gonna go on the monitoring script now, and we don’t have any blocking occurring. [07:02:50]So remember, when a shared lock is acquired, other users can read that data, right? [07:02:55]Because there’s no modification being done. Now to commit these transactions, [07:03:00]you can see the commit keyword. Now let’s execute commit. [07:03:05]Let’s do this for the next session as well. Let’s execute commit here as well. [07:03:10]Now if we run the script to monitor uncommitted transaction, we’ll no longer be seeing any session. [07:03:15]So what we are going to be doing now is that we are going to be simulating a blocking using an update statement, right? [07:03:20]So here I’m going to attempt to update the same record. [07:03:25]So basically I want to set the address to 1200 NEPA, Jamaica, right? [07:03:30]So let’s start the transaction, now let’s run the update statement, [07:03:35]now let’s check the monitoring script and here we can see that we have one session in an uncommitted state so here you’ll see the state here, right? [07:03:40]And here in the input buffer, you’ll see the statement that has been executed. [07:03:45]So previously, when we run updated statements in the database and we check, [07:03:50]the record would have been updated, right? So now let’s go back to one of the sessions [07:03:55]that we recorded the record, right? So we’re gonna be checking [07:04:00]if the person address line one has been updated. [07:04:05]So let’s go here and let’s execute the select statement and you can see that the record wasn’t changed because, [07:04:10]because the change will not be reflected in the database unless a commit statement is issued. [07:04:15]Now if somebody else try and come and update the same record, [07:04:20]they would have to wait until the first user who acquired the lock and that record execute the commit statement. [07:04:25]So let’s open another session, right? We’re gonna grab this here. [07:04:30]Let’s open a new session to the database. Now let’s execute all of this. [07:04:35]Now as you can see, the query is in an executing state. [07:04:40]So basically the user is now waiting on the other session, right? [07:04:45]Let me see the session ID. Yes. Session ID 83 to do a commit before they can access that record. [07:04:50]Now when we check the blocking script, we will be able to see [07:04:55]the records that are being blocked at the database level. So you can see that session 83 [07:05:00]is blocking session 81, right? The update statement, the time it logged in. [07:05:05]And if we scroll across, we can see more information about the transaction, [07:05:10]the login name, the username, right, the status of the query. [07:05:15]So this one is sleeping. This one is running, memory usage, and all. [07:05:20]Now, these are more database administration concept. If you want to learn more about database administration, [07:05:25]I do have a essential training on SQL Server 2023. [07:05:30]I’ll leave a link in the resource section of this lecture as well if it’s something that you want to pursue, right? [07:05:35]So with that said, let’s get right back into it. So unless session 83 commits, right, [07:05:40]61 will have to be waiting forever. [07:05:45]So there are two ways to resolve this. Either session 83 commits [07:05:50]or you kill the session as a database administrator. [07:05:55]So if we go on session 83 and run the commit statement, there should no longer be any blocking at the database level. [07:06:00]So now let’s check the monitoring script for blocking. Let’s execute [07:06:05]and now we don’t have any blocking occurring at the database. [07:06:10]Now when we check the uncommitted transactions, we’ll see that we have two uncommitted transactions. [07:06:15]One of them is just the select statement and the other one is the update statement. [07:06:20]So now that we have issued a commit statement, we can check the database [07:06:25]and see what the address is reflecting here. So let’s execute and you can see that [07:06:30]address line one has been updated to 1200, NEPA Jamaica. [07:06:35]Now monitoring blocking is important because from time to time, you may be experiencing performance issues in your application. [07:06:40]There are long wait times. And the way to resolve this [07:06:45]is by killing the transaction that is blocking other processes, right? [07:06:50]So let me simulate the blocking again and show you how you’ll go about killing the transaction. [07:06:55]So here I’m gonna try and update the address to 12002. [07:07:00]So I’m going to execute this again, begin transaction and update. [07:07:05]Now you see that this query switched to a running state, right? Now when we check the monitoring script, let’s execute. [07:07:10]We now have three uncommitted transaction. Now let’s check for blocking. [07:07:15]Now let’s execute and we can see that session 61 is now blocking session 83. [07:07:20]Now to resolve this, you can execute the kill command, right? [07:07:25]Kill and the session ID. So in this case, I want to kill session 61. [07:07:30]Now let’s execute and that should take care of the blocking at the database level. [07:07:35]So now let’s check the blocking and we no longer have any blocking taking place. [07:07:40]In the next lecture, we’re going to be taking a look at transaction isolation levels.
[07:07:45][sil.]
[07:07:50][music]
[07:07:55] Emar Morrison Hello once again learners. [07:08:00]This is Emar Morrison, and we have ended our journey exploring T-SQL syntax. [07:08:05]We want to congratulate you on your hard work and dedication throughout this course.
[07:08:10] Trevoir Williams Hi. It’s Trevoir Williams, and I echo Emar’s sentiments wholeheartedly. [07:08:15]It’s been a pleasure watching you go from strength to strength on this topic.
Emar Morrison As you venture into your careers and hobbies, [07:08:20]remember the fundamental skills and principles discussed here. [07:08:25]They will continue to serve as your foundation no matter how complex your future T-SQL project becomes. [07:08:30]And even though our course is ending, our support for your journey isn’t.
[07:08:35] Trevoir Williams Remember to keep the curiosity alive. This field is always evolving, always changing, [07:08:40]and you need to make sure that you’re keeping on top of the latest trends [07:08:45]that you’re practicing and that you’re continuously developing your skills. [07:08:50]Thank you for being a part of this amazing journey, [07:08:55]and I can’t wait to see where your knowledge in T-SQL takes you next. [07:09:00]
END TRANSCRIPT