<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Caroline Caillaud</title>
    <description>The latest articles on DEV Community by Caroline Caillaud (@carol_caillaud).</description>
    <link>https://dev.to/carol_caillaud</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2703766%2Fbde296e3-b5dd-4443-a0cd-1c1cdcdc2f09.png</url>
      <title>DEV Community: Caroline Caillaud</title>
      <link>https://dev.to/carol_caillaud</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/carol_caillaud"/>
    <language>en</language>
    <item>
      <title>HackerRank 'The Pads' MySQL</title>
      <dc:creator>Caroline Caillaud</dc:creator>
      <pubDate>Mon, 01 Dec 2025 17:57:24 +0000</pubDate>
      <link>https://dev.to/carol_caillaud/hackerrank-the-pads-mysql-46n9</link>
      <guid>https://dev.to/carol_caillaud/hackerrank-the-pads-mysql-46n9</guid>
      <description>&lt;p&gt;&lt;strong&gt;PROBLEM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generate the following two result sets:&lt;/p&gt;

&lt;p&gt;Query an alphabetically ordered list of all names in OCCUPATIONS, immediately followed by the first letter of each profession in parentheses. For example: &lt;strong&gt;AnActorName(A)&lt;/strong&gt;, &lt;strong&gt;ADoctorName(D)&lt;/strong&gt;, &lt;strong&gt;AProfessorName(P)&lt;/strong&gt;, and &lt;strong&gt;ASingerName(S)&lt;/strong&gt;.&lt;br&gt;
Query the number of occurrences of each occupation in OCCUPATIONS. Sort the occurrences in ascending order, and output them in the following format:&lt;/p&gt;

&lt;p&gt;There are a total of &lt;strong&gt;[occupation_count]&lt;/strong&gt; &lt;strong&gt;[occupation]s&lt;/strong&gt;.&lt;br&gt;
where &lt;strong&gt;[occupation_count]&lt;/strong&gt; is the number of occurrences of an occupation in OCCUPATIONS and &lt;strong&gt;[occupation]&lt;/strong&gt; is the lowercase occupation name. If more than one Occupation has the same &lt;strong&gt;[occupation_count]&lt;/strong&gt;, they should be ordered alphabetically.&lt;/p&gt;

&lt;p&gt;Note: There will be at least two entries in the table for each occupation type.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Input Format&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Name&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Occupation&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The OCCUPATIONS table is described as follows:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Occupation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Samantha&lt;/td&gt;
&lt;td&gt;Doctor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Juia&lt;/td&gt;
&lt;td&gt;Actor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maria&lt;/td&gt;
&lt;td&gt;Actor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Meera&lt;/td&gt;
&lt;td&gt;Singer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ashely&lt;/td&gt;
&lt;td&gt;Professor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ketty&lt;/td&gt;
&lt;td&gt;Professor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Christeen&lt;/td&gt;
&lt;td&gt;Professor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jane&lt;/td&gt;
&lt;td&gt;Actor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jenny&lt;/td&gt;
&lt;td&gt;Doctor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prya&lt;/td&gt;
&lt;td&gt;Singer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Sample Output&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ashely(P)
Christeen(P)
Jane(A)
Jenny(D)
Julia(A)
Ketty(P)
Maria(A)
Meera(S)
Priya(S)
Samantha(D)
There are a total of 2 doctors.
There are a total of 2 singers.
There are a total of 3 actors.
There are a total of 3 professors.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;SOLUTION&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'('&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; 
            &lt;span class="n"&gt;occupation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;')'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;occupations&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s1"&gt;'There are a total of'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;occupation&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;LOWER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;occupation&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'s.'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;occupations&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;occupation&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;occupation&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;EXPLANATION&lt;/strong&gt;&lt;br&gt;
