{"id":73216,"date":"2014-01-13T18:23:54","date_gmt":"2014-01-13T18:23:54","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/uncategorized\/oracle-for-absolute-beginners-part-2-sql\/"},"modified":"2021-07-14T13:07:36","modified_gmt":"2021-07-14T13:07:36","slug":"oracle-for-absolute-beginners-part-2-sql","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/oracle-databases\/oracle-for-absolute-beginners-part-2-sql\/","title":{"rendered":"Oracle for Absolute Beginners: Part 2 \u2013 SQL"},"content":{"rendered":"<p>A wise man* once said, no one\u2019s ever learned how to cook just by reading recipes. And so, since we painted in the background in <a title=\"Oracle for Absolute Beginners: Part 1 \u2013 Databases\" href=\"https:\/\/allthingsoracle.com\/oracle-for-absolute-beginners-part-1-databases\/\">Part 1<\/a>, we are now going to roll up our sleeves and dive in. By the end of this article you will be reading and writing SQL, the lingua franca of databases.<\/p>\n<p><em>[* that wise man was me.]<\/em><\/p>\n<h2>SQL<\/h2>\n<p>SQL stands for Structured Query Language (pronounced <i>ess-cue-ell<\/i> or <i>sequel<\/i>) and is the programming language used in the management of relational databases. And not just Oracle RDBMS; the code we are about to learn will work just as well with Microsoft\u2019s SQL Server, IBM\u2019s Informix, MySQL and dozens of others. SQL is very much the English of the database world; it is spoken in many environments.\u00a0 This is one reason why the skills you are about to learn are very valuable; they are eminently transferrable.<\/p>\n<p>SQL consists of a data definition language (DDL) and data manipulation language (DML).\u00a0 What this means is that we use SQL not only to define the tables into which we plan to put our data, but to manipulate (query, edit, delete, stuff like that) the data once it\u2019s in place.<\/p>\n<p>Manipulating data using SQL is easy, as the syntax isn\u2019t a million miles from the way we speak.\u00a0 For instance, to select all the data from a table you would use the SELECT \u2026 FROM <i>table_name<\/i> command.\u00a0 If, on the other hand, you wanted to update data, you\u2019d use the UPDATE command; and the DELETE and INSERT commands pretty much do what you\u2019d expect them to, too.<\/p>\n<p>It\u2019s easy.\u00a0 Let me show you.<\/p>\n<h2>Creating An Environment<\/h2>\n<p>Obviously we can\u2019t write database code without first having a database, so we\u2019re going to have to take something of a detour here and set ourselves up with an Oracle database that we can use.\u00a0 We\u2019ve got options: \u00a0we can download one from the <a href=\"http:\/\/oracle.com\" target=\"_blank\">Oracle.com<\/a> website. Only problem with that choice is that I like you and I don\u2019t want to put you through the torture of installing a database on our second date.\u00a0 So I\u2019d recommend that we go for option 2, and use one of the hosted workspaces that Oracle makes available on their <a href=\"http:\/\/apex.oracle.com\" target=\"_blank\">Apex.Oracle.com<\/a> website. (Apex \u2013 or Application Express \u2013 is this really great software development tool. It is beyond the scope of what we\u2019re doing now, but I\u2019d recommend that you look into it when you\u2019re more confident with your SQL and PL\/SQL. Now, however, we\u2019ll just take advantage of the database space available for free on the Apex website.)<\/p>\n<p>Requesting and setting up a workspace is reasonably straightforward, no harder than setting up a Facebook profile.\u00a0 You\u2019ll need an email address and a name for your workspace and schema (a schema name is reasonably analogous to a username) \u2013 and no, unlike Facebook, you don\u2019t need to trawl through all your photos looking for a profile pic in which you\u2019re not making a silly face.<\/p>\n<p>Once you\u2019ve created a workspace and logged in, you\u2019ll arrive at a screen with a number of choices; for our purposes, I need you to click the <b>SQL Workshop<\/b> button. \u00a0(The rest are to do with building Apex applications.)<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-4719\" alt=\"Apex-SQL Workshop\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/oracle\/2014\/01\/Apex-SQL-Workshop.jpg\" width=\"602\" height=\"196\" srcset=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/oracle\/2014\/01\/Apex-SQL-Workshop.jpg 602w, https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/oracle\/2014\/01\/Apex-SQL-Workshop-300x97.jpg 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/p>\n<p>We now have, effectively, what is pretty much an empty database (it\u2019s not <i>completely<\/i> empty; there are some demo tables). Before we can really start tearing into SQL, we need to create our tables.<\/p>\n<p>I\u2019ve put together a script (<a href=\"http:\/\/downloads.red-gate.com\/AllThingsOracle\/Oracle_For_Absolute_Beginners.zip\" target=\"_blank\">Oracle_For_Absolute_Beginners.sql<\/a>) that will create and populate the objects we require, and that I\u2019ll need you to run. To do this, click on the <b>SQL Scripts<\/b> button, upload the file, and run it. Once that is done, go back to the SQL Workshop: this time click the <b>Object Browser<\/b> button. You\u2019ll notice that in amongst the demo and Apex tables are our tables \u2013 FRIEND_NAME, ADDRESS, PHONE_NUMBER, FRIEND_ADDRESS and FRIEND_PHONE. Go on, click on them: go to the <b>Data<\/b> tab; you should recognise the records.<\/p>\n<p>All there? Good. Now, roll up your sleeves; we\u2019re going to write some SQL.<\/p>\n<h2>SQL Cont&#8217;d<\/h2>\n<p>Let\u2019s talk data manipulation: there are four main ways in which we can manipulate our data \u2013 we can SELECT it, we can INSERT new data, we can DELETE data, or we can UPDATE it.\u00a0 I\u2019ll get us started with SELECT.<\/p>\n<p>Imagine you decide to enter a team into this all-male basketball tournament, and you\u2019re wondering if you actually have enough male friends.\u00a0 Here\u2019s how you find out:<\/p>\n<pre>SELECT first_name, middle_name, last_name\r\nFROM friend_name\r\nWHERE gender = 'M';<\/pre>\n<p>Click on the <b>SQL Commands <\/b>\u00a0button, and paste the above code into the upper window. Hit run. You should see a list of all your male friends. Chandler\u2019s probably really rubbish at basketball, but that\u2019s not the point. You can probably see a clear line from the code to the resultset, but it\u2019s important that we study the syntax of SELECT statements to find out how they\u2019re stitched together.<\/p>\n<pre>SELECT &lt;comma-separated column list&gt;\r\nFROM &lt;table name&gt;\r\nWHERE &lt;condition(s)&gt;;<\/pre>\n<p>The required keywords are the SELECT \u2013 which must be followed by the name of one column, a comma-separated list of columns or an asterisk (*) which indicates that you want ALL columns \u2013 and the FROM \u2013 which must be followed by one table name or a comma-separated list of tables. The WHERE clause isn\u2019t mandatory; if you do not apply any conditions to your query, it\u2019ll return ALL matching records.<\/p>\n<p>Here\u2019s what I mean. You take a look at your male friends, realise that Chandler Bing couldn\u2019t play ball to save his life, and decide that you need to build your team from <i>all<\/i> your friends, not just the male ones.<\/p>\n<pre>SELECT *\r\nFROM FRIEND_NAME;<\/pre>\n<p>Notice the difference? This time we use the asterisk (*) in the SELECT clause indicating that we want <i>all<\/i> columns; and we do not include a WHERE clause, indicating we do not want to limit our resultset with any criteria.<\/p>\n<p>Oh, and did I forget to mention that you must end your statement with a semi-colon? Yeah, that\u2019s mandatory for all SQL statements.<\/p>\n<p>We\u2019ll talk a bit more about the WHERE clause a little later, but I should stop hogging the limelight and let you have a go. Let\u2019s say you need to view all the addresses your friends live at. Write a query to select all the columns from the ADDRESS table (hint: you don\u2019t need a WHERE clause for this).<\/p>\n<p>Done that? Good work. Now, try writing another query selecting only the HOUSE_NO and STREET columns from the ADDRESS table (hint: to select specified columns you\u2019ll need to put them in a comma-separated list in the SELECT clause).<\/p>\n<p>Hopefully you\u2019ve managed that and are now looking, slightly smugly, at a list of addresses. However, what if you did not want a list of ALL addresses; what if you only wanted a list of addresses at House 90? Then we\u2019ll need to write a WHERE clause telling Oracle not to return ALL the records in the table, but only those matching the condition we set. Let me show you what I mean.<\/p>\n<pre>SELECT HOUSE_NO, STREET\r\nFROM ADDRESS\r\nWHERE HOUSE_NO = 90;<\/pre>\n<p>The Where clause comes after the FROM clause and is made up of one or more conditions that may be true or false with Oracle returning all records that evaluate as true.<\/p>\n<p>Talking about where clauses gives me the opportunity to mention a few other things that you\u2019ll want to remember.\u00a0 I\u2019ll group these facts according to the different data types.<\/p>\n<h3>VARCHAR2:<\/h3>\n<ul>\n<li>If you want to compare a VARCHAR2 character string you must enclose it in single quotes. (<em>Where street =<strong>&#8216;<\/strong>Bedford Street<strong>&#8216;<\/strong>\u00a0<\/em> is correct; <em>where street = <strong>\u201c<\/strong>Bedford Street<strong>\u201d<\/strong><\/em> is not.) You must use the straight quote marks (&#8216;); if you use curly quotes, Oracle will error.<\/li>\n<li>Comparisons of varchar2 strings are case-sensitive. (Where street = &#8216;Bedford Street&#8217; is not the same thing as where street = &#8216;BEDFORD STREET&#8217;.) Often you will not want your query to be so finicky with cases; in those instances you can use the following function: where UPPER(street) = UPPER(&#8216;Bedford Street&#8217;).\u00a0 What this does, is convert both strings to upper case. (You can use the LOWER function \u2013 where LOWER(street) = LOWER(&#8216;Bedford Street&#8217;) \u2013 which converts them to lowercase).<\/li>\n<\/ul>\n<h3>NUMBER:<\/h3>\n<ul>\n<li>You do not need to enclose numbers in quotes to compare them. That is why, in our example, we could say where house_no = 90;<\/li>\n<li>The equals sign isn\u2019t the only operator you can use with numbers (or other data types). All the following also make sense:\n<ul>\n<li>House_no &lt; 90;<\/li>\n<li>House_no &lt;= 90<\/li>\n<li>House_no &gt; 90;<\/li>\n<li>House_no &gt;= 90;<\/li>\n<li>House_no != 90; &#8211; which, in case you\u2019re unsure, means the house number is NOT equal to 90.<\/li>\n<\/ul>\n<\/li>\n<li>You can also use ranges in your comparisons.\u00a0 If, for example, you knew the house number you were looking for was above 80 but below 100, there are two ways you could write your query.<\/li>\n<\/ul>\n<pre>SELECT HOUSE_NO, STREET\r\nFROM ADDRESS\r\nWHERE HOUSE_NO &gt;= 80\r\nAND HOUSE_NO &lt;= 100;<\/pre>\n<p>However, the following works just as well:<\/p>\n<pre>SELECT HOUSE_NO, STREET\r\nFROM ADDRESS\r\nWHERE HOUSE_NO BETWEEN 80 AND 100;<\/pre>\n<p>Got that? There is one more concept that I would like to discuss, and that is the NULL.\u00a0 A NULL is the term we use to describe something that is undefined, that has no value.\u00a0 It is not the same thing as the number 0 (because 0 itself is a value); it is undefined, nothing. Look at the data in our FRIEND_NAME\u00a0 table again (navigate to it by going back to the SQL Workshop screen and clicking the <b>Object Browser<\/b> button). Some of our friends have middle names:\u00a0 Joey\u2019s middle name is Francis, but Phoebe\u2019s middle name is undefined, nothing. It is NULL.<\/p>\n<p>MIDDLE_NAME is a VARCHAR2 column, but you can have nulls in all types of columns from VARCHAR2 to NUMBER to DATE.<\/p>\n<p>Because nulls have no value, the usual comparison operators (=, &gt;, &lt; and the rest) do not work with them (think about it; how can anything be equal or greater than something that is undefined?).\u00a0 For this reason, if we wanted to write a query to return all our friends who have a middle name, we would have to phrase it as follows:<\/p>\n<pre>SELECT *\r\nFROM FRIEND_NAME\r\nWHERE MIDDLE_NAME IS NOT NULL;<\/pre>\n<p>Conversely, if we wanted to return only those who do NOT have a middle name, it would be:<\/p>\n<pre>SELECT *\r\nFROM FRIEND_NAME\r\nWHERE MIDDLE_NAME IS NULL;<\/pre>\n<p>The IS NULL and IS NOT NULL operators work with columns of all data types \u2013 VARCHAR2, NUMBER and DATE.<\/p>\n<p>Speaking of the Date data type, I know I should now speak about the operators that work with them, but I would rather we go back to discussing Where clauses.\u00a0 Once we\u2019re old pros with them, we\u2019ll return to Dates.<\/p>\n<p>You may have noticed that we can have more than one condition in our Where clauses. In fact, using ANDs and ORs, we can build rather complex Where statements. I\u2019ll show you what I mean.<\/p>\n<p>We\u2019ve already established that your friend Chandler is rubbish at basketball. So when you see a flyer for an all-female cheerleading team, you think it\u2019ll be funny to send it to all your female friends <i>and<\/i> to Chandler. \u00a0But how do we write a query that\u2019ll give us all the names of your female friends \u2013 and Chandler.<\/p>\n<p>Here\u2019s how.<\/p>\n<pre>SELECT FIRST_NAME, MIDDLE_NAME, LAST_NAME\r\nFROM FRIEND_NAME\r\nWHERE GENDER = 'F'\r\nOR UPPER(FIRST_NAME) = 'CHANDLER';<\/pre>\n<p>You might want to pay attention to how we\u2019ve used the OR to link two conditions in our Where clause. It\u2019s also worth noting how we\u2019ve used the UPPER function to make our query case-insensitive.<\/p>\n<p>We\u2019ve talked about the SELECT clause (in which we list the columns we want our query to return), the FROM clause (in which we list the table(s) we want to query) and the WHERE clause (in which we apply conditions to our resultset). There is one further clause that we need to discuss \u2013 the ORDER BY clause. Using the order by clause we can sort the resultset according to rules we tell Oracle. Run the two following queries and notice the difference.<\/p>\n<pre>SELECT LAST_NAME, FIRST_NAME\r\nFROM FRIEND_NAME;<\/pre>\n<pre>SELECT LAST_NAME, FIRST_NAME\r\nFROM FRIEND_NAME\r\nORDER BY LAST_NAME;<\/pre>\n<p>You can use more than one column in your ORDER BY clause; if you do, Oracle will sort your resultset\u00a0 using the first named column and, in cases where the values in the first column are identical, will sort by the second column (and then the third etc).<\/p>\n<p>You can also instruct Oracle to order your resultset in descending order (the default order is ascending).<\/p>\n<pre>SELECT LAST_NAME, FIRST_NAME\r\nFROM FRIEND_NAME\r\nWHERE MIDDLE_NAME IS NULL\r\nORDER BY LAST_NAME DESC;<\/pre>\n<p>Please note that, as in the example above, your ORDER BY clause must be the final clause, coming after your WHERE clause (if you have one).<\/p>\n<h2>Conclusion<\/h2>\n<p>This is all getting very exciting, but I think we should stop and take a breath here. We\u2019ve learned how to construct select statements, modify the results we get and control its order. Next time we\u2019ll talk about adding data to our tables, deleting it, modifying it, and writing select statements that get data from more than one table. But just so you don\u2019t miss me too much in the meantime, here are some teasers for you to wrap your head around.<\/p>\n<ul>\n<li>Write a query selecting the first name, middle name and last name of all your male friends and any friend named Phoebe. Make your query case-insensitive.<\/li>\n<li>Amend the query you\u2019ve written above to order the result set by your friends\u2019 genders. Find out if you can order using a column that you have not selected.<\/li>\n<li>Write a query selecting all columns in the PHONE_NUMBER table for records with a phone_id between 2 and 6. Using the phone_number column, rearrange your resultset in descending order.<\/li>\n<li>Rewrite your query to select only the phone_number column for all records with a phone_id that is greater than or equal to 2.<\/li>\n<li>List the middle name and last name of all your friends who have a middle name, in descending order of surname.<\/li>\n<li>Write a query to find out if you have any friends that do not have a last name.<\/li>\n<\/ul>\n<h3>Next Article:\u00a0\u00a0<a href=\"https:\/\/allthingsoracle.com\/oracle-for-absolute-beginners-part-3-update-insert-delete\/?utm_source=allthingsoracle&amp;utm_medium=publink&amp;utm_content=articleseries\">Oracle for Absolute Beginners: Part 3 \u2013 Update, Insert, Delete<\/a><\/h3>\n","protected":false},"excerpt":{"rendered":"<p>A wise man* once said, no one\u2019s ever learned how to cook just by reading recipes. And so, since we painted in the background in Part 1, we are now going to roll up our sleeves and dive in. By the end of this article you will be reading and writing SQL, the lingua franca of databases. [* that wis&hellip;<\/p>\n","protected":false},"author":221907,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143533],"tags":[48366],"coauthors":[],"class_list":["post-73216","post","type-post","status-publish","format-standard","hentry","category-oracle-databases","tag-beginners-guide"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73216","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\/221907"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=73216"}],"version-history":[{"count":1,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73216\/revisions"}],"predecessor-version":[{"id":91700,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/73216\/revisions\/91700"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=73216"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=73216"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=73216"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=73216"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}