├── .DS_Store ├── .Rhistory ├── README.md ├── chinook.db └── images ├── .DS_Store ├── Concat.png ├── Functions1.png ├── Having.png ├── Maths.png ├── Select.png ├── Sort.png ├── WC-Percent.png ├── WP-Underscore.png ├── Where.png ├── Where2.png ├── aggregate.png ├── db_browser.png ├── group_by_1.png ├── subqueries-CF.png ├── subqueries.png └── tips.png /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/.DS_Store -------------------------------------------------------------------------------- /.Rhistory: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/.Rhistory -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SQL Tutorials 2 | 3 | Welcome! 4 | 5 | Here are some SQL tutorials I've been creating and posting to Twitter. 6 | 7 | ## Support Me 8 | 9 | If you find any of this useful, consider supporting me at: 10 | 11 | Buy Me A Coffee 12 | 13 | ## Let's Connect 14 | 15 | You can also follow me at: 16 | 17 | [![linkedin](https://img.shields.io/badge/linkedin-0A66C2?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/abzaaron/) 18 | [![twitter](https://img.shields.io/badge/twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white)](https://twitter.com/AbzAaron) 19 | 20 | ## Let's Begin! 21 | 22 | Let's get started! We'll begin with a quick overview of databases. 23 | 24 | ## What is a database? 25 | 26 | This is essentially a container storing organised data electronically, usually controlled by something called a database management system (DBMS for short). These can store more data (and are more secure) than a text file or spreadsheet. 27 | 28 | ## What is a DBMS? 29 | 30 | These are software packages which allow us to create, manipulate and manage our databases. You've probably heard of some before. 31 | 32 | They include: 33 | 34 | * MySQL 35 | * SQLite 36 | * PostgreSQL 37 | 38 | ## What is a table? 39 | 40 | These are structured files containing data within the database. Typically, a database contains multiple tables, each composed of rows & columns. This makes data retrieval easier. 41 | 42 | ## What are table columns & rows? 43 | 44 | Picture tables like spreadsheets. We have columns storing a particular type of data, such as name, price, or date, with each row representing a specific record. 45 | 46 | ## What is a type of data? 47 | 48 | Each column in a table has a datatype. A column called age would be a numeric datatype, as an example. Setting datatypes correctly can: 49 | 50 | * Restrict incorrect data being inserted 51 | * Help if data needs to be sorted 52 | * Help optimise memory usage 53 | 54 | ## What are constraints? 55 | 56 | These are rules enforced on your data, ensuring the correct type of data is entered into a database, maintaining data integrity. For example, a UNIQUE type constraint would ensure all values in a table column remain unique. 57 | 58 | ## What is a primary key? 59 | 60 | This is a column or combo of columns designed to uniquely identify each table row. Without a primary key, we won't always be able to uniquely identify a table record. An example might be a 'user_ID' column, whereby each record has its own unique ID. 61 | 62 | ## What is a foreign key? 63 | 64 | This is a column or combo of columns in a table that refers to the primary key of another table. This establishes a link between tables, allowing us to join them together if required. 65 | 66 | ## What is SQL? 67 | 68 | SQL, or Structured Query Language, is what we use to communicate with databases. We use this to remove data, add data, read data, join tables, create tables, and so on. It's easy to learn, and almost all DBMS support SQL. So it's worthwhile learning this! 69 | 70 | ## Getting Started 71 | 72 | A good place to get started is with SQLite. Follow the below steps to get set-up: 73 | 74 | 1. Download **DB Browser for SQLite** from https://sqlitebrowser.org 75 | 2. Download the [Chinook sample database](chinook.db) 76 | 3. Open up DB Browser for SQLite and open the database 77 | 4. Under the *Database Structure* tab, you can see a list of tables 78 | 5. Under the *Execute SQL* tab, you can run SQL queries 79 | 80 | Alternatively, you can use the SQLite command line program, rather than DB Browser: 81 | https://www.sqlite.org/cli.html 82 | 83 | You can view the database diagram illustrating table relationships for the Chinook database here: 84 | https://www.sqlitetutorial.net/sqlite-sample-database/ 85 | 86 | Play around with this database as you read through some of these tutorials. You can start by simply typing a basic command and running it to see the output: 87 | 88 | 89 | 90 | ## Select Statment 91 | 92 | The `SELECT` statement is used to retrieve table data. We only need to specify what we want to select and where we want to select it from. Simple! 93 | 94 | Note that we use `FROM` to specify the table we wish to retrieve data from. 95 | 96 | In the below example, you'll notice we've used the * character. This signifies that we want to return all columns in the table. This is useful when you are practicing; however, it's bad practice within a real production enviornment, and can slow things down. Rarely would we ever need to retun all columns. 97 | 98 | Additionally, pay attention to column placement when we are returning more than one column. There should be a comma between each column name, but not after the last one. If we were to include a comma after the last column in a `SELECT` statment, we would get an error. 99 | 100 | 101 | 102 | ## Sorting 103 | 104 | When retrieving data from a table, it will generally be displayed in the order it appears within that table; therefore it's not a good idea to rely on data being in any specific order when retrieving it. Instead, you can explicitly sort using `ORDER BY`. 105 | 106 | If we want to order descendingly, we can use `DESC`. We can also explicity write `ASC` for ascending. However, as this is the default, we don't really need to include it. 107 | 108 | 109 | 110 | ## Where Clause 111 | 112 | When extracting data from tables, you'll normally only want a subset of the data. Achieve this using the `WHERE` clause, which will filter the data. 113 | 114 | Specify `WHERE` after the `FROM` clause. 115 | 116 | Note that we've split our queries across multiple lines here, rather than just writing it all on a single line. In SQL, we don't have to worry about whitespace. It's usually good practice to split long queries across multiple lines for better readability. 117 | 118 | 119 | 120 | ## Where Clause ~ Part 2 121 | 122 | We can combine `WHERE` clauses with `AND` or `OR`. 123 | 124 | When combining these operators, `AND` is processed before `OR`. 125 | 126 | But... we can control evaluation order using parentheses to explicitly group operators, a bit like what we do in Maths! For example: 127 | 128 | * 5 + 2 x 3 = 11 129 | * (5 + 2) x 3 = 21 130 | 131 | Note how we use parenthese to change the order of evaluation, and thus change the final result. We can do the same with `AND` and `OR` in SQL. 132 | 133 | 134 | 135 | ## Wildcards ~ Percent ( % ) 136 | 137 | Wildcards are symbols used to substitute characters within a text string. Adding these to a search condition allows us to filter data matching a pattern. 138 | 139 | To do this, we use the `LIKE` operator within a `WHERE` clause. 140 | 141 | Let's look at the % wildcard. 142 | 143 | 144 | 145 | ## Wildcards ~ Underscore ( _ ) 146 | 147 | Another wildcard is the underscore. 148 | 149 | This matches 1 character, differing from the % wildcard, which represents 0, 1, or more characters. 150 | 151 | Note: wildcard searches typically take longer to run, especially if wildcard is at the start of a search pattern. Consider this before using. 152 | 153 | 154 | 155 | ## Calculated Fields ~ Concatenation 156 | 157 | In a `SELECT` statement, we can *calculate* new columns on-the-fly without altering the database data itself. 158 | 159 | One example is *concatenating* columns together. 160 | 161 | To give a new field a proper name, we use the `AS` keyword. Note that we don't actually have to include the `AS` keyword. The query would work exactly the same if we omitted this. However it's good practice to include it, for readability. 162 | 163 | 164 | 165 | ## Calculated Fields ~ Maths 166 | 167 | We learned we can calculate fields on-the-fly without altering database data itself 168 | 169 | One use for this is concatenation. Another is running maths operations on retrieved data. 170 | 171 | Here are some operators: 172 | 173 | * Division ( / ) 174 | * Addition ( + ) 175 | * Subtraction ( - ) 176 | * Multiplication ( * ) 177 | 178 | If we want to change the order or precedence, we can use parentheses (like we would in Maths). 179 | 180 | 181 | 182 | ## Functions ~ Part 1 183 | 184 | Functions are a set of instructions grouped together, used to perform a specific task. 185 | 186 | Value(s) can be passed to a function, which the function then operates on. 187 | 188 | This can make manipulating or converting data in SQL simpler and more efficient. 189 | 190 | 191 | 192 | ## Additional Info 193 | 194 | Here's just a bit more information on SQL statements! 195 | 196 | 197 | 198 | ## Aggregate Functions 199 | 200 | Aggregate functions run calculations on a set of rows to return a single value. These are: 201 | 202 | 1. `MAX` 203 | 1. `MIN` 204 | 1. `AVG` 205 | 1. `SUM` 206 | 1. `COUNT` 207 | 208 | These all ignore `NULL` (blank) values except for `COUNT(*)` which counts the number of table rows. 209 | 210 | We can use `DISTINCT` to include only unique values. Notice how it changes the average returned when we use this. 211 | 212 | Note that where you see `DISTINCT` below, you could replace this with `ALL` to perform the calculation on all rows. However, we would never do this, as `ALL` is actually the default. 213 | 214 | So for example, we could rewrite one of the other lines, like `SUM(price) AS sum_price`, as `SUM(ALL price) AS sum_price` instead. This would do exactly the same thing. 215 | 216 | 217 | 218 | ## Grouping Data 219 | 220 | The `GROUP BY` clause creates a separate group for each unique value in a column or set of columns. 221 | 222 | We can then perform aggregate functions like `SUM` or `AVG` on each individual group. 223 | 224 | Note that, if a grouping column contains `NULL`, this will be classed as a group. Also, `GROUP BY` can list multiple columns to group by (each of these must be a retrieved column under the `SELECT` statement except for the aggregate function). Similarly, every column listed in the `SELECT` statement must be included in the `GROUP BY` clause; again, with the exception of the aggregate function(s). 225 | 226 | Finally, `GROUP BY` comes after the `FROM` clause and `WHERE` clauses, but before the `ORDER BY` clause. 227 | 228 | It's worth playing around with this on your own so you can better understand what's going on. 229 | 230 | 231 | 232 | ## Filtering Grouped Data 233 | 234 | We use `HAVING` to filter grouped data. This is very similar to the `WHERE` clause. 235 | 236 | Only difference is `WHERE` filters specific rows (filters before data is grouped) and `HAVING` filters groups (filters after data is grouped) 237 | 238 | Note: We can use both clauses in one statement. So for example, we might want to filter our data using `WHERE`, then group the data, and filter those groups usin `HAVING`. 239 | 240 | 241 | 242 | ## Subqueries 243 | 244 | A *subquery* is an SQL query embedded within another query, often used within `WHERE` clause `IN` operators 245 | 246 | Subqueries are processed starting with the innermost `SELECT` statement 247 | 248 | Note: although powerful, subqueries can negatively impact performance. There are other ways we can perform the type of data retrieval we are conducting here (more on that in a later tutorial). 249 | 250 | 251 | 252 | ## Subqueries ~ Part 2 253 | 254 | Not always the best option, but we can use *subqueries* to create calculated fields (columns created on-the-fly) within a `SELECT` statement. 255 | 256 | Note: Because both tables below contain an "em_id" column, we've used syntax "table.column" to remove ambiguity & ensure correct results (i.e. Employees.em_id and Expenses.em_id). 257 | 258 | 259 | 260 | ## Joins 261 | 262 | In progress... 263 | -------------------------------------------------------------------------------- /chinook.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/chinook.db -------------------------------------------------------------------------------- /images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/.DS_Store -------------------------------------------------------------------------------- /images/Concat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/Concat.png -------------------------------------------------------------------------------- /images/Functions1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/Functions1.png -------------------------------------------------------------------------------- /images/Having.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/Having.png -------------------------------------------------------------------------------- /images/Maths.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/Maths.png -------------------------------------------------------------------------------- /images/Select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/Select.png -------------------------------------------------------------------------------- /images/Sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/Sort.png -------------------------------------------------------------------------------- /images/WC-Percent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/WC-Percent.png -------------------------------------------------------------------------------- /images/WP-Underscore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/WP-Underscore.png -------------------------------------------------------------------------------- /images/Where.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/Where.png -------------------------------------------------------------------------------- /images/Where2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/Where2.png -------------------------------------------------------------------------------- /images/aggregate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/aggregate.png -------------------------------------------------------------------------------- /images/db_browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/db_browser.png -------------------------------------------------------------------------------- /images/group_by_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/group_by_1.png -------------------------------------------------------------------------------- /images/subqueries-CF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/subqueries-CF.png -------------------------------------------------------------------------------- /images/subqueries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/subqueries.png -------------------------------------------------------------------------------- /images/tips.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ABZ-Aaron/sql-tutorials/eef3be4388fea7c0991360b3a89be769704b88e1/images/tips.png --------------------------------------------------------------------------------