The problem requires generating two result sets based on the given table, which contains two columns: Name and Occupation.&lt;br&gt;
The Occupation column can only have four possible values: Doctor, Professor, Singer, or Actor.&lt;br&gt;
In the first query, list all the names from the OCCUPATION table in alphabetical order, and for each name, append the first letter of the occupation in parentheses. &lt;br&gt;
In the second query, we need to count the number of occurrences of each occupation type and list them in ascending order by count. If multiple occupations have the same count, they should be ordered alphabetically by occupation name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The output should follow this format: There are a total of [n] [occupation]s.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The exercise expects two separate queries to be written.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First Query&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'('&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; 
            &lt;span class="n"&gt;occupation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;')'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;occupations&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns all the names with the initial of their occupation in parentheses, sorted alphabetically by name.&lt;br&gt;
The &lt;code&gt;SUBSTR&lt;/code&gt; function extracts specific characters from each name, and the &lt;code&gt;CONCAT&lt;/code&gt; function combines all the strings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second Query&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s1"&gt;'There are a total of'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;occupation&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;LOWER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;occupation&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="s1"&gt;'s.'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;occupations&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;occupation&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;occupation&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;COUNT&lt;/code&gt; function counts the number of people in each profession.&lt;br&gt;
The &lt;code&gt;LOWER&lt;/code&gt; function converts each occupation to lowercase.&lt;br&gt;
Here, we need not only to count how many people belong to each occupation but also to display these results in a specific order, sorted by the number of people in each occupation and in ascending &lt;code&gt;ASC&lt;/code&gt; order.&lt;br&gt;
If there’s a tie, such as having 3 doctors and 3 actors, the results should be sorted alphabetically by the occupation name.&lt;br&gt;
The &lt;code&gt;ORDER BY COUNT( ) ASC&lt;/code&gt; clause sorts these groups in ascending order based on the number of people. The occupation column serves as the tiebreaker; if two professions have the same count, the results are sorted alphabetically by occupation name.&lt;/p&gt;

</description>
      <category>dataengineering</category>
      <category>beginners</category>
      <category>sql</category>
      <category>mysql</category>
    </item>
    <item>
      <title>SQL JOIN</title>
      <dc:creator>Caroline Caillaud</dc:creator>
      <pubDate>Tue, 30 Sep 2025 23:29:56 +0000</pubDate>
      <link>https://dev.to/carol_caillaud/sql-join-414j</link>
      <guid>https://dev.to/carol_caillaud/sql-join-414j</guid>
      <description>&lt;p&gt;When we need to combine multiple tables and analyse their data simultaneously, we have to write an SQL query using a &lt;code&gt;JOIN&lt;/code&gt;.&lt;br&gt;
A friend of mine, even after researching how to use &lt;code&gt;JOIN&lt;/code&gt;, said he was still having trouble writing queries with &lt;code&gt;JOIN&lt;/code&gt; clauses.&lt;br&gt;
Because of that, I decided to create a post that’s simple and straightforward, so he can clearly understand how to perform queries using &lt;code&gt;JOIN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s suppose I have two tables:&lt;/p&gt;

&lt;p&gt;Table A&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;serial&lt;/span&gt; &lt;span class="k"&gt;primary&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Table B&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;serial&lt;/span&gt; &lt;span class="k"&gt;primary&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;varchar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;a_id&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's insert data into them:&lt;/p&gt;

&lt;p&gt;Table A&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'A1'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'A2'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'A3'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Table B&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'B1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'B2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'B3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, we’ll have our tables with their respective data inserted:&lt;/p&gt;

&lt;p&gt;Table A &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;A1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;A2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;A3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Table B&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;a_id&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;B1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;B2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;B3&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Note that both tables share an ID column.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syntax&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
   &lt;span class="n"&gt;table1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;column_name&lt;/span&gt;
   &lt;span class="n"&gt;table2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;column_name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;table1&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="c1"&gt;-- choose the main table&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;table2&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="c1"&gt;-- indicates the table that will be combined&lt;/span&gt;
  &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;-- "match" condition between the tables&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a few things to keep in mind when writing a &lt;code&gt;JOIN&lt;/code&gt; in SQL. It’s necessary to specify which columns should be displayed. Since our example is very short and I want to make it clear what each JOIN returns, I’ll use * to make it easier to visualise. However, in more complex cases, we specify only the data we want to show in the &lt;code&gt;SELECT&lt;/code&gt; statement. &lt;br&gt;
