{"id":94655,"date":"2022-06-15T22:47:05","date_gmt":"2022-06-15T22:47:05","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=94655"},"modified":"2022-06-15T22:47:05","modified_gmt":"2022-06-15T22:47:05","slug":"introducing-the-mysql-select-statement","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/mysql\/introducing-the-mysql-select-statement\/","title":{"rendered":"Introducing the MySQL SELECT statement"},"content":{"rendered":"<p><strong>This article is part of Robert Sheldon's continuing series on Learning MySQL. To see all of the items in the series, <a href=\"https:\/\/www.red-gate.com\/simple-talk\/mysql-coding-basics\/\">click here<\/a>.<\/strong><\/p>\n\n<p>Up to this point in the series, I\u2019ve focused primarily on creating schema objects in a MySQL database. The SQL statements used to create these objects are typically categorized as data definition language (DDL). They include statements such as <code>CREATE<\/code> <code>TABLE<\/code>, <code>CREATE<\/code> <code>VIEW<\/code>, and <code>CREATE<\/code> <code>PROCEDURE<\/code>.<\/p>\n<p>Beginning with this article, I\u2019m switching my attention to data manipulation language (DML), which includes statements used to query and modify data. Four of the most common DML statements are <code>SELECT<\/code>, <code>INSERT<\/code>, <code>UPDATE<\/code>, and <code>DELETE<\/code>. You can use the <code>SELECT<\/code> statement to retrieve data, the <code>INSERT<\/code> statement to add data, the <code>UPDATE<\/code> statement to modify data, and the <code>DELETE<\/code> statement to remove data.<\/p>\n<p>In this article, I focus on the <code>SELECT<\/code> statement, which is used extensively when working with relational databases. You can use the <code>SELECT<\/code> statement to return data from one or more MySQL tables, as well as to retrieve information about the server and database environment. The <code>SELECT<\/code> statement is one of the most commonly used SQL statements in MySQL. It is also one of the most complex.<\/p>\n<p>You got a taste of the <code>SELECT<\/code> statement in earlier articles in this series, but it was included only to support the DDL examples in those articles. This article focuses exclusively on the <code>SELECT<\/code> statement and the basic elements that go into building one. I\u2019ll be covering other DML statements later in this series.<\/p>\n<h2>Preparing your MySQL environment<\/h2>\n<p>For the examples in this article, I used the same database (<code>travel<\/code>) that you saw in the previous articles and the same two tables (<code>manufacturers<\/code> and <code>airplanes<\/code>). However, I added a lot more data this time around. If you want to try out the examples for yourself, you can download the <strong><a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/06\/MySQL_06_setup.txt\">MySQL_06_setup<\/a>\u00a0<\/strong>file and run it against your MySQL instance. The SQL in the file creates the database, adds the two tables, and inserts data in both tables.<\/p>\n<p>For your convenience, I\u2019ve included the two table definitions here so you can reference them when trying out the <code>SELECT<\/code> statements in the examples later in the article:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">CREATE TABLE manufacturers (\r\n  manufacturer_id INT UNSIGNED NOT NULL AUTO_INCREMENT,\r\n  manufacturer VARCHAR(50) NOT NULL,\r\n  create_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\r\n  last_update TIMESTAMP NOT NULL \r\n    DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\r\n  PRIMARY KEY (manufacturer_id) ) \r\nENGINE=InnoDB AUTO_INCREMENT=1001;\r\nCREATE TABLE airplanes (\r\n  plane_id INT UNSIGNED NOT NULL AUTO_INCREMENT,\r\n  plane VARCHAR(50) NOT NULL,\r\n  manufacturer_id INT UNSIGNED NOT NULL,\r\n  engine_type VARCHAR(50) NOT NULL,\r\n  engine_count TINYINT NOT NULL,\r\n  max_weight MEDIUMINT UNSIGNED NOT NULL,\r\n  wingspan DECIMAL(5,2) NOT NULL,\r\n  plane_length DECIMAL(5,2) NOT NULL,\r\n  parking_area INT GENERATED ALWAYS AS ((wingspan * plane_length)) STORED,\r\n  icao_code CHAR(4) NOT NULL,\r\n  create_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\r\n  last_update TIMESTAMP NOT NULL \r\n    DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\r\n  PRIMARY KEY (plane_id),\r\n  CONSTRAINT fk_manufacturer_id FOREIGN KEY (manufacturer_id) \r\n    REFERENCES manufacturers (manufacturer_id) ) \r\nENGINE=InnoDB AUTO_INCREMENT=101;<\/pre>\n<p>If you already have the database and tables on your MySQL instance and don\u2019t want to re-create them, you can run just the <code>INSERT<\/code> statements in the<strong> MySQL_06_setup.sql<\/strong> script. However, you should first delete any data in the table because the data being added to the <code>airplanes<\/code> table references specific values in the <code>manufacturers<\/code> table. Starting with empty tables will also ensure that you\u2019re seeing the same results as in my examples. When you run the <code>INSERT<\/code> statements, be sure to execute them in the order specified in the file.<\/p>\n<h2>The <code><strong>SELECT<\/strong><\/code> statement syntax<\/h2>\n<p>A MySQL <code>SELECT<\/code> statement is typically used to retrieve data from a single table or from multiple tables. The statement is made up of one or more clauses that together provide the logic needed to retrieve the necessary data. The statement\u2019s syntax is fairly elaborate, but to help you get started, I\u2019ve narrowed it down to the most fundamental elements:<\/p>\n<pre class=\"theme:undefined lang:tsql decode:true\">SELECT [ALL | DISTINCT] select_list \r\n[FROM table_ref] \r\n[WHERE where_condition] \r\n[GROUP BY group_list] \r\n[HAVING having_condition]\r\n[ORDER BY order_list]<\/pre>\n<p>The five clauses shown in the syntax are highly versatile and can be used to build a wide range of statements:<\/p>\n<ul>\n<li>The <code>SELECT<\/code> clause is the only required clause in a <code>SELECT<\/code> statement. The clause typically specifies the columns from which to retrieve data from the target table or tables, but it can also be used to return the results of an expression, such as a system function or calculation.<\/li>\n<li>The <code>FROM<\/code> clause specifies the target table or tables from which to retrieve data. If you specify multiple tables, you are performing a join.<\/li>\n<li>The <code>WHERE<\/code> clause acts as a filter that limits the rows returned by the query. The clause defines one or more search conditions that must evaluate to true for a row to be returned. Multiple search conditions are linked together with logical operators that determine how to apply those conditions.<\/li>\n<li>The <code>GROUP<\/code> <code>BY<\/code> clause groups the data based on one or more specified expressions, which are typically columns in the target tables.<\/li>\n<li>The <code>HAVING<\/code> clause is similar to the <code>WHERE<\/code> clause because it defines one or more search conditions that limit the results. However, the <code>HAVING<\/code> clause is specific to grouped data and is processed after the <code>GROUP<\/code> <code>by<\/code> clause.<\/li>\n<li>The <code>ORDER<\/code> <code>BY<\/code> clause sorts the data based on one or more specified expressions, which are typically the columns in the target tables.<\/li>\n<\/ul>\n<p>There are a number of other clauses and options that I have not included here, and they are also important to understand, but for now, these five clauses provide a good starting point for learning how to use a <code>SELECT<\/code> statement to query a database.<\/p>\n<h2>The <code><strong>SELECT<\/strong><\/code> clause<\/h2>\n<p>At a minimum, the <code>SELECT<\/code> clause requires the <code>SELECT<\/code> keyword and the select list, which is made up of one or more expressions. An expression can be a column name, calculation, function, subquery, literal value, or other construction. The select list commonly includes columns from the tables referenced in the <code>FROM<\/code> clause (if one is included).<\/p>\n<p>Unlike the other clauses in the <code>SELECT<\/code> statement, the <code>SELECT<\/code> clause can stand on its own to create a very simple statement. For example, the following <code>SELECT<\/code> statement includes only the <code>SELECT<\/code> clause, and the select list within that clause includes only one expression:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT CURRENT_TIMESTAMP;<\/pre>\n<p>The expression, in this case, is the <code>CURRENT_TIMESTAMP<\/code> function, which returns the current date and time. If you run this statement, MySQL returns a single value that contains both the date and time in a format that depends on your location and server settings. For example, when I ran the statement, I received the following results:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">2022-06-03 15:03:13<\/pre>\n<p>As you can see, a <code>SELECT<\/code> statement can be fairly basic, as long as it includes the <code>SELECT<\/code> clause and a select list with at least one expression.<\/p>\n<h2>The <code><strong>FROM<\/strong><\/code> clause<\/h2>\n<p>The <code>FROM<\/code> clause references the table or tables that contain the source data. Although it is an optional clause, most <code>SELECT<\/code> statements include the <code>FROM<\/code> clause. If you are targeting only one table, you need only specify the <code>FROM<\/code> keyword, followed by the table name. For example, the following <code>SELECT<\/code> statement retrieves data only from the <code>airplanes<\/code> table:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT * FROM airplanes;<\/pre>\n<p>Notice that the <code>SELECT<\/code> clause specifies only an asterisk for the select list. In MySQL, like many relational database systems, you can use an asterisk to indicate that all columns should be returned from the table or tables referenced in the <code>FROM<\/code> clause, which in this case, points only to the <code>airplanes<\/code> table. Figure 1 shows part of the results returned by this statement. In all, the query should return 241 rows.<\/p>\n<p class=\"caption\"><img loading=\"lazy\" decoding=\"async\" width=\"1169\" height=\"303\" class=\"wp-image-94669\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/06\/table-description-automatically-generated-6.png\" alt=\"Table\n\nDescription automatically generated\" \/> Figure 1. Retrieving all rows and columns from the <code>airplanes<\/code> table<\/p>\n<p>The <code>SELECT<\/code> statement in the preceding example demonstrates the basic construction needed to return all rows and columns from a table. However, you can narrow down your <code>SELECT<\/code> clause by specifying the exact columns to return. For example, the following <code>SELECT<\/code> statement returns the <code>plane<\/code>, <code>engine_type<\/code>, and <code>engine_count<\/code> columns from the <code>airplanes<\/code> table:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT plane, engine_type, engine_count\r\nFROM airplanes;<\/pre>\n<p>Notice that the expressions (column names) in the select list are separated with commas, but there is no comma after the <code>SELECT<\/code> clause itself. The <code>SELECT<\/code> statement still returns 241 rows from the <code>airplanes<\/code> table; however, the results now include only these three columns, as shown in Figure 2.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-94670\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/06\/table-description-automatically-generated-7.png\" alt=\"An image showing the query results. Columns plane, engine_type, engine_count\" width=\"417\" height=\"305\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 2. Retrieving specific columns from the <code>airplanes<\/code> table<\/p>\n<p>You can refine your select list even further when retrieving data from the target table. For example, the select list in the following <code>SELECT<\/code> statement uses the <code>ROUND<\/code> system function to round the <code>wingspan<\/code> value to the nearest integer:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT plane, ROUND(wingspan) AS wingspan_rnd\r\nFROM airplanes;<\/pre>\n<p>The <code>wingspan<\/code> column is passed in as an argument to the <code>ROUND<\/code> function, which is followed by the <code>AS<\/code> keyword and then by the <code>wingspan_rnd<\/code> alias. The alias is assigned to the output column generated by the <code>ROUND<\/code> function, as shown in Figure 3. When assigning a column alias, you can omit the <code>AS<\/code> keyword, but it can be useful to retain for clarity.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-94671\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/06\/table-description-automatically-generated-8.png\" alt=\"An image showing the query results. Columns plane and wingspan_rnd\" width=\"342\" height=\"308\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 3. Using a system function in a select expression<\/p>\n<p>The <code>SELECT<\/code> statement still returns 241 rows from the <code>airplanes<\/code> table, but now it includes only the <code>plane<\/code> and <code>wingspan_rnd<\/code> columns. As you can see from the examples in the section, the <code>SELECT<\/code> clause works hand-in-hand with the <code>FROM<\/code> clause in determining what column data to return. However, the <code>FROM<\/code> clause itself remained unchanged in all these examples. When a <code>FROM<\/code> clause is included in a <code>SELECT<\/code> statement, it serves as the foundation on which the rest of the <code>SELECT<\/code> statement is built.<\/p>\n<h2>The <code><strong>WHERE<\/strong><\/code> clause<\/h2>\n<p>In the previous section, you saw how the <code>SELECT<\/code> clause can be used to limit the columns returned from the table specified in the <code>FROM<\/code> clause. The <code>WHERE<\/code> clause is similar in this respect, except that it is used to limit the rows returned from the target table.<\/p>\n<p>When defining the <code>WHERE<\/code> clause, you need to specify at least one search condition, which must evaluate to true for a row to be returned. For example, the following <code>SELECT<\/code> statement includes a <code>WHERE<\/code> clause that limits the returned rows to those with an <code>engine_type<\/code> value that equals <code>turboprop<\/code>:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT plane, ROUND(wingspan) AS wingspan_rnd\r\nFROM airplanes\r\nWHERE engine_type = 'turboprop';<\/pre>\n<p>The <code>WHERE<\/code> clause search condition (<code>engine_type<\/code> <code>=<\/code> <code>'turboprop'<\/code>) states that the <code>engine_type<\/code> value must equal <code>turboprop<\/code> for a row to be returned. The expression uses the equal (<code>=<\/code>) comparison operator to compare the <code>engine_type<\/code> value to the <code>turboprop<\/code> string. If they are equal, the search condition evaluates to true, and the row is returned.<\/p>\n<p>Figure 4 shows part of the results that the statement returns. The result set now includes only 26 rows because only those rows satisfy the search condition.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-94672\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/06\/table-description-automatically-generated-with-me-3.png\" alt=\"An image showing the query results with columns plane and wingspan_rnd\" width=\"342\" height=\"307\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 4. Using a <code>WHERE<\/code> clause to filter data<\/p>\n<p>When you add a <code>WHERE<\/code> clause to your <code>SELECT<\/code> statement, you can define multiple search conditions. For example, the following <code>SELECT<\/code> statement again includes a <code>WHERE<\/code> clause, but this time it specifies that the <code>engine_type<\/code> value must equal <code>turboprop<\/code> and that the <code>max_weight<\/code> value must be greater than <code>10000<\/code>:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT plane, ROUND(wingspan) AS wingspan_rnd\r\nFROM airplanes\r\nWHERE engine_type = 'turboprop' AND max_weight &gt; 10000;<\/pre>\n<p>The second search condition uses the greater than (<code>&gt;<\/code>) operator rather than equal, but the basic concept is the same in terms of filtering data. However, notice that the two search conditions are connected by the <code>AND<\/code> logical operator. This means that both search conditions must evaluate to true for a row to be returned. Figure 5 shows the results after running the <code>SELECT<\/code> statement, which now returns only 15 rows.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-94673\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/06\/table-description-automatically-generated-with-me-4.png\" alt=\"An image showing the query results with columns plane and wingspan_rnd\" width=\"340\" height=\"308\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 5. Defining multiple search conditions in a <code>WHERE<\/code> clause<\/p>\n<p>MySQL supports several types of logical operators. Although the <code>AND<\/code> operator is commonly used, you might want to define different logic. For example, you can use an <code>OR<\/code> operator to indicate that either of the two search conditions must evaluate to true, but not necessarily both. You can also string together more than two search conditions, but you need to be sure to implement the logic correctly, or you risk incorrect results. For more information about using logical operators, check out the <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/logical-operators.html\">MySQL documentation<\/a>.<\/p>\n<h2>The <code><strong>ORDER<\/strong><\/code> <code><strong>BY<\/strong><\/code> clause<\/h2>\n<p>The <code>ORDER<\/code> <code>BY<\/code> clause lets you sort the results returned by your <code>SELECT<\/code> statement. You can specify one or more expressions, which are typically columns. You can also define the sort order as either <code>ASC<\/code> (ascending) or <code>DESC<\/code> (descending). For example, the following <code>SELECT<\/code> statement is the same as the preceding one except that it now includes an <code>ORDER<\/code> <code>BY<\/code> clause that sorts the results by the <code>wingspan_rnd<\/code> column, in descending order:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT plane, ROUND(wingspan) AS wingspan_rnd\r\nFROM airplanes\r\nWHERE engine_type = 'turboprop' AND max_weight &gt; 10000\r\nORDER BY wingspan_rnd DESC;<\/pre>\n<p>Figure 6 shows the results returned by this statement. As you can see, you can use a column alias defined in the select list within your <code>ORDER<\/code> <code>BY<\/code> clause.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-94674\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/06\/table-description-automatically-generated-9.png\" alt=\"An image showing the query results with columns plane and wingspan_rnd\" width=\"371\" height=\"309\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 6. Sorting the results by the <code>wingspan_rnd<\/code> column<\/p>\n<p>When using an <code>ORDER<\/code> <code>BY<\/code> clause, you might discover that some values are duplicated. For example, the above results show that several planes have a wingspan of 55 feet and several others are 50 feet. In some cases, you might want to return a single column so you can view its range of values, such as in the following example:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT ROUND(wingspan) AS wingspan_rnd\r\nFROM airplanes\r\nWHERE engine_type = 'turboprop' AND max_weight &gt; 10000\r\nORDER BY wingspan_rnd DESC;<\/pre>\n<p>Now the <code>SELECT<\/code> statement returns only the <code>wingspan_rnd<\/code> column, as shown in Figure 7.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-94675\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/06\/a-picture-containing-application-description-auto-1.png\" alt=\"An image showing the query results with column wingspan_rnd\" width=\"110\" height=\"308\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 7. Returning a single column<\/p>\n<p>If all you\u2019re after is a range of values and don\u2019t want the duplicate values, you can add the <code>DISTINCT<\/code> keyword to your <code>SELECT<\/code> clause. You might do this, for example, to populate an application\u2019s drop-down list. The following <code>SELECT<\/code> statement uses <code>DISTINCT<\/code> to remove the duplicates in the <code>wingspan_rnd<\/code> column:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT DISTINCT ROUND(wingspan) AS wingspan_rnd\r\nFROM airplanes\r\nWHERE engine_type = 'turboprop' AND max_weight &gt; 10000\r\nORDER BY wingspan_rnd DESC;<\/pre>\n<p>Figure 8 shows the results of running the <code>SELECT<\/code> statement with <code>DISTINCT<\/code> included. Now the statement returns only eight rows, and each row is unique.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-94676\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/06\/table-description-automatically-generated-with-me-5.png\" alt=\"An image showing the query results with column wingspan_rnd\" width=\"107\" height=\"181\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 8. Removing duplicate rows<\/p>\n<p>The <code>SELECT<\/code> clause supports both the <code>DISTINCT<\/code> and <code>ALL<\/code> options. As you have seen, the <code>DISTINCT<\/code> option species that all duplicate rows should be removed from the result set. The <code>ALL<\/code> option specifies that all rows should be returned. This is the default, so you do not need to include it.<\/p>\n<h2>Joining tables in the <code><strong>FROM<\/strong><\/code> clause<\/h2>\n<p>When retrieving data from a MySQL database, you might want to pull the data from multiple tables, in which case you can create a join that effectively merges the results from both tables together. MySQL, like other relational database systems, supports multiple ways to join tables, although they don\u2019t necessarily approach joins in the same way.<\/p>\n<p>When you\u2019re first getting started with MySQL joins, it\u2019s important to know that most joins fall into one of two basic categories:<\/p>\n<ul>\n<li><strong>Inner joins.<\/strong> Matches one or more columns in two tables and returns all rows with matching values.<\/li>\n<li><strong>Outer joins.<\/strong> Matches one or more columns in two tables and returns all rows with matching values, but also returns the non-matching rows from either the left table (left outer join) or the right table (right outer join).<\/li>\n<\/ul>\n<p>The best way to understand how a join works is to see one in action. In the following example, I join the <code>airplanes<\/code> and <code>manufacturers<\/code> tables based on the <code>manufacturer_id<\/code> column in both tables:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT m.manufacturer, a.plane, a.engine_type, \r\n  a.engine_count, a.parking_area\r\nFROM airplanes a INNER JOIN manufacturers m\r\n  ON a.manufacturer_id = m.manufacturer_id\r\nWHERE a.parking_area &gt; 1000 AND max_weight &gt; 10000\r\nORDER BY a.parking_area DESC, m.manufacturer, a.plane;<\/pre>\n<p>This statement creates an inner join, as indicated by the <code>INNER<\/code> <code>JOIN<\/code> keywords in the <code>FROM<\/code> clause (in between the two table names). The <code>FROM<\/code> clause also includes the <code>ON<\/code> subclause, which specifies that the <code>manufacturer_id<\/code> value in the <code>manufacturers<\/code> table must equal the <code>manufacturer_id<\/code> value in the <code>airplanes<\/code> table.<\/p>\n<p>Because this is an inner join, MySQL will find all the rows with matching <code>manufacturer_id<\/code> values. You must make sure that your column references in any of the <code>SELECT<\/code> statement clauses are not ambiguous in any way, which can occur if the two tables contain columns with the same name, as in <code>manufacturer_id<\/code>. This includes the <code>FROM<\/code> clause itself.<\/p>\n<p>The easiest way to address any ambiguity is to assign aliases to the table names and then use those aliases when referencing the columns in the rest of the statement. For example, the <code>FROM<\/code> clause assigns the alias <code>a<\/code> to <code>airplanes<\/code>, so all column references are preceded by an <code>a<\/code>, followed by a period, and then followed by the column name.<\/p>\n<p>Figure 9 shows part of the results returned by the <code>SELECT<\/code> statement, which includes 152 rows in all.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-94677\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/06\/table-description-automatically-generated-10.png\" alt=\"An image showing the query results with columns manufacturer, plane, engine_type, engine_count, parking_area\" width=\"604\" height=\"308\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 9. Creating an inner join between two tables<\/p>\n<p>There is much more to joins than what I\u2019ve shown you here, but this should at least give you a sense of how they work until we can spend more time on them. In the meantime, you might want to check out the MySQL documentation on <a href=\"https:\/\/dev.mysql.com\/doc\/refman\/8.0\/en\/join.html\">joins<\/a>. The information can be a little difficult to weed through, but it might help you better understand how they work.<\/p>\n<h2>The <code><strong>GROUP<\/strong><\/code> <code><strong>BY<\/strong><\/code> clause<\/h2>\n<p>Another important clause in the <code>SELECT<\/code> statement is <code>GROUP<\/code> <code>BY<\/code>, which makes it possible to group and aggregate data in the target tables. The clause requires at least one expression in addition to the <code>GROUP<\/code> <code>BY<\/code> keywords. The expression is usually one of the columns in the target tables. For example, the following <code>SELECT<\/code> statement includes a <code>GROUP<\/code> <code>BY<\/code> clause that groups the data based on the <code>manufacturer_id<\/code> column in the <code>manufacturers<\/code> table:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT m.manufacturer, COUNT(*) AS plane_cnt\r\nFROM airplanes a INNER JOIN manufacturers m\r\n  ON a.manufacturer_id = m.manufacturer_id\r\nWHERE max_weight &lt; 1000000\r\nGROUP BY m.manufacturer_id\r\nORDER BY plane_cnt DESC;<\/pre>\n<p>When using a <code>GROUP<\/code> <code>BY<\/code> clause, you typically limit the columns in the select list to those included in the <code>GROUP<\/code> <code>BY<\/code> clause or to those derived from aggregate expressions. This example does both.<\/p>\n<p>The select list includes the <code>manufacturer_id<\/code> column, which is also referenced in the <code>GROUP<\/code> <code>BY<\/code> clause. The select list also includes the <code>COUNT(*)<\/code> aggregate function, which returns the total number of rows in each group. The <code>COUNT<\/code> function is a special type of function that takes an asterisk as its argument. The function provides a simple way to return the total number of rows (number of airplanes) for each manufacturer group. Figure 10 shows the statement\u2019s results.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-94678\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/06\/table-description-automatically-generated-11.png\" alt=\"An image showing query results with columns manufacturer and plane_cnt\" width=\"172\" height=\"150\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 10. Grouping data<\/p>\n<p>As you can see, the results show the total number of planes associated with each manufacturer. You can also group the data based on more than one column. For example, the <code>GROUP<\/code> <code>BY<\/code> clause in the following <code>SELECT<\/code> statement groups the data first by <code>manufacturer_id<\/code> and then by <code>engine_type<\/code>:<\/p>\n<pre class=\"lang:tsql theme:ssms2012-simple-talk\">SELECT m.manufacturer, a.engine_type, COUNT(*) AS plane_cnt\r\nFROM airplanes a INNER JOIN manufacturers m\r\n  ON a.manufacturer_id = m.manufacturer_id\r\nWHERE max_weight &lt; 1000000\r\nGROUP BY m.manufacturer_id, a.engine_type\r\nORDER BY m.manufacturer ASC, a.engine_type ASC;<\/pre>\n<p>The select list has also been updated to include the <code>engine_type<\/code> column, which is now in the <code>GROUP<\/code> <code>BY<\/code> clause. Figure 11 shows the results returned by the <code>SELECT<\/code> statement.<\/p>\n<p><strong><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-94679\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2022\/06\/a-picture-containing-text-indoor-screenshot-des-1.png\" alt=\"An image showing query results with columns manufacturer, engine_type, plane_cnt\" width=\"249\" height=\"271\" \/><\/strong><\/p>\n<p class=\"caption\">Figure 11. Grouping data by multiple columns<\/p>\n<p>The results now show the total number of airplanes for each engine type from each manufacturer. However, this time the results are sorted first by the <code>manufacturer<\/code> values and then by the <code>engine_type<\/code> values.<\/p>\n<h2>Working with the <code><strong>SELECT<\/strong><\/code> statement<\/h2>\n<p>The five clauses I\u2019ve covered here\u2014<code>SELECT<\/code>, <code>FROM<\/code>, <code>WHERE<\/code>, <code>ORDER<\/code> <code>BY<\/code>, and <code>GROUP<\/code> <code>BY<\/code>\u2014can provide you with a good foundation for getting started with <code>SELECT<\/code> statements. With these five clauses, you can build very precise queries that retrieve exactly the data you need from your MySQL databases.<\/p>\n<p>That said, this article only skims the surface of the <code>SELECT<\/code> statement. There is much more to each clause, and there are additional clauses. In fact, a full discussion of the <code>SELECT<\/code> statement could easily fill an entire volume\u2014if not more. But this information should at least provide you with a launching off point. Just know that there is much more to the MySQL <code>SELECT<\/code> statement than can be described in a single article.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Use SELECT statements to query a MySQL database. In this article, Robert Sheldon explains how. &hellip;<\/p>\n","protected":false},"author":221841,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[53,145792],"tags":[95506,4760,5854,5558],"coauthors":[6779],"class_list":["post-94655","post","type-post","status-publish","format-standard","hentry","category-featured","category-mysql","tag-automate","tag-group-by","tag-mysql","tag-select"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/94655","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221841"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=94655"}],"version-history":[{"count":5,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/94655\/revisions"}],"predecessor-version":[{"id":94684,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/94655\/revisions\/94684"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=94655"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=94655"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=94655"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=94655"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}