A &lt;code&gt;JOIN&lt;/code&gt; can be an &lt;code&gt;INNER JOIN&lt;/code&gt;, &lt;code&gt;LEFT JOIN&lt;/code&gt;, &lt;code&gt;RIGHT JOIN&lt;/code&gt;, or &lt;code&gt;FULL OUTER JOIN&lt;/code&gt;.&lt;br&gt;
We use the &lt;code&gt;ON&lt;/code&gt; clause to specify which tables we are joining and how the tables are related. We need to explicitly state in the SQL query that the id column of table A corresponds to the a_id column of table B.&lt;/p&gt;

&lt;p&gt;Now, let’s run SQL statements that will select records with matching values in both tables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;INNER JOIN&lt;/strong&gt;&lt;br&gt;
QUERY:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OUTPUT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;  &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a_id&lt;/span&gt;
 &lt;span class="mi"&gt;1&lt;/span&gt;      &lt;span class="n"&gt;A1&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;      &lt;span class="n"&gt;B1&lt;/span&gt;      &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="mi"&gt;2&lt;/span&gt;      &lt;span class="n"&gt;A2&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;      &lt;span class="n"&gt;B2&lt;/span&gt;      &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;INNER JOIN&lt;/code&gt; returns rows where the condition A.id = B.a_id is true in both tables. B3 → a_id has no match. Since there’s no corresponding row, B3 isn't included in the &lt;code&gt;INNER JOIN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LEFT JOIN&lt;/strong&gt;&lt;br&gt;
QUERY:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OUTPUT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;  &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a_id&lt;/span&gt;
 &lt;span class="mi"&gt;1&lt;/span&gt;      &lt;span class="n"&gt;A1&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;      &lt;span class="n"&gt;B1&lt;/span&gt;      &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="mi"&gt;2&lt;/span&gt;      &lt;span class="n"&gt;A2&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;      &lt;span class="n"&gt;B2&lt;/span&gt;      &lt;span class="mi"&gt;2&lt;/span&gt;
 &lt;span class="mi"&gt;3&lt;/span&gt;      &lt;span class="n"&gt;A3&lt;/span&gt;    &lt;span class="k"&gt;null&lt;/span&gt;   &lt;span class="k"&gt;null&lt;/span&gt;    &lt;span class="k"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a &lt;code&gt;LEFT JOIN&lt;/code&gt;, all rows from table A are retained. When there’s no matching row in B, the fields from B are NULL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RIGHT JOIN&lt;/strong&gt;&lt;br&gt;
QUERY:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="k"&gt;RIGHT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OUTPUT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;  &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a_id&lt;/span&gt;
 &lt;span class="mi"&gt;1&lt;/span&gt;      &lt;span class="n"&gt;A1&lt;/span&gt;     &lt;span class="mi"&gt;1&lt;/span&gt;      &lt;span class="n"&gt;B1&lt;/span&gt;      &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="mi"&gt;2&lt;/span&gt;      &lt;span class="n"&gt;A2&lt;/span&gt;     &lt;span class="mi"&gt;2&lt;/span&gt;      &lt;span class="n"&gt;B2&lt;/span&gt;      &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;null&lt;/span&gt;   &lt;span class="k"&gt;null&lt;/span&gt;    &lt;span class="mi"&gt;3&lt;/span&gt;      &lt;span class="n"&gt;B3&lt;/span&gt;     &lt;span class="k"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a &lt;code&gt;RIGHT JOIN&lt;/code&gt;, all rows from table B are retained. When there’s no matching row in A, the fields from A are NULL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FULL OUTER JOIN&lt;/strong&gt;&lt;br&gt;
QUERY:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="k"&gt;FULL&lt;/span&gt; &lt;span class="k"&gt;OUTER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OUTPUT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;  &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;  &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a_id&lt;/span&gt;
 &lt;span class="mi"&gt;1&lt;/span&gt;      &lt;span class="n"&gt;A1&lt;/span&gt;      &lt;span class="mi"&gt;1&lt;/span&gt;     &lt;span class="n"&gt;B1&lt;/span&gt;       &lt;span class="mi"&gt;1&lt;/span&gt;
 &lt;span class="mi"&gt;2&lt;/span&gt;      &lt;span class="n"&gt;A2&lt;/span&gt;      &lt;span class="mi"&gt;2&lt;/span&gt;     &lt;span class="n"&gt;B2&lt;/span&gt;       &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="k"&gt;null&lt;/span&gt;   &lt;span class="k"&gt;null&lt;/span&gt;     &lt;span class="mi"&gt;3&lt;/span&gt;     &lt;span class="n"&gt;B3&lt;/span&gt;      &lt;span class="k"&gt;null&lt;/span&gt;
 &lt;span class="mi"&gt;3&lt;/span&gt;      &lt;span class="n"&gt;A3&lt;/span&gt;    &lt;span class="k"&gt;null&lt;/span&gt;    &lt;span class="k"&gt;null&lt;/span&gt;    &lt;span class="k"&gt;null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;FULL OUTER JOIN&lt;/code&gt; (or &lt;code&gt;OUTER JOIN&lt;/code&gt;) returns all rows from both A and B, with NULL where there is no match, and also includes rows that don’t have a corresponding match, such as the row A3, which had no match, and the row B3, which also had no match.&lt;/p&gt;

&lt;p&gt;Understanding JOINs is essential for efficiently working with relational databases. When we clearly understand the different types and how tables relate to one another, we can write queries better.&lt;/p&gt;

</description>
      <category>database</category>
      <category>sql</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>HackerRank 'Higher than 75 marks' MySQL and PostgreSQL</title>
      <dc:creator>Caroline Caillaud</dc:creator>
      <pubDate>Wed, 30 Apr 2025 21:15:45 +0000</pubDate>
      <link>https://dev.to/carol_caillaud/tutorial-com-postgresql-2dec</link>
      <guid>https://dev.to/carol_caillaud/tutorial-com-postgresql-2dec</guid>
      <description>&lt;p&gt;I'm trying to create the habit of revisiting exercises I've previously solved after some time, to check whether I'm truly retaining the concepts and topics I’ve studied.&lt;/p&gt;

&lt;p&gt;When redoing a HackerRank exercise, I decided to solve it using a different approach — this time with &lt;code&gt;ORDER BY RIGHT&lt;/code&gt;, which is valid in MySQL and useful when we want to sort a column by the end of the string values. I wasn’t aware of this usage before. So, the first time I solved the challenge, I used the &lt;code&gt;SUBSTRING&lt;/code&gt; function instead.&lt;/p&gt;

&lt;p&gt;This was the exercise:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0qyuvnjw38vjw8j2a3zc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0qyuvnjw38vjw8j2a3zc.png" alt=" " width="683" height="667"&gt;&lt;/a&gt;&lt;br&gt;
It’s a simple task. It asks us to select the names of students who scored more than 75, and order the results by the last three characters of their names in ascending order. If two or more names end with the same three letters, then sort them by their ID in ascending order.&lt;br&gt;
The difference lies in how the &lt;code&gt;SUBSTRING&lt;/code&gt; function works in PostgreSQL compared to MySQL.&lt;/p&gt;

&lt;p&gt;Here are some possible solutions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compatible with both MySQL and PostgreSQL:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT
  name
FROM 
  STUDENTS
WHERE 
  marks &amp;gt; 75 
ORDER BY 
  RIGHT(name, 3),
  id ASC;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Using &lt;code&gt;RIGHT(column, n)&lt;/code&gt; returns the last n characters of a string. So, this query sorts by the last three letters of the name. Simple and straightforward.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SUBSTRING()&lt;/code&gt; in MySQL:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT 
  name
FROM 
  STUDENTS
WHERE 
  marks &amp;gt; 75
ORDER BY 
  SUBSTRING(name,-3, 3), 
  id ASC;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;em&gt;Testing in PostgreSQL via WSL&lt;/em&gt;&lt;br&gt;
HackerRank doesn’t offer PostgreSQL as an option, but I was advised to test queries in the actual database environment. It takes more effort, but I find that it really helps me get used to the tool. Plus, new questions always come up — whether it's due to an error or a difference in PostgreSQL's syntax — and I end up learning beyond the scope of the original problem. And also, cause I believe this has helped me to absorb the concepts in a smooth way.&lt;/p&gt;

&lt;p&gt;When I tried to use &lt;code&gt;SUBSTRING&lt;/code&gt; the same way I did in the MySQL version, it didn’t work as expected in PostgreSQL.&lt;br&gt;
It turns out that PostgreSQL doesn’t support negative indices in &lt;code&gt;SUBSTRING&lt;/code&gt;. While it allows syntax like &lt;code&gt;SUBSTRING(column, -X, Y)&lt;/code&gt;, the behavior may not be what you'd expect.&lt;/p&gt;

&lt;p&gt;In my local database, I created a station table with a city column and added some city names. To better visualize what was happening, I ran this query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT 
  city, 
  SUBSTRING(city, -3, 3) AS error,
  RIGHT(city, 3) AS certo
FROM station;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this was the result:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc164v74bko0e5pwrrhb2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc164v74bko0e5pwrrhb2.png" alt=" " width="614" height="584"&gt;&lt;/a&gt;&lt;br&gt;
So, PostgreSQL accepts the syntax, but returns an empty string because the negative index is ignored in &lt;code&gt;SUBSTRING&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A simple way to view:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhbyzjewx7yew25aqvf0v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhbyzjewx7yew25aqvf0v.png" alt=" " width="800" height="163"&gt;&lt;/a&gt;&lt;br&gt;
PostgreSQL does not interpret &lt;code&gt;-3&lt;/code&gt; as “from the end.” It didn’t throw an error — just returned an empty string.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;SUBSTRING&lt;/code&gt; correctly:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbr88vstwjj7g189rj6lj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbr88vstwjj7g189rj6lj.png" alt=" " width="800" height="126"&gt;&lt;/a&gt;&lt;br&gt;
This returns the last 3 characters as expected.&lt;/p&gt;

&lt;p&gt;So, to use &lt;code&gt;SUBSTRING&lt;/code&gt; correctly in PostgreSQL for the same exercise, it would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT 
  name
FROM 
  students
WHERE 
  marks &amp;gt; 75
ORDER BY 
  SUBSTRING(name FROM LENGTH(name) - 2 FOR 3),
  id ASC;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the starting index must be positive, and it counts from the beginning of the string.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Practical Backup and Restore in PostgreSQL using pg_dump and pg_restore</title>
      <dc:creator>Caroline Caillaud</dc:creator>
      <pubDate>Tue, 11 Mar 2025 21:33:16 +0000</pubDate>
      <link>https://dev.to/carol_caillaud/backup-and-unstalling-postgresql-290i</link>
      <guid>https://dev.to/carol_caillaud/backup-and-unstalling-postgresql-290i</guid>
      <description>&lt;p&gt;In this article, you will learn how to practically perform backups and restore databases in PostgreSQL using the &lt;code&gt;pg_dump&lt;/code&gt; and &lt;code&gt;pg_restore&lt;/code&gt; tools.&lt;br&gt;
In PostgreSQL, to extract a database or a table into a file, we can generate backups using the &lt;code&gt;pg_dump&lt;/code&gt; utility. &lt;code&gt;pg_dump&lt;/code&gt; is an external tool used to export data and/or schema into a format that can be restored later.&lt;br&gt;
It is possible to generate a backup either in SQL text format or in a binary format.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CREATING A BACKUP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SQL BACKUP&lt;br&gt;&lt;br&gt;
We can use &lt;code&gt;pg_dump&lt;/code&gt; to save the entire database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pg_dump -U postgres_username -d db_name &amp;gt; backup.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or we can use &lt;code&gt;pg_dump&lt;/code&gt; to save only a specific table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pg_dump -U postgres_username -d db_name -t table_name &amp;gt; backup.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;pg_dump&lt;/code&gt; command also accepts common options that psql supports. So, in addition to specifying &lt;code&gt;-U&lt;/code&gt; (user) and &lt;code&gt;-d&lt;/code&gt; (database), you can explicitly indicate the server's host and port if needed.
&lt;code&gt;-h&lt;/code&gt; to specify the host (the PostgreSQL server address)
&lt;code&gt;-p&lt;/code&gt; to specify the port (the port where the server is listening).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;&amp;gt;&lt;/code&gt; symbol redirects the output of the command to a file, saving the result into a newly created &lt;code&gt;.sql&lt;/code&gt; file.&lt;br&gt;
This file will contain the necessary SQL commands to recreate the database or table in the same state and data as it was at the time of the backup.&lt;br&gt;
The generated file can be edited and opened in any text editor. It can also be versioned using tools like Git to track changes over time, or directly applied to another PostgreSQL server to recreate the database elsewhere.&lt;/p&gt;

&lt;p&gt;BINARY BACKUP(-Fc FORMAT)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pg_dump -U postgres_username -d db_name -Fc -f /path/backup.dump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;-Fc&lt;/code&gt; option instructs &lt;code&gt;pg_dump&lt;/code&gt; to save the backup in a custom binary format.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;-f&lt;/code&gt; option specifies the output file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;RESTORING THE BACKUP&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Important: To restore a backup, the target database must already exist.&lt;/p&gt;

&lt;p&gt;RESTORING FROM AN SQL BACKUP &lt;br&gt;
For a SQL restore use &lt;code&gt;psql&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql -U postgres -d newdb_name &amp;lt; backup.sql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;RESTORING FROM A BINARY BACKUP&lt;br&gt;
For large databases, it is recommended to use &lt;code&gt;pg_restore&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Binary backup custom:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pg_restore -U postgres -d newdb_name backup.dump
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;pg_restore&lt;/code&gt; command also accepts common options that psql supports. Therefore, you can also specify the server's host and port if needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With &lt;code&gt;pg_dump&lt;/code&gt; and &lt;code&gt;pg_restore&lt;/code&gt;, PostgreSQL provides flexible options for both simple exports and optimized backups for handling large volumes of data.&lt;/p&gt;

</description>
      <category>dataengineering</category>
      <category>beginners</category>
      <category>postgressql</category>
      <category>database</category>
    </item>
    <item>
      <title>Getting Started with PostgreSQL</title>
      <dc:creator>Caroline Caillaud</dc:creator>
      <pubDate>Mon, 10 Mar 2025 22:57:20 +0000</pubDate>
      <link>https://dev.to/carol_caillaud/getting-started-with-postgresql-3h05</link>
      <guid>https://dev.to/carol_caillaud/getting-started-with-postgresql-3h05</guid>
      <description>&lt;p&gt;In this article, I will cover the first steps needed to use a database.&lt;br&gt;
First, we need to install PostgreSQL. In my case, I am using PostgreSQL on Windows via WSL, so I used the terminal to run the necessary commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;INSTALLING POSTGRESQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before installing any packages, let's update the system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt upgrade -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's install PostgreSQL along with additional packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install postgresql postgresql-contrib -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start and enable postgres:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl start postgresql
sudo systemctl enable postgresql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check if the service is running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl status postgresql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything is working correctly, you should see something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;● postgresql.service - PostgreSQL database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql.service; enabled; preset: disabled)
     Active: active (running) since Sun 2025-03-09 08:11:05 -03; 2h 13min ago
 Invocation: 438028c9f2dd4a159e35421d9c15d7fe
       Docs: man:postgres(1)
   Main PID: 747 (postgres)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CREATING A ROLE FOR YOUR USER&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check the name of your user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;whoami
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access the database and create a role for your user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;su postgres
psql -U postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The prompt will change to postgres=#, indicating that we are inside the database.&lt;br&gt;
Inside postgres shell run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE ROLE &amp;lt;user-name&amp;gt; WITH LOGIN SUPERUSER CREATEDB CREATEROLE;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quit out of postgres:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\q
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CREATING A DATABASE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command to create a new PostgreSQL database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE DATABASE database_name;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you should be able to connect to postgres just using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;CONNECTING TO THE DATABASE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are two ways to connect.&lt;/p&gt;

&lt;p&gt;By running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\c database_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are unsure of the database name you want to access, you can list all databases in PostgreSQL by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\l
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no database is specified, PostgreSQL will try to connect to the default postgres database created during installation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CREATING TABLES&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To illustrate, let's create a users table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(150) UNIQUE NOT NULL,
    age INT CHECK (age &amp;gt;= 0),
    create_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference between using NOT NULL and UNIQUE NOT NULL is as follows:&lt;br&gt;
NOT NULL ensures that a column cannot have null values but allows duplicates.&lt;br&gt;
UNIQUE NOT NULL prevents null values and also enforces uniqueness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CRUD OPERATIONS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CRUD stands for Create, Read, Update, and Delete. The four fundamental operations in database management.&lt;/p&gt;

&lt;p&gt;INSERTING VALUES (Create)&lt;br&gt;
When a table is first created, it is empty. To insert values into a PostgreSQL table, use the INSERT INTO command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command adds rows to the table.&lt;/p&gt;

&lt;p&gt;READING DATA (Read)&lt;br&gt;
To do it use the SELECT command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name, email FROM users;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will display rows from the selected columns.&lt;/p&gt;

&lt;p&gt;UPDATING DATA (Update)&lt;br&gt;
The UPDATE operation is used when we need to modify existing data in a table, whether to correct a record or update some information. Use the the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UPDATE users
SET email = 'carlos.cpg@exemplo.com'
WHERE name = 'Carlos Silva';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will update the specified columns for all rows that match the condition. &lt;/p&gt;

&lt;p&gt;DELETING DATA (Delete)&lt;br&gt;
The DELETE operation removes data from a table. Use the DELETE command as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DELETE FROM users
WHERE name = 'Carlos Silva';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;DELETING A DATABASE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to delete everything and restart for practice, run the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DROP DATABASE users;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will delete the database you created.&lt;/p&gt;

&lt;p&gt;Now that we have configured PostgreSQL and explored the basic operations for inserting, querying, updating, and deleting data, you can start experimenting. Practice and explore to get comfortable with data manipulation and database operations. Have fun!&lt;/p&gt;

</description>
      <category>dataengineering</category>
      <category>beginners</category>
      <category>postgres</category>
      <category>database</category>
    </item>
    <item>
      <title>HackerRank 'Occupations' MySQL</title>
      <dc:creator>Caroline Caillaud</dc:creator>
      <pubDate>Sun, 09 Feb 2025 15:24:04 +0000</pubDate>
      <link>https://dev.to/carol_caillaud/hackerrank-occupations-mysql-kkh</link>
      <guid>https://dev.to/carol_caillaud/hackerrank-occupations-mysql-kkh</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;PROBLEM&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Pivot the Occupation column in OCCUPATIONS so that each Name is sorted alphabetically and displayed underneath its corresponding Occupation. The output should consist of four columns (Doctor, Professor, Singer, and Actor) in that specific order, with their respective names listed alphabetically under each column.&lt;/p&gt;

&lt;p&gt;Note: Print NULL when there are no more names corresponding to an occupation.&lt;/p&gt;

&lt;p&gt;Input Format&lt;/p&gt;

&lt;p&gt;The OCCUPATIONS table is described as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flaeor580nzq0bke3510b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flaeor580nzq0bke3510b.png" alt=" " width="468" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Occupation will only contain one of the following values: Doctor, Professor, Singer or Actor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41dt72b6025jrmex137v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41dt72b6025jrmex137v.png" alt=" " width="476" height="717"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4iuv8doawgbf3o345gkz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4iuv8doawgbf3o345gkz.png" alt=" " width="800" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;EXPLANATION&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
The first column is an alphabetically ordered list of Doctor names.&lt;br&gt;
The second column is an alphabetically ordered list of Professor names.&lt;br&gt;
The third column is an alphabetically ordered list of Singer names.&lt;br&gt;
The fourth column is an alphabetically ordered list of Actor names.&lt;br&gt;
The empty cell data for columns with less than the maximum number of names per occupation (in this case, the Professor and Actor columns) are filled with NULL values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;SOLUTION&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfaum285d342b484ldg1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdfaum285d342b484ldg1.png" alt=" " width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;EXPLANATION&lt;/em&gt;&lt;/strong&gt; &lt;br&gt;
The data is initially organized vertically, and the exercise requires the data to be arranged in a horizontal format. That is, we need to pivot the Occupation column from the OCCUPATIONS table so that each Name is sorted alphabetically and displayed under its respective occupation, with a separate column for each occupation.&lt;/p&gt;

&lt;p&gt;The output should contain four columns (Doctor, Professor, Singer, and Actor) with the names listed in alphabetical order under each column and should return NULL when there are no more names corresponding to an occupation.&lt;br&gt;
MySQL does not have a built-in PIVOT function. To solve this problem, it will be necessary to create a pivot table using CASE(), ROW_NUMBER() and MAX() to reorganize the data from the OCCUPATIONS table.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;CASE&lt;/span&gt; 
        &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Doctor'&lt;/span&gt; 
        &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;Doctor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;CASE&lt;/span&gt; 
        &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Professor'&lt;/span&gt; 
        &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;Professor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;CASE&lt;/span&gt; 
        &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Singer'&lt;/span&gt; 
        &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;Singer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;CASE&lt;/span&gt; 
        &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Actor'&lt;/span&gt; 
        &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;Actor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CASE expression organizes each name into the correct column in the pivot table. CASE checks each row and correctly distributes the names among the corresponding columns. The MAX() function selects the non-null name in each group.&lt;br&gt;
What happens is that if the row analyzed by the CASE logic is 'Doctor', the name is placed in the 'Doctor' column; otherwise, it returns NULL. The same applies to 'Professor', 'Singer', and 'Actor'.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="k"&gt;SELECT&lt;/span&gt;
       &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;occupation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
         &lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;occupation&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;occ_rownumber&lt;/span&gt;
   &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;OCCUPATIONS&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;subquery&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The subquery uses ROW_NUMBER() to create a unique index for each name within its occupation, allowing the data to be aligned within a partition by numbering the rows by occupation.&lt;/p&gt;

&lt;p&gt;By partitioning by Occupation and ordering by Name, we ensure that each occupation has its entries numbered in alphabetical order. This returns a list where each name is assigned a row number within its occupation.&lt;/p&gt;

&lt;p&gt;The ROW_NUMBER logic allows transforming the vertical list into a table, where each column represents an occupation, and each row contains a name sorted alphabetically.&lt;/p&gt;

&lt;p&gt;This way, we can correctly pivot the data in MySQL.&lt;/p&gt;

</description>
      <category>dataengineering</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>sql</category>
    </item>
  </channel>
</rss>
