<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ SQL - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Aprenda a codificar - de graça. Tutoriais de programação em Python, JavaScript, Linux e muito mais. ]]>
        </description>
        <link>https://www.freecodecamp.org/portuguese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ SQL - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 25 May 2026 04:46:52 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/tag/sql/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ SQL e bancos de dados – um curso completo para iniciantes ]]>
                </title>
                <description>
                    <![CDATA[ Neste curso, Mike Dane ensinará os fundamentos de gerenciamento de bancos de dados e SQL. O curso começa com Mike ajudando você a instalar o MySQL no Windows ou Mac. Em seguida, ele explora temas como design de schemas, operações  Create-Read-Update-Delete (CRUD) e outros fundamentos de bancos de dados. ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/sql-e-bancos-de-dados-um-curso-completo-para-iniciantes/</link>
                <guid isPermaLink="false">65cd087641193b03f6540000</guid>
                
                    <category>
                        <![CDATA[ SQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Rhuan Emanuel ]]>
                </dc:creator>
                <pubDate>Mon, 20 May 2024 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/05/news-sql-full-course.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/sql-and-databases-full-course/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">SQL and Databases - A Full Course for Beginners</a>
      </p><p>Neste curso, Mike Dane ensinará os fundamentos de gerenciamento de bancos de dados e SQL.</p><p>O curso começa com Mike ajudando você a instalar o MySQL no Windows ou Mac. Em seguida, ele explora temas como design de <em>schemas</em>, operações <em>Create-Read-Update-Delete</em> (CRUD) e outros fundamentos de bancos de dados.</p><p>Se você nunca estudou bancos de dados ou SQL antes, este curso é um excelente ponto de partida. O curso abrange:</p><ul><li>O que é um banco de dados</li><li>Tabelas e chaves</li><li>Fundamentos do SQL</li><li>Instalação do MySQL no Windows/Mac</li><li>Criação de tabelas</li><li>Inserção de dados</li><li>Restrições</li><li>Atualização e exclusão de dados</li><li>Consultas básicas</li><li>Introdução a bancos de dados de empresas</li><li>Criação de bancos de dados de empresas</li><li>Outras consultas básicas</li><li>Funções</li><li>Caracteres curingas</li><li>Uniões (<em>Union</em>)</li><li>Junções (<em>Join</em>)</li><li>Consultas aninhadas</li><li><em>On Delete</em></li><li><em>Triggers</em></li><li>Diagramas de entidade e relacionamento</li></ul><p>Você pode assistir o <a href="https://www.youtube.com/watch?v=HXV3zeQKqGY">curso completo de SQL em 4 horas, sem anúncios, no YouTube</a> (curso em inglês). Você pode assisti-lo clicando diretamente no link abaixo.</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/HXV3zeQKqGY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" title="SQL Tutorial - Full Database Course for Beginners" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><p>Boa programação para você!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Instrução de exclusão de linha no SQL – como remover os dados de uma tabela com consultas de exemplo ]]>
                </title>
                <description>
                    <![CDATA[ Não exagero ao dizer que gosto muito de trabalhar com o SQL em meus projetos pessoais e profissionais. Sua simplicidade e o fato de ser direto ao ponto apelam para o meu desejo de ter limites bem definidos com relação ao que a linguagem me deixará ou não "sair impune" ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/instrucao-de-exclusao-de-linha-no-sql-como-remover-os-dados-de-uma-tabela-com-consultas-de-exemplo/</link>
                <guid isPermaLink="false">65480747935ea203f011a7b8</guid>
                
                    <category>
                        <![CDATA[ SQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Sun, 05 Nov 2023 21:57:16 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/11/u-j-e-s-h-7ySd00IGyx4-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/sql-delete-row-statement-examples/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">SQL Delete Row Statement - How to Remove Data From a Table With Example Queries</a>
      </p><p>Não exagero ao dizer que gosto muito de trabalhar com o SQL em meus projetos pessoais e profissionais.</p><p>Sua simplicidade e o fato de ser direto ao ponto apelam para o meu desejo de ter limites bem definidos com relação ao que a linguagem me deixará ou não "sair impune" em termos de sintaxe.</p><p>O SQL é estruturado de maneira clara e concisa em termos de operação, onde a entrada do usuário dita os dados retornados. Daí meu comentário sobre ter limites bem definidos na sintaxe.</p><p>Embora eu celebre sua resiliência (o SQL foi criado em 1974, tendo sido lançado inicialmente em 1986) na comunidade de desenvolvedores, também sei que, ao trabalhar com dados, pode parecer que até mesmo os fundamentos são estressantes e assustadores.</p><p>Estou aqui (espero) para lançar luz sobre esses fundamentos de trabalho com dados: excluir uma linha inteira de dados.</p><p>Embora não analisemos o processo de <a href="https://www.freecodecamp.org/news/sql-create-table-statement-with-example-syntax/">estabelecer uma tabela no SQL</a> ou de <a href="https://www.freecodecamp.org/news/sql-update-statement-example-queries-for-updating-table-values/">preencher essa tabela com dados/atualizar esses dados</a>, faço aqui o link para esses outros artigos (em inglês) caso você queira saber mais ou ainda revisar o assunto.</p><p>Certo. Agora, vamos à parte divertida – vamos começar a excluir dados de uma tabela!</p><h2 id="vis-o-geral-de-exclus-o-de-linhas-no-sql"><strong>Visão geral de exclusão de linhas no SQL</strong></h2><p>Aqui está a tabela, que chamamos de <em><em>Cute_Doggos</em> </em>(cachorros fofos), que usaremos em nosso exemplo para a exclusão de dados:</p><!--kg-card-begin: html--><table style="box-sizing: inherit; border: 0px; margin: 0.5em 0px 2.5em; padding: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-variant-alternates: inherit; font-variant-position: inherit; font-weight: 400; font-stretch: inherit; line-height: inherit; font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, Oxygen, Ubuntu, Cantarell, &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, sans-serif; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 1.6rem; vertical-align: top; border-spacing: 0px; border-collapse: collapse; display: inline-block; overflow-x: auto; max-width: 100%; width: auto; white-space: nowrap; background: radial-gradient(at left center, rgba(0, 0, 0, 0.2) 0px, rgba(0, 0, 0, 0) 75%) 0px center / 10px 100% no-repeat scroll, radial-gradient(at right center, rgba(0, 0, 0, 0.2) 0px, rgba(0, 0, 0, 0) 75%) 100% center / 10px 100% scroll rgb(24, 26, 27); color: rgb(218, 215, 210); letter-spacing: normal; orphans: 2; text-align: start; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><tbody style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><th style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: 700; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 1.2rem; vertical-align: baseline; color: var(--darkreader-text--gray85); letter-spacing: 0.2px; text-align: left; text-transform: uppercase; background-color: var(--darkreader-bg--gray10);"></th></tr><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">Name</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Color</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Breed</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Age</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Weight</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Height</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Fav_Food</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Fav_Toy</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Dislikes</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat;">Allergies</td></tr></tbody><tbody style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">daisy</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">red</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">standard dachshund</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">1 yr</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">14</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">6</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">salmon flavored kibble</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">squeeky ball</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">birds flying over the yard</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat;">cats, baths, cleanliness</td></tr><tr data-darkreader-inline-bgcolor="" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-color: lightgrey; --darkreader-inline-bgcolor: #313537;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">winston</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">black/tan</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">rottweiler</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">3 yrs</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">41</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">17</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">literally anything</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">rope tug</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">staying off the couch</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat;">listening, behaving, not slobbering on everything</td></tr><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">sammie</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">light honey</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">golden retriever</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">9 yrs</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">46</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">19</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">beef flavored kibble</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">her bed</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">rambutcious puppies</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat;">none known</td></tr><tr data-darkreader-inline-bgcolor="" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-color: lightgrey; --darkreader-inline-bgcolor: #313537;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">penelope</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">gray and white</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">husky</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">9 months</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">16</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">12</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">old shoes</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">outside</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">kennel</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat;">none known</td></tr></tbody></table><!--kg-card-end: html--><p>Como você pode ter imaginado, são dados fictícios de uma tabela que eu tirei do nada. 🙂 Porém, espero que eles ilustrem aquilo a que nos dispomos.</p><p>Como acontece com a maioria dos aspectos de natureza técnica, nunca é demais verificar a documentação oficial também. Se você deseja fazer isso, a Microsoft tem ótimas <a href="https://docs.microsoft.com/en-us/sql/t-sql/statements/delete-transact-sql?view=sql-server-ver15">informações detalhadas sobre a instrução DELETE no SQL</a> (em inglês).</p><p>Vamos ao que importa nesse artigo – falar de exclusão de dados. &nbsp;A ação é tão simples quanto o próprio nome e aqui está a sintaxe de base:</p><p><code>DELETE FROM <em><em>n</em>ome<em>_</em>da<em>_tab</em>ela</em></code></p><h3 id="-com-essa-sintaxe-voc-exclui-todas-as-linhas-de-dados-da-tabela-inteira-"><strong>***Com essa sintaxe, você exclui todas as linhas de dados da tabela inteira.***</strong></h3><p>Em nosso exemplo acima, a consulta seria a seguinte:</p><p><code>DELETE FROM Cute_Doggos</code></p><p>Esse pode ser nossa finalidade. Quanto mais você escrever SQL, mais casos você encontrará de se usar a instrução DELETE nesse sentido.</p><p>Eu usei essa declaração muitas vezes para limpar uma tabela depois que ela foi preenchida com dados de teste. Essa abordagem nos permite manter os nomes de coluna, tipos de dados, índices e estrutura geral da tabela, de fato, sem excluir a tabela real.</p><p><em>Como observação<em>, </em>se sua finalidade for a de excluir todas as linhas dentro de uma tabela<em>, </em>a abordagem mais rápida seria a de usar a instrução<em> <a href="https://docs.microsoft.com/en-us/sql/t-sql/statements/truncate-table-transact-sql?view=sql-server-ver15">TRUNCATE TABLE</a></em> (em inglês), já que <em>us</em>a<em> </em>muito menos recursos de sistema<em>.</em></em></p><h2 id="exemplo-de-consultas-com-delete"><strong>Exemplo de consultas com Delete</strong></h2><p>Na grande maioria das vezes, quando você usa a funcionalidade DELETE, você vai querer direcionar melhor sua abordagem. Para isso, adicionaremos uma condição e a sintaxe ficará assim:</p><p><code>DELETE FROM <em><em>n</em>ome<em>_</em>da<em>_tab</em>ela</em> WHERE <em><em>condi</em>coes<em>_exis</em>tentes</em></code></p><p>Usando nossa tabela de cães acima, a consulta teria essa aparência:</p><p><code>DELETE FROM Cute_Doggos WHERE dbo.Cute_Doggos.Height &gt; 18</code></p><p>Isso removeria todas as entradas da nossa tabela que correspondam à nossa condição de que a altura (<em>height</em>) seja maior que 18. Se você estiver usando o Microsoft SQL Server Manager, receberá uma instrução de retorno assim:</p><p><code>(1 row affected)</code> (1 linha afetada)</p><p>Se você quiser ver as linhas de dados que foram excluídas (para fins de registro, indicações visuais para usuários e assim por diante), podemos usar a instrução OUTPUT para fazer exatamente isso.</p><p>Nossa tabela, agora, ficaria assim:</p><!--kg-card-begin: html--><table style="box-sizing: inherit; border: 0px; margin: 0.5em 0px 2.5em; padding: 0px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-variant-alternates: inherit; font-variant-position: inherit; font-weight: 400; font-stretch: inherit; line-height: inherit; font-family: -apple-system, BlinkMacSystemFont, &quot;Segoe UI&quot;, Roboto, Oxygen, Ubuntu, Cantarell, &quot;Open Sans&quot;, &quot;Helvetica Neue&quot;, sans-serif; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 1.6rem; vertical-align: top; border-spacing: 0px; border-collapse: collapse; display: inline-block; overflow-x: auto; max-width: 100%; width: auto; white-space: nowrap; background: radial-gradient(at left center, rgba(0, 0, 0, 0.2) 0px, rgba(0, 0, 0, 0) 75%) 0px center / 10px 100% no-repeat scroll, radial-gradient(at right center, rgba(0, 0, 0, 0.2) 0px, rgba(0, 0, 0, 0) 75%) 100% center / 10px 100% scroll rgb(24, 26, 27); color: rgb(218, 215, 210); letter-spacing: normal; orphans: 2; text-align: start; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><tbody style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><th style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: 700; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 1.2rem; vertical-align: baseline; color: var(--darkreader-text--gray85); letter-spacing: 0.2px; text-align: left; text-transform: uppercase; background-color: var(--darkreader-bg--gray10);"></th></tr><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: bold; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">Name</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Color</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Breed</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Age</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Weight</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Height</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Fav_Food</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Fav_Toy</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">Dislikes</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat;">Allergies</td></tr></tbody><tbody style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">daisy</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">red</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">standard dachshund</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">1 yr</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">14</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">6</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">salmon flavored kibble</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">squeeky ball</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">birds flying over the yard</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat;">cats, baths, cleanliness</td></tr><tr data-darkreader-inline-bgcolor="" style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-color: lightgrey; --darkreader-inline-bgcolor: #313537;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">winston</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">black/tan</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">rottweiler</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">3 yrs</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">41</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">17</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">literally anything</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">rope tug</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">staying off the couch</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat;">listening, behaving, not slobbering on everything</td></tr><tr style="box-sizing: inherit; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;"><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to right, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-size: 20px 100%; background-repeat: no-repeat;">penelope</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">gray and white</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">husky</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">9 months</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">16</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">12</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">old shoes</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">outside</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline;">kennel</td><td style="box-sizing: inherit; margin: 0px; padding: 6px 12px; border: var(--darkreader-border--gray10) 1px solid; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; line-height: inherit; font-family: inherit; font-optical-sizing: inherit; font-kerning: inherit; font-feature-settings: inherit; font-variation-settings: inherit; font-size: 16px; vertical-align: baseline; background-image: linear-gradient(to left, rgb(24, 26, 27) 50%, rgba(24, 26, 27, 0) 100%); background-position: 100% 0px; background-size: 20px 100%; background-repeat: no-repeat;">none known</td></tr></tbody></table><!--kg-card-end: html--><p>A condição que definimos é totalmente nossa escolha. Se isso for muito estreito para suas necessidades, há outras opções.</p><p>Digamos que você não se importe com os registros específicos que remove, apenas que você precisa remover um certo número de registros na tabela.</p><p><code>DELETE TOP 2 FROM Cute_Doggos</code></p><p>Você pode estar pensando que essa consulta removeria os dois primeiros registros da tabela – e você não está muito longe da verdade. O único problema é que, como o SQL armazena registros em uma ordem aleatória, essa sintaxe removerá dois registros <strong><u>ALEATÓRIOS</u></strong> da tabela.</p><p>Se quiser remover uma porcentagem de registros, o SQL também consegue fazer isso:</p><p><code>DELETE TOP 25 PERCENT FROM Cute_Doggos</code></p><p>Mais uma vez, a consulta excluirá registros <strong><u>ALEATÓRIOS</u></strong>. Em nosso exemplo, como temos quatro registros, essa consulta excluiria um registro aleatório (4 * 0.25 = 1).</p><p>Como comentário final, ao usar a palavra-chave TOP, não podemos usar uma instrução <a href="https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-ver15">ORDER BY</a>, em função da aleatoriedade do armazenamento de registros.</p><h2 id="conclus-o"><strong>Conclusão</strong></h2><p>Agora que você viu a instrução DELETE em ação, você está pronto para testar e excluir todos os dados de todas as tabelas! Quem sabe não faça isso? Poderá custar um final de semana prolongado de restauração de backups. 😉</p><p>De qualquer forma, agora você está pronto para começar a usá-la bem.</p><p>Espero que o artigo tenha sido útil. Confira meu <a href="https://jonathansexton.me/blog">blog</a> (em inglês). Atualmente, estou reconstruindo o blog em Gatsby/WordPress. Confira um artigo em breve sobre o assunto. No blog, eu frequentemente publico artigos sobre desenvolvimento para a web, vida em geral e aprendizagem.</p><p>Enquanto estiver lá no blog, inscreva-se também na minha newsletter. Você pode fazer isso no canto superior direito da página principal do blog. Gosto de enviar artigos interessantes (meus e de outros autores), recursos e ferramentas para desenvolvedores de vez em quando.</p><p>Se tiver perguntas sobre este artigo ou sobre qualquer coisa em geral, deixe um oi no <a href="https://twitter.com/jj_goose">Twitter</a>, em outra rede social que você encontrar na newsletter, na página principal do blog ou no meu <a href="https://www.freecodecamp.org/news/author/jonathan/">perfil aqui no freeCodeCamp</a>. 😀</p><p>Tenha um ótimo dia! Boa aprendizagem e uma ótima programação para você.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Tutorial de Joins em SQL: Cross Join, Full Outer Join, Inner Join, Left Join e Right Join ]]>
                </title>
                <description>
                    <![CDATA[ As joins (ou junções, no português) do SQL permitem que nossos sistemas de gerenciamento de banco de dados sejam, bem, relacionais. Joins nos permitem reconstruir nossas tabelas separadas dentro do banco de dados em relacionamentos poderosos para nossas aplicações. Neste artigo, vamos olhar para cada tipo diferente de join no ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/tutorial-de-joins-em-sql-cross-join-full-outer-join-inner-join-left-join-e-right-join/</link>
                <guid isPermaLink="false">62b9ce78a3520206e79ceb2b</guid>
                
                    <category>
                        <![CDATA[ SQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Glaucia Esppenchutz ]]>
                </dc:creator>
                <pubDate>Fri, 22 Jul 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/07/5f9c98fc740569d1a4ca1d31.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/sql-joins-tutorial/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">SQL Joins Tutorial: Cross Join, Full Outer Join, Inner Join, Left Join, and Right Join.</a>
      </p><p>As <em>joins</em> (ou junções, no português)<em> </em>do SQL permitem que nossos sistemas de gerenciamento de banco de dados sejam, bem, <em>relacionais.</em></p><p><em>Joins</em> nos permitem reconstruir nossas tabelas separadas dentro do banco de dados em relacionamentos poderosos para nossas aplicações.</p><p>Neste artigo, vamos olhar para cada tipo diferente de <em>join</em> no SQL e aprender como usá-los.</p><p>Sobre o que vamos tratar neste artigo:</p><ul><li>O que é uma <em>join</em>? </li><li>Como configurar nosso banco de dados</li><li><code>CROSS JOIN</code></li><li>Como configurar nossos dados de exemplo (diretores e filmes)</li><li><code>FULL OUTER JOIN</code></li><li><code>INNER JOIN</code></li><li><code>LEFT JOIN</code> / <code>RIGHT JOIN</code></li><li>Como filtrar dados com <a href="https://www.freecodecamp.org/news/sql-joins-tutorial/#filtering-using-left-join"><code>LEFT JOIN</code></a></li><li>Múltiplas <em>joins</em></li><li><em>Joins</em> com condições extras</li><li>A realidade sobre escrever <em>queries </em>(ou buscas, no português) &nbsp;com <em>joins</em></li></ul><p><em>(Alerta de spoiler: abordaremos cinco tipos diferentes– mas você precisará saber apenas dois deles!)</em></p><h2 id="o-que-uma-join"><strong>O que é uma join?</strong></h2><p>Uma <em>join</em> é uma operação que combina duas ou mais linhas em uma só linha.</p><p>Essas linhas normalmente vêm de duas tabelas diferentes, embora não precisem ser.</p><p>Antes de olharmos como escrever uma <em>join</em> propriamente dita, vamos olhar para o que seria o resultado de uma <em>join</em>.</p><p>Vamos pegar o exemplo de um sistema que armazena informações sobre usuários e seus endereços.</p><p>As linhas da tabela que armazena as informações dos usuários se parece com isso:</p><pre><code> id |     name     |        email        | age
----+--------------+---------------------+-----
  1 | John Smith   | johnsmith@gmail.com |  25
  2 | Jane Doe     | janedoe@Gmail.com   |  28
  3 | Xavier Wills | xavier@wills.io     |  3
...
(7 rows)</code></pre><p>E as linhas da tabela que armazena informações sobre os endereços seria desse jeito:</p><pre><code> id |      street       |     city      | state | user_id
----+-------------------+---------------+-------+---------
  1 | 1234 Main Street  | Oklahoma City | OK    |       1
  2 | 4444 Broadway Ave | Oklahoma City | OK    |       2
  3 | 5678 Party Ln     | Tulsa         | OK    |       3
(3 rows)</code></pre><p>Poderíamos escrever <em>queries </em>para buscar separadamente tanto as informações do usuário como seu endereço – mas, idealmente, poderíamos escrever <em>apenas uma query</em> para retornar todos os usuários e seus endereços no mesmo resultado.</p><p>E é exatamente isso que a <em>join</em> nos permite!</p><p>Veremos como escrever essas junções em breve, mas, se juntarmos nossas informações de usuário com as de endereço, teremos este resultado:</p><pre><code> id |     name     |        email        | age | id |      street       |     city      | state | user_id
----+--------------+---------------------+-----+----+-------------------+---------------+-------+---------
  1 | John Smith   | johnsmith@gmail.com |  25 |  1 | 1234 Main Street  | Oklahoma City | OK    |       1
  2 | Jane Doe     | janedoe@Gmail.com   |  28 |  2 | 4444 Broadway Ave | Oklahoma City | OK    |       2
  3 | Xavier Wills | xavier@wills.io     |  35 |  3 | 5678 Party Ln     | Tulsa         | OK    |       3
(3 rows)
</code></pre><p>Aqui, podemos ver todos os nossos usuários e seus respectivos endereços em um único resultado.</p><p>Além de produzir resultados combinados, outro uso importante das <em>joins</em> é retirar informações adicionais da nossa busca, que também podem ser filtrados. </p><p>Por exemplo, se quisermos enviar uma correspondência física para nossos usuários que moram na cidade de Oklahoma, podemos usar essa <em>join</em> e definir um filtro baseado na coluna <code>city</code>.</p><p>Agora que sabemos o propósito das <em>joins</em>– vamos escrever algumas!</p><h2 id="como-configurar-nosso-banco-de-dados"><strong>Como configurar nosso banco de dados</strong></h2><p>Antes de começarmos a escrever nossas <em>queries</em>, precisamos configurar nosso banco de dados.</p><p>Para os nossos exemplos, usaremos o PostgreSQL, mas a escrita das <em>queries </em>e os conceitos mostrados aqui podem ser facilmente traduzidos para qualquer outro sistema de banco de dados moderno (como o MySQL, o SQL Server etc.).</p><p>Para trabalhar com um banco PostgreSQL, usamos o <code><a href="https://www.postgresql.org/docs/current/app-psql.html">psql</a></code> – a linha de comando interativa do PostgreSQL. Se você tiver algum outro <em>client</em> (ou serviço, em português) com o qual esteja acostumado a trabalhar, não tem problema.</p><p>Vamos começar criando nosso banco de dados. Com o PostegreSQL já <a href="https://www.postgresql.org/download/">instalado</a>, podemos executar o comando <code>createdb &lt;nome-do-banco-da-dados&gt;</code> em nosso terminal para criar um banco de dados. Vou chamar o meu de <code>fcc</code>:</p><pre><code class="language-bash">$ createdb fcc
</code></pre><p>Vamos iniciar o console interativo usando o comando &nbsp;<code>psql</code> e conectar o banco de dados que criamos usando <code>\c &lt;nome-do-banco-de-dados&gt;</code>:</p><pre><code class="language-bash">$ psql
psql (11.5)
Type "help" for help.

john=# \c fcc
You are now connected to database "fcc" as user "john".
fcc=#
</code></pre><blockquote><em><strong>Observação</strong>: eu limpei o resultado do <code>psql</code> nesses exemplos para tornar mais fácil a leitura. Então, não se preocupe se o seu retorno não for exatamente igual ao que está vendo no seu terminal.</em></blockquote><p>Eu aconselho você a seguir os exemplos e executar as <em>queries</em> por conta própria. Desse modo, você aprenderá e se lembrará com mais facilidade, trabalhando nos exemplos em vez de apenas ler sobre eles.</p><p>Agora, vamos às <em>joins</em>!</p><h2 id="cross-join"><strong><strong><code>CROSS JOIN</code></strong></strong></h2><p>O tipo mais simples de <em>join</em> que podemos fazer é a <code>CROSS JOIN</code>, ou "<em>produto cartesiano</em>".</p><p>Essa <em>join</em> pega cada linha de uma tabela e a combina com cada linha da outra tabela.</p><p>Se tivéssemos duas listas – uma contendo <code>1, 2, 3</code> e a outra contendo <code>A, B, C</code> — o produto cartesiano das duas seria:</p><pre><code>1A, 1B, 1C
2A, 2B, 2C
3A, 3B, 3C
</code></pre><p>Cada valor da primeira lista é emparelhado com cada valor da segunda lista.</p><p>Vamos escrever esse exemplo simples em uma <em>query</em> do SQL.</p><p>Primeiro, vamos criar duas tabelas simples e inserir alguns dados:</p><pre><code class="language-sql">CREATE TABLE letters(
  letter TEXT
);

INSERT INTO letters(letter) VALUES ('A'), ('B'), ('C');

CREATE TABLE numbers(
  number TEXT
);

INSERT INTO numbers(number) VALUES (1), (2), (3);
</code></pre><p>Nossas duas tabelas, <code>letters</code> e <code>numbers</code>, tem apenas uma coluna: um simples campo de texto. </p><p>Agora, vamos juntá-las com um <code>CROSS JOIN</code>:</p><pre><code class="language-sql">SELECT *
FROM letters
CROSS JOIN numbers;
</code></pre><pre><code> letter | number
--------+--------
 A      | 1
 A      | 2
 A      | 3
 B      | 1
 B      | 2
 B      | 3
 C      | 1
 C      | 2
 C      | 3
(9 rows)

</code></pre><p>Esse é o tipo mais simples de <em>join</em> que podemos fazer – mesmo nesse exemplo simples, no entanto, podemos ver a <em>join</em> em funcionamento: as duas linhas separadas (uma de <code>letters</code> e outra de <code>numbers</code>) foram combinadas para formar uma única linha.</p><p>Embora esse tipo de <em>join</em> seja frequentemente discutido como sendo apenas um exemplo acadêmico, ele tem um bom caso de uso: cobrir intervalos de datas.</p><h3 id="cross-join-com-intervalos-de-datas"><strong><strong><code>CROSS JOIN</code> </strong>com intervalos de datas</strong></h3><p>Um bom caso de uso do <code>CROSS JOIN</code> é pegar cada linha de uma tabela e aplicar para cada dia de um intervalo de data específico.</p><p>Digamos, por exemplo, que estávamos criando uma aplicação que monitora atividades diárias – coisas como escovar os dentes, tomar o café da manhã ou tomar banho.</p><p>Se você quiser gerar um registro <em>para cada tarefa</em> e <em>para cada dia</em> da semana passada, você poderia usar a <code>CROSS JOIN</code> em um intervalo de datas.</p><p>Para criar esse intervalo, podemos usar a função <code><a href="https://www.postgresql.org/docs/current/functions-srf.html">generate_series</a></code>:</p><pre><code class="language-sql">SELECT generate_series(
  (CURRENT_DATE - INTERVAL '5 day'),
  CURRENT_DATE,
  INTERVAL '1 day'
)::DATE AS day;
</code></pre><p>A função <code><a href="https://www.postgresql.org/docs/current/functions-srf.html">generate_series</a></code> recebe três parâmetros:</p><p>O primeiro parâmetro é o valor de início. Nesse exemplo, usamos <code>CURRENT_DATE - INTERVAL '5 day'</code>. Isso retorna o dia atual menos 5 dias – ou "cinco dias atrás".</p><p>O segundo parâmetro é a data atual (<code>CURRENT_DATE</code>).</p><p>O terceiro parâmetro é o "intervalo" – ou o quanto nós queremos incrementar em cada valor por vez. Já que essas são tarefas diárias, vamos usar o intervalo de um dia (<code>INTERVAL '1 day'</code>).</p><p>Juntando tudo, isso gera uma série de datas começando de cinco dias atrás, terminando hoje e sendo incrementando um dia por vez.</p><p>Finalmente, removemos a parte do tempo, lançando a saída desses valores para uma data usando <code>::DATE</code>, e atribuímos um nome à coluna usando <code>AS day</code> para fazer com que o retorno seja um pouco melhor.</p><p>O resultado dessa <em>query</em> são os últimos cinco dias mais o dia de hoje:</p><pre><code>    day
------------
 2020-08-19
 2020-08-20
 2020-08-21
 2020-08-22
 2020-08-23
 2020-08-24
(6 rows)
</code></pre><p>Voltando ao nosso exemplo de tarefas diárias, vamos criar uma tabela simples para conter as tarefas que queremos completar e inserir algumas tarefas:</p><pre><code class="language-sql">CREATE TABLE tasks(
  name TEXT
);

INSERT INTO tasks(name) VALUES
('Escovar os dentes'),
('Tomar o café da manhã'),
('Tomar banho'),
('Vestir-se');
</code></pre><p>Nossa tabela <code>tasks</code> tem apenas uma coluna, <code>name</code>, Nela, nós inserimos quatro tarefas.</p><p>Agora, vamos usar a <code>CROSS JOIN</code> nas nossas tarefas e na <em>query</em> que cria o intervalo de datas:</p><pre><code class="language-sql">SELECT
  tasks.name,
  dates.day
FROM tasks
CROSS JOIN
(
  SELECT generate_series(
    (CURRENT_DATE - INTERVAL '5 day'),
    CURRENT_DATE,
    INTERVAL '1 day'
  )::DATE	AS day
) AS dates
</code></pre><p>(Já que nossa <em>query</em> de produção de dados não é exatamente uma tabela, nós podemos escrevê-la como uma <em>subquery</em>.)</p><p>A partir dessa <em>query,</em> retornamos o nome das tarefas e o dia. O resultado terá essa aparência:</p><pre><code>     name              |    day
---------------+-------------------
 Escovar os dentes     | 2020-08-19
 Escovar os dentes     | 2020-08-20
 Escovar os dentes     | 2020-08-21
 Escovar os dentes     | 2020-08-22
 Escovar os dentes     | 2020-08-23
 Escovar os dentes     | 2020-08-24
 Tomar o café da manhã | 2020-08-19
 Tomar o café da manhã | 2020-08-20
 Tomar o café da manhã | 2020-08-21
 Tomar o café da manhã | 2020-08-22
 ...
 (24 rows)
</code></pre><p>Como esperávamos, nós recebemos uma linha para cada tarefa para cada dia em nosso intervalo de datas. </p><p>A <code>CROSS JOIN</code> é a <em>join</em> mais simples que podemos fazer, mas, para ver os outros tipos, vamos precisar de um exemplo mais realista de configuração de tabela:</p><h2 id="como-configurar-nossos-dados-de-exemplo-diretores-e-filmes-">Como configurar nossos dados de exemplo (diretores e filmes)</h2><p>Para ilustrar os próximos tipos de <em>join</em>, vamos usar o exemplo de <em><em>movies</em> e <em>movie directors</em> </em>(filmes e diretores de filmes, em português)<em><em>.</em></em></p><p>Nessa situação, o filme tem apenas um diretor, mas um filme não necessariamente precisa ter um diretor associado – imagine que um novo filme foi anunciado mas a escolha do diretor ainda não foi feita ou confirmada.</p><p>Nossa tabela <code>directors</code> armazenará o nome de cada diretor, enquanto a tabela <code>movies</code> armazenará o nome de cada filme, assim como a referência do diretor associado (caso haja uma).</p><p>Vamos criar as duas tabelas e inserir alguns dados nelas:</p><pre><code class="language-sql">CREATE TABLE directors(
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL
);

INSERT INTO directors(name) VALUES
('John Smith'),
('Jane Doe'),
('Xavier Wills')
('Bev Scott'),
('Bree Jensen');

CREATE TABLE movies(
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL,
  director_id INTEGER REFERENCES directors 
);

INSERT INTO movies(name, director_id) VALUES
('Movie 1', 1),
('Movie 2', 1),
('Movie 3', 2),
('Movie 4', NULL),
('Movie 5', NULL);
</code></pre><p>Temos cinco diretores, cinco filmes e três desses filmes tem diretores associados a eles. O diretor com o ID 1 tem dois filmes, enquanto o diretor ID 2 tem um.</p><h2 id="full-outer-join"><strong><strong><code>FULL OUTER JOIN</code></strong></strong></h2><p>Agora que temos alguns dados para trabalhar, vamos olhar a <code>FULL OUTER JOIN</code>.</p><p>A <code>FULL OUTER JOIN</code> tem algumas semelhanças com a <code>CROSS JOIN</code>, mas algumas diferenças importantes.</p><p>A primeira diferença é que uma <code>FULL OUTER JOIN</code> precisa de uma <strong>condição para fazer a <em>join</em>.</strong></p><p>A condição da <em>join</em> especifica como duas linhas de duas tabelas diferentes estão relacionadas uma com a outra, bem como o critério a ser usado para juntá-las.</p><p>No nosso exemplo, nossa tabela <code>movies</code> tem uma referência aos diretores através da coluna <code>director_id</code>. Essa coluna corresponde à coluna <code>id</code> da tabela <code>directors</code>. Essas são as duas colunas que usaremos como condição para a <em>join</em>.</p><p>Escrevemos essa <em>join</em> entre as duas tabelas desta forma:</p><pre><code class="language-sql">SELECT *
FROM movies
FULL OUTER JOIN directors
  ON directors.id = movies.director_id;
</code></pre><p>Observe a condição da <em>join</em> especificada, que corresponde o filme ao seu diretor : <code>ON movies.director_id = directors.id</code>.</p><p>Nossos resultados vão se parecer com um produto cartesiano estranho:</p><pre><code>  id  |  name   | director_id |  id  |     name
------+---------+-------------+------+--------------
    1 | Movie 1 |           1 |    1 | John Smith
    2 | Movie 2 |           1 |    1 | John Smith
    3 | Movie 3 |           2 |    2 | Jane Doe
    4 | Movie 4 |        NULL | NULL | NULL
    5 | Movie 5 |        NULL | NULL | NULL
 NULL | NULL    |        NULL |    5 | Bree Jensen
 NULL | NULL    |        NULL |    4 | Bev Scott
 NULL | NULL    |        NULL |    3 | Xavier Wills
(8 rows)
</code></pre><p>As primeiras linhas que veremos são aquelas onde o filme tem um diretor e que nossa condição de <em>join</em> avaliou como verdadeira.</p><p>No entanto, após essas linhas, vemos algumas linhas restantes de cada tabela – mas com valores <code>NULL</code>, onde a outra tabela não teve uma correspondência.</p><blockquote><strong>Observação</strong>: se você não está familiarizado com valores do tipo <code>NULL</code>, pode <a href="https://www.freecodecamp.org/news/sql-operators-tutorial/#dealing-with-missing-data-null-">veja esta explicação</a> (em inglês) no tutorial de operadores SQL</blockquote><p>Também vemos outra diferença entre a <code>CROSS JOIN</code> e a <code>FULL OUTER JOIN</code> aqui. A <code>FULL OUTER JOIN</code> retorna uma linha distinta em cada linha– diferentemente da <code>CROSS JOIN</code>, que retorna múltiplas. </p><h2 id="inner-join"><strong><strong><code>INNER JOIN</code></strong></strong></h2><p>O próximo tipo de <em>join</em>, a <code>INNER JOIN</code>, é mais comumente utilizado do que todos os outros.</p><p>Uma <em>inner join</em> <strong>retorna apenas as linhas onde a condição de <em>join</em> é verdadeira.</strong></p><p>No nosso exemplo, uma <em>inner join</em> entre nossas tabelas de &nbsp;<code>movies</code> e <code>directors</code> retornaria apenas registros onde o filme possui um diretor atribuído.</p><p>A sintaxe é basicamente a mesma que vimos antes:</p><pre><code class="language-sql">SELECT *
FROM movies
INNER JOIN directors
  ON directors.id = movies.director_id;
</code></pre><p>Nosso resultado mostra apenas os três filmes que possuem um diretor.</p><pre><code> id |  name   | director_id | id |    name
----+---------+-------------+----+------------
  1 | Movie 1 |           1 |  1 | John Smith
  2 | Movie 2 |           1 |  1 | John Smith
  3 | Movie 3 |           2 |  2 | Jane Doe
(3 rows)
</code></pre><p>Já que uma <em>inner join</em> inclui apenas as linhas que tenham uma condição de <em>join</em> que a corresponda, a <em>ordem de junção das duas tabelas não fará diferença.</em></p><p>Se invertermos a ordem das tabelas, a <em>query</em> terá o mesmo resultado:</p><pre><code class="language-sql">SELECT *
FROM directors
INNER JOIN movies
  ON movies.director_id = directors.id;
</code></pre><pre><code> id |    name    | id |  name   | director_id
----+------------+----+---------+-------------
  1 | John Smith |  1 | Movie 1 |           1
  1 | John Smith |  2 | Movie 2 |           1
  2 | Jane Doe   |  3 | Movie 3 |           2
(3 rows)
</code></pre><p>Como listamos a tabela de <code>directors</code> primeiro nessa <em>query</em> e selecionamos todas as colunas (<code>SELECT *</code>), vemos a coluna de <code>directors</code> primeiro e depois as outras colunas de <code>movies</code> - o resultado dos dados, no entanto, é o mesmo.</p><p>Essa é uma propriedade muito útil das <em>inner joins</em>, mas não é uma realidade de todos os outros tipos de <em>join</em>– como veremos no nosso próximo exemplo.</p><h2 id="left-join-right-join"><strong><strong><code>LEFT JOIN</code>/<code>RIGHT JOIN</code></strong></strong></h2><p>Os próximos dois tipos de <em>join</em> usam um modificador (<code>LEFT</code> ou <code>RIGHT</code>) que afeta qual dado de tabela será incluído no resultado final.</p><blockquote><strong>Observação</strong>: a <code>LEFT JOIN</code> e a <code>RIGHT JOIN</code> também podem ser referidas como <code>LEFT OUTER JOIN</code> e <code>RIGHT OUTER JOIN</code>.</blockquote><p>Essas <em>joins</em> são usadas em <em>queries</em> onde queremos retornar todos os dados da tabela específica e,<em> caso existam</em>, os dados correspondentes da outra tabela. </p><p>Se os dados correspondentes não existirem, ainda teremos os dados da tabela primária.</p><p>Seria como uma busca por uma informação específica e um bônus caso a informação de bônus exista.</p><p>Isso será simples de entender com um exemplo. Vamos encontrar todos os filmes e seus diretores, mas não vamos nos importar com o fato de eles terem um diretor ou não – esse é o bônus:</p><pre><code class="language-sql">SELECT *
FROM movies
LEFT JOIN directors
  ON directors.id = movies.director_id;
</code></pre><p>A <em>query</em> segue o mesmo padrão que vimos antes – apenas especificamos a <em>join</em> como <code>LEFT JOIN</code>.</p><p>Nesse exemplo, a tabela <code>movies</code> é a tabela <em>left</em> (ou da esquerda, em português).</p><p>Se escrevermos a <em>query</em> em uma linha, fica um pouco mais fácil de ver:</p><pre><code class="language-sql">... FROM movies LEFT JOIN directors ...
</code></pre><p><strong>Uma <em>left join</em> retorna todos os dados da tabela da esquerda.</strong></p><p>Uma <em>left join</em> retorna também todas linhas da tabela da direita (a outra tabela, no caso) <strong>que correspondam à condição da <em>join</em>.</strong></p><p>As colunas da tabela da direita <strong>que não correspondam à condição da <em>join</em> serão retornadas como <code>NULL</code>.</strong></p><pre><code> id |  name   | director_id |  id  |    name
----+---------+-------------+------+------------
  1 | Movie 1 |           1 |    1 | John Smith
  2 | Movie 2 |           1 |    1 | John Smith
  3 | Movie 3 |           2 |    2 | Jane Doe
  4 | Movie 4 |        NULL | NULL | NULL
  5 | Movie 5 |        NULL | NULL | NULL
(5 rows)
</code></pre><p>Olhando para os resultados, &nbsp;podemos ver o porquê de esse tipo de <em>join</em> ser útil para uma busca que "<em>traga tudo disto e, caso exista, um pouco daquilo</em>".</p><h3 id="right-join"><strong><strong><code>RIGHT JOIN</code></strong></strong></h3><p>A <code>RIGHT JOIN</code> funciona exatamente como a <code>LEFT JOIN</code> – exceto que as regras agora são inversas para a ordem das tabelas.</p><p>Em uma <em>right join</em>, todas as linhas da tabela da direita são retornadas. A tabela da esquerda é retornada com base na condição da <em>join</em>.</p><p>Vamos usar a mesma query que vimos acima e substituir a <code>LEFT JOIN</code> por <code>RIGHT JOIN</code>:</p><pre><code class="language-sql">SELECT *
FROM movies
RIGHT JOIN directors
  ON directors.id = movies.director_id;
</code></pre><pre><code>  id  |  name   | director_id | id |     name
------+---------+-------------+----+--------------
    1 | Movie 1 |           1 |  1 | John Smith
    2 | Movie 2 |           1 |  1 | John Smith
    3 | Movie 3 |           2 |  2 | Jane Doe
 NULL | NULL    |        NULL |  5 | Bree Jensen
 NULL | NULL    |        NULL |  4 | Bev Scott
 NULL | NULL    |        NULL |  3 | Xavier Wills
(6 rows)
</code></pre><p>Nosso resultado agora são todas as linhas de <code>directors</code> e, caso existam, os dados de <code>movies</code>.</p><p>Tudo &nbsp;o que fizemos foi trocar qual tabela é considerada primária – a tabela da qual queremos ver todos os dados sem considerar se temos dados associados.</p><h3 id="left-join-right-join-na-produ-o-de-aplica-es"><strong><strong><code>LEFT JOIN</code>/<code>RIGHT JOIN</code> </strong>na produção de aplicações</strong></h3><p>Na criação de uma aplicação, eu utilizo apenas <code>LEFT JOIN</code> e nunca uso <code>RIGHT JOIN</code>.</p><p>Eu faço isso porque, na minha opinião, um <code>LEFT JOIN</code> torna a <em>query</em> muito mais fácil de ser lida e entendida.</p><p>Quando estou escrevendo uma <em>query,</em> gosto de começar a pensar em um resultado "base", digamos todos os dados de filmes, e então trazer (ou retirar) os grupos de informações dessa base.</p><p>Como eu gosto de começar com uma base, a <code>LEFT JOIN</code> se encaixa bem nessa linha de raciocínio. Eu quero todas as linhas da minha tabela base (a tabela da esquerda) e, condicionalmente, as da tabela da direita. </p><p>Na prática, eu não acho que já tenha visto uma <code>RIGHT JOIN</code> em uma aplicação em produção. Entenda, não tem nada de errado com uma <code>RIGHT JOIN</code> - eu apenas acho que deixa a <em>query</em> mais difícil de entender.</p><h3 id="reescrevendo-o-right-join"><strong>Reescrevendo o<strong> <code>RIGHT JOIN</code></strong></strong></h3><p>Se quisermos virar nosso cenário acima, ao invés de retornar todos os diretores e condicionalmente seus filmes, podemos facilmente reescrever a <code>RIGHT JOIN</code> para uma <code>LEFT JOIN</code>.</p><p>Tudo que precisamos fazer é trocar a ordem das tabelas da <em>query</em> e mudar a palavra <code>RIGHT</code> para <code>LEFT</code>:</p><pre><code class="language-sql">SELECT *
FROM directors
LEFT JOIN movies
  ON movies.director_id = directors.id;
</code></pre><blockquote>Observação: eu gosto de colocar a tabela que será adicionada (a da direita– no exemplo acima, de <code>movies</code>) primeiro na condição da join (<code>ON movies.director_id = ...</code>) – mas essa é apenas minha preferencia pessoal.</blockquote><h2 id="como-filtrar-dados-com-left-join"><strong>Como filtrar dados com<strong> <code>LEFT JOIN</code></strong></strong></h2><p>Existem dois casos de uso para a <code>LEFT JOIN</code> (ou a <code>RIGHT JOIN</code>).</p><p>O primeiro, nós já vimos: retornar todas as linhas de uma tabela e, condicionalmente, as da outra.</p><p>O segundo caso de uso é para retornar as linhas da primeira tabela onde os <strong>dados da segunda tabela não estão presentes.</strong></p><p>O cenário tem essa aparência: <em>encontre todos os diretores que não pertencem a nenhum filme.</em></p><p>Para fazer isso, vamos começar com uma <code>LEFT JOIN</code> e nossa tabela <code>directors</code> será a primária ou a tabela da esquerda: </p><pre><code class="language-sql">SELECT *
FROM directors
LEFT JOIN movies
  ON movies.director_id = directors.id;
</code></pre><p>Para um diretor que não pertence a nenhum filme, as colunas da tabela <code>movies</code> são <code>NULL</code>:</p><pre><code> id |     name     |  id  |  name   | director_id
----+--------------+------+---------+-------------
  1 | John Smith   |    1 | Movie 1 |           1
  1 | John Smith   |    2 | Movie 2 |           1
  2 | Jane Doe     |    3 | Movie 3 |           2
  5 | Bree Jensen  | NULL | NULL    |        NULL
  4 | Bev Scott    | NULL | NULL    |        NULL
  3 | Xavier Wills | NULL | NULL    |        NULL
(6 rows)
</code></pre><p>No nosso exemplo, os diretores com ID 3, 4 e 5 não pertencem a nenhum filme.</p><p>Para filtrar nosso resultado para apenas essas linhas, podemos adicionar uma cláusula <code>WHERE</code> que retornará apenas os filmes onde os dados são <code>NULL</code>:</p><pre><code class="language-sql">SELECT *
FROM directors
LEFT JOIN movies
  ON movies.director_id = directors.id
WHERE movies.id IS NULL;
</code></pre><pre><code> id |     name     |  id  | name | director_id
----+--------------+------+------+-------------
  5 | Bree Jensen  | NULL | NULL |        NULL
  4 | Bev Scott    | NULL | NULL |        NULL
  3 | Xavier Wills | NULL | NULL |        NULL
(3 rows)
</code></pre><p>E aqui estão nossos três filmes sem diretor!</p><p>É comum usar a coluna <code>id</code> da tabela para filtrar os dados (<code>WHERE movies.id IS NULL</code>), mas todas as colunas da tabela <code>movies</code> são <code>NULL</code> - nesse caso, qualquer uma funcionaria.</p><p>Já que sabemos que todas as colunas de <code>movies</code> seriam <code>NULL</code>. Na <em>query</em> acima, poderíamos escrever apenas <code>SELECT directors.*</code> ao invés de <code>SELECT *</code> para retornar todas as informações dos diretores.</p><h3 id="usando-a-left-join-para-encontrar-dados-correspondentes"><strong>Usando a <strong><code>LEFT JOIN</code></strong> para encontrar dados correspondentes<strong> </strong></strong></h3><p>Na nossa <em>query</em> anterior, encontramos diretores que <em>não pertenciam</em> a nenhum filme.</p><p>Usando a mesma estrutura, podemos encontrar os diretores que <em>pertencem </em>a algum filme mudando apenas a nossa condição <code>WHERE</code> para buscar as linhas onde os dados do filme <em>não são</em> <code>NULL</code>:</p><pre><code class="language-sql">SELECT *
FROM directors
LEFT JOIN movies
  ON movies.director_id = directors.id
WHERE movies.id IS NOT NULL;
</code></pre><pre><code> id |    name    | id |  name   | director_id
----+------------+----+---------+-------------
  1 | John Smith |  1 | Movie 1 |           1
  1 | John Smith |  2 | Movie 2 |           1
  2 | Jane Doe   |  3 | Movie 3 |           2
(3 rows)
</code></pre><p>Pode até parecer prático, mas, na verdade, nós implementamos novamente a <code>INNER JOIN</code>!</p><h2 id="m-ltiplas-joins"><strong>Múltiplas<strong> joins</strong></strong></h2><p>Nós já vimos como combinar duas tabelas, mas e se quisermos fazer múltiplas <em>joins</em> em uma linha?</p><p>Na verdade, é bastante simples, mas para ilustrar isso vamos precisar de uma terceira tabela: <code>tickets</code>.</p><p>Essa tabela representará os ingressos vendidos por filme:</p><pre><code class="language-sql">CREATE TABLE tickets(
  id SERIAL PRIMARY KEY,
  movie_id INTEGER REFERENCES movies NOT NULL
);

INSERT INTO tickets(movie_id) VALUES (1), (1), (3);
</code></pre><p>A tabela <code>tickets</code> &nbsp;tem apenas um <code>id</code> e a referência a um filme: <code>movie_id</code>.</p><p>Nós também inserimos dois ingressos vendidos para o filme ID 1, e um ingresso vendido para o filme ID 3.</p><p>Agora, vamos combinar <code>directors</code> com <code>movies</code> — e, então, <code>movies</code> com <code>tickets</code>!</p><pre><code class="language-sql">SELECT *
FROM directors
INNER JOIN movies
  ON movies.director_id = directors.id
INNER JOIN tickets
  ON tickets.movie_id = movies.id;
</code></pre><p>Já que ambas são <em>inner joins</em>, a ordem em que nós escrevemos a <em>join</em> não importa. Poderíamos ter começado com <code>tickets</code> e, então, adicionado <code>movies</code> e finalizado com a adição de <code>directors</code>.</p><p>Novamente, tudo se resume a forma na qual você está tentando consultar e o que faz a busca mais compreensível.</p><p>No nosso resultado, vamos perceber que reduzimos ainda mais as linhas retornadas:</p><pre><code> id |    name    | id |  name   | director_id | id | movie_id
----+------------+----+---------+-------------+----+----------
  1 | John Smith |  1 | Movie 1 |           1 |  1 |        1
  1 | John Smith |  1 | Movie 1 |           1 |  2 |        1
  2 | Jane Doe   |  3 | Movie 3 |           2 |  3 |        3
(3 rows)
</code></pre><p>Isso faz sentido porque adicionamos outra <code>INNER JOIN</code>. Na prática, ela adiciona uma outra condicional do tipo "AND" na nossa busca.</p><p>Nossa <em>query</em>, essencialmente, diz: <em>"retorne todos os diretores que pertencem a filmes <strong>que também tenham</strong> ingressos vendidos"</em></p><p>Se, ao invés disso, quiséssemos encontrar diretores que pertencem a filmes <em>que talvez não tenham ingressos vendidos ainda</em>, poderíamos substituir nossa <code>INNER JOIN</code> por uma <code>LEFT JOIN</code>:</p><pre><code class="language-sql">SELECT *
FROM directors
JOIN movies
  ON movies.director_id = directors.id
LEFT JOIN tickets
  ON tickets.movie_id = movies.id;
</code></pre><p>Podemos ver que <code>Movie 2</code> agora volta ao nosso conjunto de resultados:</p><pre><code> id |    name    | id |  name   | director_id |  id  | movie_id
----+------------+----+---------+-------------+------+----------
  1 | John Smith |  1 | Movie 1 |           1 |    1 |        1
  1 | John Smith |  1 | Movie 1 |           1 |    2 |        1
  2 | Jane Doe   |  3 | Movie 3 |           2 |    3 |        3
  1 | John Smith |  2 | Movie 2 |           1 | NULL |     NULL
(4 rows)
</code></pre><p>Esse filme ainda não teve nenhum ingresso vendido, mas foi excluído anteriormente dos resultados por conta da <code>INNER JOIN</code>.</p><p>Vou deixar isso como um <em>Exercício para o Leitor™</em>. Como você encontraria os diretores que pertencem a algum filme e <strong>não tem</strong> nenhum ingresso vendido?</p><h3 id="a-ordem-de-execu-o-das-joins"><strong>A ordem de execução das <em>j<strong>oin</strong>s</em></strong></h3><p>No fim, realmente não ligamos para a ordem como as <em>joins</em> são executadas.</p><p>Uma das diferenças principais entre o SQL e outras linguagens de programação modernas é o fato de o SQL ser uma linguagem <strong>declarativa</strong>.</p><p>Isso significa que especificamos o que queremos, mas não especificamos os detalhes da execução – esses detalhes são deixados para o planejador de buscas da base de dados. Especificamos as <em>joins</em> que queremos e as condições e o planejador do banco de dados cuida do resto.</p><p>Na realidade, porém, o banco de dados não está juntando três tabelas ao mesmo tempo. Ao invés disso, ele provavelmente unirá as duas primeiras tabelas em um resultado intermediário e, então, usará esse resultado para unir a terceira tabela.</p><p>(<strong>Observação</strong>: essa é uma explicação bastante simplificada.)</p><p>Então, como estamos trabalhando em buscas com várias <em>joins</em>, podemos simplesmente pensar que são <em>joins</em> entre duas tabelas – mesmo que uma delas seja bastante grande.</p><h2 id="joins-com-condi-es-extras"><strong><strong><em>Joins </em></strong>com condições extras</strong></h2><p>O último tópico de que trataremos são as <em>joins</em> com condições extras.</p><p>Da mesma forma que ocorre com a cláusula <code>WHERE</code>, podemos adicionar quantas condicionais quisermos as condições da <em>join</em>.</p><p>Por exemplo, se quisermos encontrar os filmes cujos diretores não tenham o nome "John Smith", podemos adicionar uma condição extra à nossa <em>join</em> com um <code>AND</code>:</p><pre><code class="language-sql">SELECT *
FROM movies
INNER JOIN directors
  ON directors.id = movies.director_id
  AND directors.name &lt;&gt; 'John Smith';</code></pre><p>Podemos usar qualquer operador onde colocaríamos uma cláusula <code>WHERE</code> nessa condicional da <em>join</em>.</p><p>Podemos também ter o mesmo resultado dessa busca se colocarmos a condicional com a cláusula <code>WHERE</code> :</p><pre><code class="language-sql">SELECT *
FROM movies
INNER JOIN directors
  ON directors.id = movies.director_id
WHERE directors.name &lt;&gt; 'John Smith';</code></pre><p>Existem algumas diferenças sutis acontecendo por trás dos panos aqui, mas, para o propósito deste artigo, o resultado é o mesmo.</p><p>(Se você não é familiarizado com todas as outras formas de filtrar uma busca em SQL, dê uma olhada <a href="https://www.freecodecamp.org/news/sql-operators-tutorial/">neste artigo comentado anteriormente</a> - em inglês.)</p><h2 id="a-realidade-sobre-escrever-queries-e-joins"><strong>A realidade sobre escrever <em>queries</em> e <em>joins</em></strong></h2><p>Na realidade, eu apenas uso <em>joins</em> de três formas diferentes:</p><h4 id="inner-join-1"><strong><strong><code>INNER JOIN</code></strong></strong></h4><p>O primeiro caso de uso é o de registros onde o relacionamento entre duas tabelas <strong>existe</strong>. Isso é coberto totalmente pelo <code>INNER JOIN</code>.</p><p>Essas são situações como encontrar "<em>filmes que tenham diretores</em>" ou "<em>usuários que tenham postagens</em>".</p><h4 id="left-join"><strong><strong><code>LEFT JOIN</code></strong></strong></h4><p>O segundo caso de uso é o de registros de uma tabela – e se o relacionamento existir– e registros de uma segunda tabela. Esse caso é coberto pelo <code>LEFT JOIN</code>.</p><p>Esse caso é o de situações como "<em>filmes com diretores caso existam</em>" ou "<em>usuários com postagens caso haja alguma</em>"</p><h4 id="exclus-o-do-left-join"><strong>Exclusão do &nbsp;<strong><code>LEFT JOIN</code></strong></strong></h4><p>O terceiro caso de uso mais comum é o nosso segundo caso com uma <code>LEFT JOIN</code>: encontrar os registros de uma tabela que <strong>não </strong>tenham relação com a segunda tabela.</p><p>São situações como "filmes sem diretores" ou "usuários sem postagens".</p><h3 id="dois-tipos-de-joins-muito-teis-"><strong>Dois tipos de <em>joins</em> muito úteis.</strong></h3><p>Eu não acho que já tenha usado uma <code>FULL OUTER JOIN</code> ou uma &nbsp;<code>RIGHT JOIN</code> em uma aplicação em produção. Esses tipos de caso de uso não costumam aparecer frequentemente ou a <em>query</em> pode ser escrita de forma mais simples (no caso do <code>RIGHT JOIN</code>).</p><p>Ocasionalmente, eu já usei o <code>CROSS JOIN</code> para algumas coisas como espalhar registros em um intervalo de datas (como vimos no começo do artigo), mas esse cenário também não costuma aparecer com frequência.</p><p>Então, boas notícias! Existem realmente dois tipos de <em>joins</em> que você precisa saber para 99,9% dos casos que aparecerão: <code>INNER JOIN</code> e <code>LEFT JOIN</code>!</p><p>Se você gostou deste artigo, pode <a href="https://twitter.com/johnmosesman">seguir o autor no Twitter</a>, onde ele fala sobre assuntos relacionados a bancos de dados e a desenvolvimento.</p><p>Obrigado pela leitura!</p><p>Um último conselho para o final: a maioria dos bancos de dados permitirá que você escreva apenas <code>JOIN</code> no lugar do <code>INNER JOIN</code> – isso poupará um pouco de digitação. :)</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Os melhores exemplos de SQL ]]>
                </title>
                <description>
                    <![CDATA[ SQL é a abreviação de Structured Query Language, ou Linguagem de Consulta Estruturada. Ela é usada para todos os tipos de bancos de dados relacionais. Exemplo de sintaxe básica de SQL Este guia fornece uma descrição básica e geral da sintaxe das instruções em SQL. SQL é um padrão internacional ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/os-melhores-exemplos-de-sql/</link>
                <guid isPermaLink="false">6239f3fd6a6ca90519acf0e3</guid>
                
                    <category>
                        <![CDATA[ SQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Tue, 22 Mar 2022 19:25:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/03/sql-image.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/sql-example/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Best SQL Examples</a>
      </p><p>SQL é a abreviação de Structured Query Language, ou Linguagem de Consulta Estruturada. Ela é usada para todos os tipos de bancos de dados relacionais.</p><h2 id="exemplo-de-sintaxe-b-sica-de-sql"><strong>Exemplo de sintaxe básica de SQL</strong></h2><p>Este guia fornece uma descrição básica e geral da sintaxe das instruções em SQL.</p><p>SQL é um padrão internacional (ISO), mas você encontrará muitas diferenças entre as implementações. Este guia usa o MySQL como exemplo. Se você usar um dos vários outros Sistemas de Gerenciamento de Bancos de Dados (conhecidos pela sigla DBMS, em inglês), precisará conferir o manual do DBMS em questão, se necessário.</p><h3 id="do-que-trataremos"><strong>Do que trataremos</strong></h3><ul><li>Uso (define que banco de dados a instrução utilizará)</li><li>Instruções com SELECT e FROM</li><li>Instrução WHERE (AND/OR, IN, BETWEEN e LIKE)</li><li>ORDER BY (ASC, DESC)</li><li>GROUP BY e HAVING</li></ul><h3 id="como-usar"><strong>Como usar</strong></h3><p>O comando abaixo é usado para selecionar o banco de dados contendo as tabelas para suas instruções em SQL:</p><pre><code>use fcc_sql_guides_database; -- seleciona o banco de dados da amostra, chamado fcc_sql_guides</code></pre><h3 id="instru-es-select-e-from"><strong>Instruções SELECT e FROM</strong></h3><p>A parte SELECT normalmente é utilizada para determinar quais colunas dos dados você quer exibir nos resultados. Também existem opções que você pode usar para mostrar dados que não são de uma coluna da tabela.</p><p>Este exemplo mostra duas colunas selecionadas da tabela "student" e duas colunas calculadas. A primeira das colunas calculadas é um número sem significado. A outra é a data do sistema.</p><pre><code>	select studentID, FullName, 3+2 as five, now() as currentDate
    from student;
</code></pre><h2 id="instru-o-where-and-or-in-between-e-like-">Instrução WHERE (AND/OR, IN, BETWEEN e LIKE)</h2><p>A instrução WHERE é usada para limitar o número de linhas retornado.</p><pre><code>    select studentID, FullName, sat_score, recordUpdated
    from student
    where (
		studentID between 1 and 5
		or studentID = 8
        or FullName like '%Maximo%'
		);
</code></pre><p>Neste caso, usar todas as propriedades torna a instrução WHERE bastante ridícula.</p><p>Compare o resultado com a instrução SQL acima para seguir a lógica.</p><p>Serão apresentadas linhas que:</p><ul><li>Têm studentIDs entre 1 e 5 (incluindo os extremos)</li><li>ou studentID = 8</li><li>ou ainda que tenha "Maximo" no nome</li></ul><p>O exemplo a seguir é semelhante, mas especifica ainda mais excluindo os alunos com pontuações de SAT que estiverem entre 1000 e 1400. Esses não serão apresentados:</p><pre><code>    select studentID, FullName, sat_score, recordUpdated
    from student
    where (
		studentID between 1 and 5
		or studentID = 8
        or FullName like '%Maximo%'
		)
		and sat_score NOT in (1000, 1400);
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/03/syntax02.jpg" class="kg-image" alt="syntax02" width="414" height="147" loading="lazy"></figure><h3 id="order-by-asc-desc-"><strong>ORDER BY (ASC, DESC)</strong></h3><p>ORDER BY nos oferece uma maneira de ordenar o conjunto de resultados por um ou mais itens da seção SELECT. Abaixo veremos a mesma lista que vemos acima, mas ordenada pelo Full Name (nome completo) dos alunos. A ordem padrão é a ascendente (ASC), mas para ordenar em ordem inversa (descendente), é possível usar DESC.</p><pre><code>SELECT studentID, FullName, sat_score
FROM student
ORDER BY FullName DESC;
</code></pre><pre><code>+-----------+------------------------+-----------+
| studentID | FullName               | sat_score |
+-----------+------------------------+-----------+
|         2 | Teri Gutierrez         |       800 |
|         3 | Spencer Pautier        |      1000 |
|         6 | Sophie Freeman         |      1200 |
|         9 | Raymond F. Boyce       |      2400 |
|         1 | Monique Davis          |       400 |
|         4 | Louis Ramsey           |      1200 |
|         7 | Edgar Frank "Ted" Codd |      2400 |
|         8 | Donald D. Chamberlin   |      2400 |
|         5 | Alvin Greene           |      1200 |
+-----------+------------------------+-----------+
9 rows in set (0.00 sec)
</code></pre><p><em>Abaixo vemos a lista NÃO <em>ORDE</em>NADA<em>, </em>atual e completa dos alunos, para comparar à lista acima<em>.</em></em></p><pre><code>SELECT studentID, FullName, sat_score, rcd_updated FROM student;
</code></pre><pre><code>+-----------+------------------------+-----------+---------------------+
| studentID | FullName               | sat_score | rcd_updated         |
+-----------+------------------------+-----------+---------------------+
|         1 | Monique Davis          |       400 | 2017-08-16 15:34:50 |
|         2 | Teri Gutierrez         |       800 | 2017-08-16 15:34:50 |
|         3 | Spencer Pautier        |      1000 | 2017-08-16 15:34:50 |
|         4 | Louis Ramsey           |      1200 | 2017-08-16 15:34:50 |
|         5 | Alvin Greene           |      1200 | 2017-08-16 15:34:50 |
|         6 | Sophie Freeman         |      1200 | 2017-08-16 15:34:50 |
|         7 | Edgar Frank "Ted" Codd |      2400 | 2017-08-16 15:35:33 |
|         8 | Donald D. Chamberlin   |      2400 | 2017-08-16 15:35:33 |
|         9 | Raymond F. Boyce       |      2400 | 2017-08-16 15:35:33 |
+-----------+------------------------+-----------+---------------------+
9 rows in set (0.00 sec)
</code></pre><p>Podemos limitar ainda mais. Nesse caso, com studentIDs entre 1 e 5 OU studentID de 8 OU nome completo que contenha "Maximo" E pontuação do SAT que não seja de 1000 ou 1400</p><pre><code>    select studentID, FullName, sat_score
    from student
    where (studentID between 1 and 5 -- incluindo os extremos
		or studentID = 8
        or FullName like '%Maximo%')
		and sat_score NOT in (1000, 1400)
	order by FullName DESC;
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/03/syntax03.jpg" class="kg-image" alt="syntax03" width="302" height="144" loading="lazy"></figure><h3 id="group-by-e-having"><strong>GROUP BY e HAVING</strong></h3><p>GROUP BY nos dá uma maneira de combinar linhas e dados agregados. A instrução HAVING é como a instrução WHERE acima, com a exceção de que ela atua nos dados agrupados.</p><p>Os dados abaixo pertencem aos dados de contribuições de campanha que usamos em alguns desses guias.</p><p>A instrução em SQL que segue responde a pergunta: "quais candidatos receberam o menor número de contribuições (não em termos de dinheiro, mas de contagem (*)) em 2016, mas somente aqueles que tiveram mais de 80 contribuições?"</p><p>Ordenar esse conjunto de dados em uma ordem descendente (DESC) coloca os candidatos com o maior número de contribuições na parte de cima da lista.</p><pre><code>    select Candidate, Election_year, sum(Total_$), count(*)
    from combined_party_data
    where Election_year = 2016
    group by Candidate, Election_year
    having count(*) &gt; 80
    order by count(*) DESC;
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/03/syntax04.jpg" class="kg-image" alt="syntax04" width="573" height="176" loading="lazy"></figure><h2 id="o-operador-between-em-sql">O operador BETWEEN em SQL</h2><p>O operador BETWEEN é útil, por causa do otimizador de consultas do SQL (ou <em>SQL Query Optimizer</em>). Embora BETWEEN seja, funcionalmente, o mesmo que: x &lt;= elemento &lt;= y, o otimizador de consultas do SQL reconhecerá esse comando mais rápido e terá um código otimizado para executá-lo.</p><p>Esse operador é usado em uma instrução WHERE ou em uma instrução GROUP BY/HAVING.</p><p>As linhas selecionadas são as que têm um valor maior que o mínimo e menor que o máximo.</p><p>É importante lembrar de que os valores inseridos no comando são <strong><strong><strong><strong>exclu</strong></strong></strong>ídos</strong> do resultado. Obtemos apenas os valores entre eles.</p><p>Essa é a sintaxe para usar a função em uma instrução WHERE:</p><pre><code>select field1, testField
from table1
where testField between min and max
</code></pre><p>Aqui temos um exemplo usando a tabela student e a instrução WHERE:</p><pre><code>-- sem a instrução WHERE
select studentID, FullName, studentID
from student;
    
-- com a instrução WHERE e com BETWEEN
select studentID, FullName, studentID
from student
where studentID between 2 and 7;
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/03/between01.jpg" class="kg-image" alt="between01" width="567" height="206" loading="lazy"></figure><p>Aqui temos um exemplo de uso na tabela de fundos de campanha com a instrução HAVING. Ele retornará linhas onde a soma das doações para um candidato estavam ente US$3 milhões e US$18 milhões com base na instrução HAVING e na parte GROUP BY da instrução. Veja mais sobre agregação <a href="https://www.freecodecamp.org/portuguese/news/tutorial-de-group-do-sql-count-sum-average-e-instrucao-having-explicadas/">no guia específico</a>.</p><pre><code>select Candidate, Office_Sought, Election_Year, format(sum(Total_$),2)
from combined_party_data
where Election_Year = 2016
group by Candidate, Office_Sought, Election_Year
having sum(Total_$) between 3000000 and 18000000
order by sum(Total_$) desc; 
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/03/between02.jpg" class="kg-image" alt="between02" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/03/between02.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/03/between02.jpg 680w" width="680" height="147" loading="lazy"></figure><p>Uma tabela é um grupo de dados armazenado em um banco de dados.</p><p>Para criar uma tabela em um banco de dados, use a instrução <code>CREATE TABLE</code>. Você dá um nome à tabela e uma lista de colunas com seus tipos de dados.</p><pre><code>CREATE TABLE TABLENAME(Attribute1 Datatype, Attribute2 Datatype,........);
</code></pre><p>Aqui temos um exemplo de criação da tabela Person:</p><pre><code>CREATE TABLE Person(
  Id int not null,
  Name varchar not null,
  DateOfBirth date not null,
  Gender bit not null,
  PRIMARY KEY( Id )
);
</code></pre><p>No exemplo acima, cada Person (pessoa) tem um Name (nome), uma Date of Birth (data de nascimento) e um Gender (gênero). A coluna Id é a chave que identifica uma pessoa na tabela. Você usa a palavra-chave <code>PRIMARY KEY</code> para configurar uma ou mais colunas como uma chave primária.</p><p>Uma coluna pode ser <code>not null</code> ou <code>null</code>, indicando se ela é ou não obrigatória.</p><p>Consultas do tipo INSERT são uma maneira de inserir dados em uma tabela. Digamos que tenhamos criado uma tabela usando o seguinte:</p><p><code>CREATE TABLE example_table ( name varchar(255), age int)</code></p><p><strong><strong>example_table</strong></strong></p><pre><code>Name|Age
--- | --- </code></pre><p>Agora, para adicionar dados a essa tabela, usaremos <strong><strong>INSERT</strong></strong>, dessa forma:</p><p><code>INSERT INTO example_table (column1,column2) VALUES ("Andrew",23)</code></p><p><strong><strong>example_table</strong></strong></p><pre><code>Name|Age
--- | --- 
Andrew|23</code></pre><p>Até mesmo a instrução abaixo funcionará. Sempre é bom, no entanto, especificar quais dados estão sendo inseridos em quais colunas.</p><p><code>INSERT INTO table_name VALUES ("John", 28)</code></p><p><strong><strong>example_table</strong></strong></p><pre><code>Name|Age
--- | --- 
Andrew|23
John|28</code></pre><p>AND é usado em uma instrução WHERE ou em uma instrução GROUP BY/HAVING para limitar as linhas retornadas pela instrução executada. Use AND quando é necessário atender a mais de uma condição.</p><p>Usamos a tabela student para apresentar exemplos.</p><p>Aqui temos a tabela student sem usar uma instrução WHERE:</p><pre><code>select * from student;
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/03/and_operator01.jpg" class="kg-image" alt="and_operator01" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/03/and_operator01.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/03/and_operator01.jpg 760w" sizes="(min-width: 720px) 720px" width="760" height="247" loading="lazy"></figure><p>Agora, a instrução WHERE é adicionada para que sejam exibidos apenas os alunos de programação:</p><pre><code>select * from student 
where programOfStudy = 'Programming';
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/03/and_operator02.jpg" class="kg-image" alt="and_operator02" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/03/and_operator02.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/03/and_operator02.jpg 790w" sizes="(min-width: 720px) 720px" width="790" height="179" loading="lazy"></figure><p>Em seguida, a instrução WHERE é atualizada com AND para mostrar resultados dos alunos de programação que também tenham uma pontuação no SAT maior que 800:</p><pre><code>select * from student 
where programOfStudy = 'Programming' 
and sat_score &gt; 800;
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/03/and_operator03.jpg" class="kg-image" alt="and_operator03" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/03/and_operator03.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/03/and_operator03.jpg 790w" sizes="(min-width: 720px) 720px" width="790" height="179" loading="lazy"></figure><p>Abaixo temos um exemplo mais complexo da tabela de contribuições de campanha. O exemplo tem uma instrução GROUP BY com uma instrução HAVING usando um AND para restringir o número de registros retornados a candidatos de 2016 com contribuições entre US$3 milhões e US$18 milhões no total.</p><pre><code>select Candidate, Office_Sought, Election_Year, FORMAT(sum(Total_$),2) from combined_party_data
where Office_Sought = 'PRESIDENT / VICE PRESIDENT'
group by Candidate, Office_Sought, Election_Year
 having Election_Year = 2016 and sum(Total_$) between 3000000 and 18000000
order by sum(Total_$) desc;
</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/03/and_operator06.jpg" class="kg-image" alt="and_operator06" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/03/and_operator06.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/03/and_operator06.jpg 710w" width="710" height="175" loading="lazy"></figure><h2 id="perguntas-de-entrevistas-comuns-sobre-sql"><strong>Perguntas de entrevistas comuns sobre SQL</strong></h2><h3 id="o-que-um-inner-join-em-sql"><strong>O que é um inner join em SQL?</strong></h3><p>Esse é o tipo padrão de join se nenhum join for especificado. Ele retorna todas as linhas nas quais haja ao menos uma correspondência nas duas tabelas.</p><pre><code>SELECT * FROM A x JOIN B y ON y.aId = x.Id
</code></pre><h3 id="o-que-um-left-join-em-sql"><strong>O que é um left join em SQL?</strong></h3><p>Um left join retorna todas as linhas da tabela da esquerda e as linhas correspondentes da tabela da direita. As linhas da tabela da esquerda serão retornadas mesmo sem ter uma correspondência na tabela da direita. As linhas da tabela da esquerda sem correspondência na tabela da direita terão <code>null</code> nos valores da tabela da direita.</p><pre><code>SELECT * FROM A x LEFT JOIN B y ON y.aId = x.Id
</code></pre><h3 id="o-que-um-right-join-em-sql"><strong>O que é um right join em SQL?</strong></h3><p>Um right join retorna todas as linhas da tabela da direita e as linhas correspondentes da tabela da esquerda. Ao contrário do left join, ele retornará todas as linhas da tabela da direita mesmo que não haja correspondência na tabela da esquerda. As linhas da tabela da direita que não têm correspondência na tabela da esquerda terão valores <code>null</code> para as colunas da tabela da esquerda.</p><pre><code>SELECT * FROM A x RIGHT JOIN B y ON y.aId = x.Id
</code></pre><h3 id="o-que-um-full-join-em-sql"><strong>O que é um full join em SQL?</strong></h3><p>Um full join retorna todas as linhas para as quais haja uma correspondência em qualquer uma das tabelas. Assim, se houver linhas na tabela da esquerda sem correspondência na tabela da direita, elas serão incluídas. Se houver linhas na tabela da direita que não têm correspondências na tabela da esquerda, elas também serão incluídas.</p><pre><code>SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
FULL OUTER JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
ORDER BY Customers.CustomerName
</code></pre><h3 id="qual-o-resultado-do-comando-seguinte"><strong>Qual é o resultado do comando seguinte?</strong></h3><pre><code>  DROP VIEW view_name
</code></pre><p>Aqui, teremos um erro, pois não podemos realizar uma operação DML em uma view.</p><h3 id="podemos-fazer-um-rollback-ap-s-usar-um-comando-alter"><strong>Podemos fazer um rollback após usar um comando ALTER?</strong></h3><p>Não, pois ALTER é um comando DDL e servidores da Oracle realizam um COMMIT automático quando as instruções DDL são executadas.</p><h3 id="qual-a-nica-restri-o-que-imp-e-as-regras-em-n-vel-de-coluna"><strong>Qual é a única restrição que impõe as regras em nível de coluna?</strong></h3><p>NOT NULL é a única restrição que funciona em nível de coluna.</p><h3 id="o-que-s-o-as-pseudocolunas-em-sql-pode-fornecer-alguns-exemplos"><strong>O que são as pseudocolunas em SQL? Pode fornecer alguns exemplos?</strong></h3><p>Uma pseudocoluna é uma função que retorna um valor gerado pelo sistema. O motivo pelo qual isso é conhecido assim é porque uma pseudocoluna é um valor atribuído pela Oracle usado no mesmo contexto que uma coluna de banco de dados da Oracle, mas não armazenado em disco.</p><pre><code>    ROWNUM, ROWID, USER, CURRVAL, NEXTVAL etc.
</code></pre><h2 id="crie-a-fun-o-role_tables_and_views">Crie a função role_tables_and_views</h2><pre><code>    CREATE ROLE role_tables_and_views
</code></pre><p>Dê à função da pergunta anterior os privilégios para se conectar ao banco de dados e os privilégios de criar tabelas e views.</p><p>O privilégio para se conectar com o banco de dados é CREATE SESSION. O privilégio para criar tabelas é CREATE TABLE. O privilégio para criar views é CREATE VIEW.</p><pre><code>    GRANT Create session, create table, create view TO role_tables_and_views
</code></pre><p>Crie um usuário my723acct com a senha kmd26pt. Use os dados de usuário e as tablespaces de dados temporários fornecidas pelo PO8 e dê a esse usuário 10M de espaço de armazenamento em dados de usuários e 5M de espaço de armazenamento em temporary_data.</p><pre><code>    CREATE USER my723acct IDENTIFIED BY kmd26pt
    DEFAULT TABLESPACE user_data
    TEMPORARY TABLESPACE temporary_data
    QUOTA 10M on user_data QUOTA 5M on temporary_data
</code></pre><p>Dê à função da pergunta anterior aos usuários anny e rita</p><pre><code>    GRANT role_tables_and_views TO anny, rita
</code></pre><p>Escreva um comando que altere a senha do usuário rita de abcd para dfgh</p><pre><code>    ALTER USER rita IDENTIFIED BY dfgh
</code></pre><p>Os usuários rita e anny não têm privilégios de SELECT na tabela INVENTORY, criada por SCOTT. Escreva um comando para permitir que SCOTT dê aos usuários privilégios de SELECT para essas tabelas.</p><pre><code>    GRANT select ON inventory TO rita, anny
</code></pre><p>O usuário rita foi transferido e agora está indo para outra empresa. Como os objetos que ela criou já não estão sendo usados, escreva um comando para remover esse usuário e todos os seus objetos.</p><p>Aqui, a opção CASCADE é necessária para remover todos os objetos do usuário no banco de dados.</p><pre><code>   DROP USER rita CASCADE
</code></pre><p>O usuário rita foi transferido e já não precisa do privilégio que foi dado a ela pela função <em>role_tables_and_views</em>. Escreva um comando para removê-la de seus privilégios anteriormente recebidos, exceto pelo fato de ela ainda poder se conectar ao banco de dados.</p><pre><code>    REVOKE select ON scott.inventory FROM rita
    REVOKE create table, create view FROM rita
</code></pre><h2 id="escreva-uma-consulta-em-sql-para-encontrar-o-en-simo-maior-sal-rio-da-tabela">Escreva uma consulta em SQL para encontrar o enésimo maior salário da tabela</h2><pre><code>   SELECT TOP 1 Salary
   FROM (
      SELECT DISTINCT TOP N Salary
      FROM Employee
      ORDER BY Salary DESC
      )
    ORDER BY Salary ASC</code></pre><h2 id="instru-o-create-view-em-sql"><strong>Instrução CREATE VIEW em SQL</strong></h2><h3 id="o-que-uma-view"><strong>O que é uma view?</strong></h3><p>Uma view é um objeto de banco de dados que apresenta os dados existentes em uma ou mais tabelas. Views são usadas de modo semelhante às tabelas, mas elas não contêm dados. Elas simplesmente "apontam" para os dados que existem em outros lugares (como tabelas ou outras views, por exemplo).</p><h3 id="por-que-elas-s-o-t-o-legais"><strong>Por que elas são tão legais?</strong></h3><ul><li>Views São uma maneira de limitar os dados apresentados. Por exemplo, o departamento de recursos humanos filtrou informações para poder apresentar somente aquelas que não são confidenciais. As informações confidenciais, neste caso, poderiam ser números da previdência, gênero do funcionário, valor do salário, endereço residencial etc.</li><li>Dados complexos em mais de uma tabela podem ser combinados em uma única "view". Isso pode facilitar a vida para analistas de empresas e programadores.</li></ul><h3 id="dicas-de-seguran-a-importantes"><strong>Dicas de segurança importantes</strong></h3><ul><li>Views são gerenciadas pelo sistema. Quando os dados nas tabelas relacionadas são alterados, adicionados ou atualizados, a view é atualizada pelo sistema. Queremos usá-las apenas quando necessário para gerenciar o uso dos recursos do sistema.</li><li>Em MySQL, alterações ao design da tabela (ou seja, colunas novas ou excluídas) realizados APÓS a criação de uma view não são atualizados na própria view. A view teria de ser atualizada ou recriada.</li><li>Views são um dos quatro tipos de objeto de bancos de dados padrão. Os outros são tabelas, procedimentos armazenados e funções.</li><li>Views geralmente podem ser tratadas como tabelas, mas as atualizações são limitadas ou não disponíveis quando a view contém mais de uma tabela.</li><li>Há vários outros detalhes sobre as views que estão além do escopo desse guia introdutório. Aproveite seu tempo para ler o manual dos gerenciadores de bancos de dados e divirta-se com esse objeto do SQL poderoso.</li></ul><h3 id="sintaxe-da-instru-o-create-view-mysql-"><strong>Sintaxe da instrução Create View (MySQL)</strong></h3><pre><code>CREATE
    [OR REPLACE]
    [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
    [DEFINER = { user | CURRENT_USER }]
    [SQL SECURITY { DEFINER | INVOKER }]
    VIEW view_name [(column_list)]
    AS select_statement
	[WITH [CASCADED | LOCAL] CHECK OPTION]
</code></pre><p><em>Este guia tratará da parte da instrução que vemos abaixo<em>…</em></em></p><pre><code>CREATE
    VIEW view_name [(column_list)]
    AS select_statement
</code></pre><h3 id="exemplo-de-cria-o-de-views-a-partir-da-tabela-student"><strong>Exemplo de criação de views a partir da tabela student</strong></h3><p>Observações:</p><ul><li>O nome da view tem um "v" no início. Recomenda-se que o nome da view indique que ela é uma view de alguma maneira para facilitar a vida de programadores e administradores de bancos de dados. Sua TI deve ter as próprias regras para nomear objetos.</li><li>As colunas na view são limitadas pela instrução SELECT e pelas linhas de dados pela instrução WHERE.</li><li>O caractere "`" ao redor dos nomes das views são obrigatórios, por causa do "-" que aparece nos nomes. O MySQL relata um erro se não estiverem lá.</li></ul><pre><code>create view `programming-students-v` as
select FullName, programOfStudy 
from student 
where programOfStudy = 'Programming';

select * from `programming-students-v`;
</code></pre><h3 id="exemplo-de-uso-de-uma-view-para-combinar-dados-de-mais-de-uma-tabela"><strong>Exemplo de uso de uma view para combinar dados de mais de uma tabela</strong></h3><p>Uma tabela sobre a demografia dos alunos foi adicionada ao banco de dados para demonstrar esse uso. Essa view combinará as tabelas.</p><p>Observações:</p><ul><li>Para "unir" as tabelas por meio de um join, elas precisam ter campos em comum (geralmente, as chaves primárias) que identificam cada linha com exclusividade. Neste caso, falamos da studentID. Se quiser saber mais sobre o assunto, consulte o guia sobre <a href="https://guide.freecodecamp.org/sql/sql-joins/index.md" rel="nofollow noopener">joins em SQL</a> (em inglês).</li><li>Observe o "alias" dado a cada tabela ("s" para <em>student</em> - aluno - e "sc" para <em>student contact</em> - contato do aluno). É uma ferramenta que serve para encurtar os nomes das tabelas e facilitar a identificação de qual tabela está sendo usada. É mais fácil do que digitar longos nomes de tabela repetidamente. Neste exemplo, foi necessário porque o nome de coluna <em>studentID </em>é igual nas duas tabelas. O sistema apresentaria um "erro de nome ambíguo de coluna" se não especificássemos que tabela usar.</li></ul><p><em>Como ocorre com tudo o que está relacionado a <em>SQL</em>, há MUITO MAIS do que é oferecido nesse guia introdutório<em>. </em>Espero que este guia dê a você pelo menos o suficiente para começar<em>. </em>Consulte o manual para seu gerenciador de bancos de dados e divirta-se experimentando com opções diferentes por sua conta<em>.</em></em></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Comandos básicos em SQL - A lista de consultas e instruções de banco de dados que você deve conhecer ]]>
                </title>
                <description>
                    <![CDATA[ SQL significa Linguagem de Consulta Estruturada (Structured Query Language em inglês). Os comandos SQL são as instruções usadas para se comunicar com um banco de dados para executar tarefas, funções e consultas com dados. Os comandos do SQL podem ser usados ​​para pesquisar o banco de dados e realizar outras ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/comandos-basicos-em-sql-a-lista-de-consultas-e-instrucoes-de-banco-de-dados-que-voce-deve-conhecer/</link>
                <guid isPermaLink="false">6208eecccfef2204db7ee04f</guid>
                
                    <category>
                        <![CDATA[ SQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Fernando Mota Freitas ]]>
                </dc:creator>
                <pubDate>Sat, 19 Feb 2022 22:36:25 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/artigo3-sql-basics-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/basic-sql-commands/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Basic SQL Commands - The List of Database Queries and Statements You Should Know</a>
      </p><p>SQL significa Linguagem de Consulta Estruturada (Structured Query Language em inglês). Os comandos SQL são as instruções usadas para se comunicar com um banco de dados para executar tarefas, funções e consultas com dados.</p><p>Os comandos do SQL podem ser usados ​​para pesquisar o banco de dados e realizar outras funções, como criar tabelas, adicionar dados a tabelas, modificar dados e descartar tabelas.</p><p>Aqui está uma lista de comandos SQL básicos (às vezes chamados de instruções) que você deve saber se vai trabalhar com SQL.</p><h3 id="select-e-from"><strong>SELECT e FROM</strong></h3><p>A parte <code>SELECT</code> (selecionar, em inglês) de uma consulta determina quais colunas dos dados serão exibidas nos resultados. Também há opções que você pode aplicar para mostrar dados que não são uma coluna da tabela.</p><p>O exemplo abaixo mostra três colunas selecionadas na tabela "student" (aluno, em inglês), para isso usamos o comando <code>FROM</code> (vindo de, em inglês) e uma coluna calculada. O banco de dados armazena o studentID, FirstName e LastName do aluno (id do aluno, nome e sobrenome em inglês, respectivamente). Podemos combinar as colunas FirstName e LastName para criar a coluna calculada FullName. (nome completo, em inglês)‌. </p><pre><code class="language-sql">SELECT studentID, FirstName, LastName, FirstName + ' ' + LastName AS FullName
FROM student;</code></pre><pre><code class="language-text">+-----------+-------------------+------------+------------------------+
| studentID | FirstName         | LastName   | FullName               |
+-----------+-------------------+------------+------------------------+
|         1 | Monique           | Davis      | Monique Davis          |
|         2 | Teri              | Gutierrez  | Teri Gutierrez         |
|         3 | Spencer           | Pautier    | Spencer Pautier        |
|         4 | Louis             | Ramsey     | Louis Ramsey           |
|         5 | Alvin             | Greene     | Alvin Greene           |
|         6 | Sophie            | Freeman    | Sophie Freeman         |
|         7 | Edgar Frank "Ted" | Codd       | Edgar Frank "Ted" Codd |
|         8 | Donald D.         | Chamberlin | Donald D. Chamberlin   |
|         9 | Raymond F.        | Boyce      | Raymond F. Boyce       |
+-----------+-------------------+------------+------------------------+
9 rows in set (0.00 sec)</code></pre><h3 id="create-table"><strong><strong><strong>CREATE TABLE</strong></strong></strong></h3><p><code>CREATE TABLE</code> (criar tabela, em inglês) faz exatamente o que parece: cria uma tabela no banco de dados. Você pode especificar o nome da tabela e as colunas que devem estar nela.</p><pre><code class="language-sql">CREATE TABLE nome_da_tabela (
    coluna_1 tipo_de_dados,
    coluna_2 tipo_de_dados,
    coluna_3 tipo_de_dados
);</code></pre><h3 id="alter-table">ALTER TABLE</h3><p><a href="https://translate.google.com/website?sl=en&amp;tl=pt&amp;hl=pt-BR&amp;client=webapp&amp;u=https://dev.mysql.com/doc/refman/5.7/en/alter-table.html"><code>ALTER TABLE</code></a> (alterar tabela, em inglês) altera a estrutura de uma tabela. Aqui está demonstrado como você adicionaria uma coluna a um banco de dados:</p><pre><code class="language-sql">ALTER TABLE nome_da_tabela
ADD coluna tipo_de_dados;</code></pre><h3 id="check">CHECK</h3><p>A instrução <code>CHECK</code> (verificar, em inglês) é usada para limitar o intervalo de valores que pode ser colocado em uma coluna.</p><p>Se você definir uma instrução <code>CHECK</code> em uma única coluna, ela permitirá apenas determinados valores para essa coluna. Se você definir uma instrução <code>CHECK</code> em uma tabela, ela poderá limitar os valores em determinadas colunas com base nos valores de outras colunas dessa linha.</p><p>O SQL a seguir cria uma instrução <code>CHECK</code> na coluna "Age" (idade, em inglês) quando a tabela "Persons" (pessoas, em inglês) é criada. <code>CHECK</code> garante que você não tenha pessoas com menos de 18 anos.‌</p><pre><code class="language-sql">CREATE TABLE Persons (
    ID int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Age int,
    CHECK (Age&gt;=18)
);</code></pre><p>Para permitir a nomeação de uma instrução <code>CHECK</code> e para definir uma instrução <code>CHECK</code> em várias colunas, use a seguinte sintaxe no SQL:</p><pre><code class="language-sql">CREATE TABLE Persons (
    ID int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Age int,
    City varchar(255),
    CONSTRAINT CHK_Person CHECK (Age&gt;=18 AND City='Sandnes')
);</code></pre><h2 id="-where">‌WHERE</h2><p><strong><strong><strong>(</strong></strong><code>AND</code> ,<code>OR</code><strong><strong> , <code>IN</code>, <code>BETWEEN</code></strong></strong> </strong>e<strong><strong><strong> <code>LIKE</code>)</strong></strong></strong></p><p>A instrução <code>WHERE</code> (onde, em inglês) é usada para limitar o número de linhas retornadas.</p><p>Como exemplo, primeiro mostraremos uma instrução <code>SELECT</code> e resultados <em>sem</em> declaração <code>WHERE</code>. Em seguida, adicionaremos uma instrução <code>WHERE</code> que usa todos os cinco qualificadores acima.‌ &nbsp; </p><pre><code class="language-sql">SELECT studentID, FullName, sat_score, rcd_updated FROM student;</code></pre><pre><code class="language-text">+-----------+------------------------+-----------+---------------------+
| studentID | FullName               | sat_score | rcd_updated         |
+-----------+------------------------+-----------+---------------------+
|         1 | Monique Davis          |       400 | 2017-08-16 15:34:50 |
|         2 | Teri Gutierrez         |       800 | 2017-08-16 15:34:50 |
|         3 | Spencer Pautier        |      1000 | 2017-08-16 15:34:50 |
|         4 | Louis Ramsey           |      1200 | 2017-08-16 15:34:50 |
|         5 | Alvin Greene           |      1200 | 2017-08-16 15:34:50 |
|         6 | Sophie Freeman         |      1200 | 2017-08-16 15:34:50 |
|         7 | Edgar Frank "Ted" Codd |      2400 | 2017-08-16 15:35:33 |
|         8 | Donald D. Chamberlin   |      2400 | 2017-08-16 15:35:33 |
|         9 | Raymond F. Boyce       |      2400 | 2017-08-16 15:35:33 |
+-----------+------------------------+-----------+---------------------+
9 rows in set (0.00 sec)</code></pre><p>Agora, repetiremos a consulta <code>SELECT</code>, mas limitaremos as linhas retornadas usando uma instrução <code>WHERE</code>.</p><pre><code class="language-sql">STUDENT studentID, FullName, sat_score, recordUpdated
FROM student
WHERE (studentID BETWEEN 1 AND 5 OR studentID = 8)
        AND
        sat_score NOT IN (1000, 1400);</code></pre><pre><code class="language-text">+-----------+----------------------+-----------+---------------------+
| studentID | FullName             | sat_score | rcd_updated         |
+-----------+----------------------+-----------+---------------------+
|         1 | Monique Davis        |       400 | 2017-08-16 15:34:50 |
|         2 | Teri Gutierrez       |       800 | 2017-08-16 15:34:50 |
|         4 | Louis Ramsey         |      1200 | 2017-08-16 15:34:50 |
|         5 | Alvin Greene         |      1200 | 2017-08-16 15:34:50 |
|         8 | Donald D. Chamberlin |      2400 | 2017-08-16 15:35:33 |
+-----------+----------------------+-----------+---------------------+
5 rows in set (0.00 sec)</code></pre><h2 id="update">UPDATE</h2><p>Para atualizar um registro em uma tabela, você usa a instrução <code>UPDATE</code> (atualizar, em inglês).</p><p>Use a instrução <code>WHERE</code> para especificar quais registros você deseja atualizar. É possível atualizar uma ou mais colunas por vez. A sintaxe é:‌ </p><pre><code class="language-sql">UPDATE nome_da_tabela
SET coluna1 = valor1, 
    coluna2 = valor2, ...
WHERE condição;</code></pre><p>Aqui está um exemplo atualizando Name (nome, em inglês) do registro com Id 4:‌ &nbsp; </p><pre><code class="language-sql">UPDATE Person
SET Name = "Elton John"
WHERE Id = 4;</code></pre><p>Você também pode atualizar colunas em uma tabela usando valores de outras tabelas. Use a instrução <code>JOIN</code> (unir, em inglês) para obter dados de várias tabelas. A sintaxe é:</p><pre><code class="language-sql">UPDATE nome_da_tabela1
SET nome_da_tabela1.coluna1 = nome_da_tabela2.colunaA
    nome_da_tabela1.coluna2 = nome_da_tabela2.colunaB
FROM nome_da_tabela1
JOIN nome_da_tabela2 ON nome_da_tabela1.ChaveEstrangeira = nome_da_tabela2.Chave</code></pre><p>Aqui está um exemplo de atualização de Manager (gerenciador, em inglês) de todos os registros:‌ &nbsp; &nbsp; &nbsp;</p><pre><code class="language-sql">UPDATE Person
SET Person.Manager = Department.Manager
FROM Person
JOIN Department ON Person.DepartmentID = Department.ID</code></pre><h2 id="group-by">GROUP BY</h2><p><code>GROUP BY</code> (agrupar por, em inglês) permite combinar linhas e agregar dados.</p><p>Aqui está a sintaxe de <code>GROUP BY</code>:‌ &nbsp; &nbsp;</p><pre><code class="language-sql">SELECT nome_da_coluna, COUNT(*)
FROM nome_da_tabela
GROUP BY nome_da_coluna;</code></pre><h2 id="having">HAVING</h2><p><code>HAVING</code> (contendo, em inglês) permite filtrar os dados agregados pela instrução <code>GROUP BY</code> para que o usuário obtenha um conjunto limitado de registros para visualização.</p><p>Aqui está a sintaxe de <code>HAVING</code>:‌ &nbsp;</p><pre><code class="language-sql">SELECT nome_da_coluna, COUNT(*)
FROM nome_da_tabela
GROUP BY nome_da_coluna
HAVING COUNT(*) &gt; valor;</code></pre><h2 id="avg-">AVG()</h2><p>"Average" (média, em inglês) é usado para calcular a média de uma coluna numérica do conjunto de linhas retornado por uma instrução SQL.</p><p>Aqui está a sintaxe para usar a função:‌ </p><pre><code class="language-sql">SELECT campoAgrupamento, AVG(num_campo)
FROM tabela1
GROUP BY campoAgrupamento</code></pre><p>Aqui está um exemplo usando a tabela de alunos:‌ &nbsp;</p><pre><code class="language-sql">SELECT studentID, FullName, AVG(sat_score) 
FROM student 
GROUP BY studentID, FullName;</code></pre><h2 id="as">AS</h2><p><code>AS</code> (como, em inglês - similar a <em>like</em>, que vemos posteriormente) permite renomear uma coluna ou tabela usando um alias.‌ &nbsp;</p><pre><code class="language-sql">SELECT user_only_num1 AS AgeOfServer, (user_only_num1 - warranty_period) AS NonWarrantyPeriod FROM server_table</code></pre><p>Isso resulta na saída abaixo.‌</p><pre><code class="language-text">+-------------+------------------------+
| AgeOfServer | NonWarrantyPeriod      | 
+-------------+------------------------+
|         36  |                     24 |
|         24  |                     12 | 
|         61  |                     49 |
|         12  |                      0 | 
|          6  |                     -6 |
|          0  |                    -12 | 
|         36  |                     24 |
|         36  |                     24 | 
|         24  |                     12 | 
+-------------+------------------------+</code></pre><p> Você também pode usar AS para atribuir um nome a uma tabela para facilitar a referência em junções.‌ &nbsp; </p><pre><code class="language-sql">SELECT ord.product, ord.ord_number, ord.price, cust.cust_name, cust.cust_number FROM customer_table AS cust

JOIN order_table AS ord ON cust.cust_number = ord.cust_number</code></pre><p>Isso resulta na saída como abaixo.</p><pre><code class="language-text">+-------------+------------+-----------+-----------------+--------------+
| product     | ord_number | price     | cust_name       | cust_number  |
+-------------+------------+-----------+-----------------+--------------+
|     RAM     |   12345    |       124 | John Smith      |  20          |
|     CPU     |   12346    |       212 | Mia X           |  22          |
|     USB     |   12347    |        49 | Elise Beth      |  21          |
|     Cable   |   12348    |         0 | Paul Fort       |  19          |
|     Mouse   |   12349    |        66 | Nats Back       |  15          |
|     Laptop  |   12350    |       612 | Mel S           |  36          |
|     Keyboard|   12351    |        24 | George Z        |  95          |
|     Keyboard|   12352    |        24 | Ally B          |  55          |
|     Air     |   12353    |        12 | Maria Trust     |  11          |
+-------------+------------+-----------+-----------------+--------------+</code></pre><h2 id="order-by">ORDER BY</h2><p><code>ORDER BY</code> (ordenar por, em inglês) nos dá uma maneira de classificar o conjunto de resultados por um ou mais itens na seção <code>SELECT</code>. Aqui está um SQL classificando os alunos por FullName em ordem decrescente. A ordem de classificação padrão é crescente (<code>ASC</code>), mas, para classificar na ordem oposta (decrescente), você usa <code>DESC</code>.‌ &nbsp;</p><pre><code class="language-sql">SELECT studentID, FullName, sat_score
FROM student
ORDER BY FullName DESC;</code></pre><h2 id="count">COUNT</h2><p><code>COUNT</code> (contar, em inglês) contará o número de linhas e retornará essa contagem como uma coluna no conjunto de resultados.</p><p>Aqui estão alguns exemplos onde você usaria COUNT:</p><ul><li>Para contar todas as linhas em uma tabela (GROUP BY não é obrigatório)</li><li>Para contar os totais de subconjuntos de dados (requer um GROUP BY na instrução)</li></ul><p>Essa instrução SQL fornece uma contagem de todas as linhas. Observe que você pode dar um nome à coluna COUNT resultante usando "AS".‌ &nbsp; </p><pre><code class="language-sql">SELECT count(*) AS studentCount FROM student; </code></pre><h2 id="delete">DELETE</h2><p><code>DELETE</code> (excluir, em inglês) é usado para excluir um registro em uma tabela.</p><p>Tome cuidado. Você pode excluir todos os registros da tabela ou apenas alguns deles. Use a condição <code>WHERE</code> para especificar quais registros você deseja excluir. A sintaxe é:‌</p><pre><code class="language-sql">DELETE FROM table_name
WHERE condition;</code></pre><p>Aqui está um exemplo de exclusão do registro com Id 3 na tabela Person:‌</p><pre><code class="language-sql">DELETE FROM Person
WHERE Id = 3;</code></pre><h2 id="inner-join">INNER JOIN</h2><p><code>JOIN</code> (junção, em inglês), também chamado de <em>inner join</em> (junção interna, em inglês), seleciona registros que têm valores correspondentes em duas tabelas.‌ &nbsp;</p><pre><code class="language-sql">SELECT * FROM A x JOIN B y ON y.aId = x.Id</code></pre><h2 id="left-join">LEFT JOIN</h2><p>A <code>LEFT JOIN</code> (junção à esquerda, em inglês) retorna todas as linhas da tabela da esquerda e as linhas correspondentes da tabela da direita. As linhas na tabela da esquerda serão retornadas mesmo que não haja correspondência na tabela da direita. As linhas da tabela à esquerda sem correspondência na tabela à direita terão os valores da tabela à direita <code>null</code>.‌</p><pre><code class="language-sql">SELECT * FROM A x LEFT JOIN B y ON y.aId = x.Id</code></pre><h2 id="-right-join">‌RIGHT JOIN</h2><p>A <code>RIGHT JOIN</code> (junção à direita, em inglês) retorna todas as linhas da tabela da direita e as linhas correspondentes da tabela da esquerda. Ao contrário de uma junção à esquerda, isso retornará todas as linhas da tabela à direita, mesmo quando não houver correspondência na tabela à esquerda. As linhas na tabela à direita que não têm correspondência na tabela à esquerda terão valores <code>null</code> para as colunas da tabela à esquerda.‌ </p><pre><code class="language-sql">SELECT * FROM A x RIGHT JOIN B y ON y.aId = x.Id</code></pre><h2 id="full-outer-join">FULL OUTER JOIN</h2><p>A <code>FULL OUTER JOIN</code> (junção externa completa, em inglês) retorna todas as linhas para as quais haja uma correspondência em qualquer uma das tabelas. Portanto, se houver linhas na tabela da esquerda que não tenham correspondência na tabela da direita, elas serão incluídas. Além disso, se houver linhas na tabela à direita que não tenham correspondência na tabela à esquerda, elas também o serão.‌ </p><pre><code class="language-sql">SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
FULL OUTER JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
ORDER BY Customers.CustomerName</code></pre><h2 id="insert">INSERT</h2><p><code>INSERT</code> (inserir, em inglês) é uma maneira de inserir dados em uma tabela.‌ </p><pre><code class="language-sql">INSERT INTO nome_da_tabela (coluna_1, coluna_2, coluna_3) 
VALUES (valor_1, 'valor_2', valor_3);</code></pre><h2 id="like">LIKE</h2><p><code>LIKE</code> &nbsp;(como, em inglês - comparar com "<em>as"</em> acima) é usado em uma instrução com <code>WHERE</code> ou <code>HAVING</code>(como parte de <code>GROUP BY</code>) para limitar as linhas selecionadas aos itens quando uma coluna possui um determinado padrão de caracteres contido nela.</p><p>Este SQL selecionará os alunos que tem <code>FullName</code> começando com "Monique" ou que terminam com "Greene".‌ &nbsp; &nbsp;</p><pre><code class="language-sql">SELECT studentID, FullName, sat_score, rcd_updated
FROM student 
WHERE 
    FullName LIKE 'Monique%' OR 
    FullName LIKE '%Greene'; </code></pre><pre><code class="language-text">+-----------+---------------+-----------+---------------------+
| studentID | FullName      | sat_score | rcd_updated         |
+-----------+---------------+-----------+---------------------+
|         1 | Monique Davis |       400 | 2017-08-16 15:34:50 |
|         5 | Alvin Greene  |      1200 | 2017-08-16 15:34:50 |
+-----------+---------------+-----------+---------------------+
2 rows in set (0.00 sec)</code></pre><p>Você pode colocar <code>NOT</code> antes de <code>LIKE</code> para excluir as linhas com o padrão de string em vez de selecioná-las. Esse SQL exclui registros que contenham "encer Pauti" e "Ted" na coluna FullName.‌ &nbsp; &nbsp;</p><pre><code class="language-sql">SELECT studentID, FullName, sat_score, rcd_updated
FROM student 
WHERE FullName NOT LIKE '%encer Pauti%' AND FullName NOT LIKE '%"Ted"%';</code></pre><pre><code class="language-text">+-----------+----------------------+-----------+---------------------+
| studentID | FullName             | sat_score | rcd_updated         |
+-----------+----------------------+-----------+---------------------+
|         1 | Monique Davis        |       400 | 2017-08-16 15:34:50 |
|         2 | Teri Gutierrez       |       800 | 2017-08-16 15:34:50 |
|         4 | Louis Ramsey         |      1200 | 2017-08-16 15:34:50 |
|         5 | Alvin Greene         |      1200 | 2017-08-16 15:34:50 |
|         6 | Sophie Freeman       |      1200 | 2017-08-16 15:34:50 |
|         8 | Donald D. Chamberlin |      2400 | 2017-08-16 15:35:33 |
|         9 | Raymond F. Boyce     |      2400 | 2017-08-16 15:35:33 |
+-----------+----------------------+-----------+---------------------+
7 rows in set (0.00 sec)</code></pre> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como criar e manipular bancos de dados SQL com Python ]]>
                </title>
                <description>
                    <![CDATA[ Python [https://docs.python.org/pt-br/3/] e SQL [https://pt.wikipedia.org/wiki/SQL] são duas das linguagens mais importantes para analistas de dados. Neste artigo, mostrarei tudo que você precisa saber para conectar o Python e o SQL. Você aprenderá a obter dados de bancos de dados relacionais diretamente de seus pipelines de aprendizado de máquina, armazenar dados ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-criar-e-manipular-bancos-de-dados-sql-com-python/</link>
                <guid isPermaLink="false">61ed7ef7b5028e04fdf66700</guid>
                
                    <category>
                        <![CDATA[ SQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Cayo Dias ]]>
                </dc:creator>
                <pubDate>Sat, 19 Feb 2022 15:32:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/Untitled-design-1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/connect-python-with-sql/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Create and Manipulate SQL Databases with Python</a>
      </p><p><a href="https://docs.python.org/pt-br/3/">Python</a> e <a href="https://pt.wikipedia.org/wiki/SQL">SQL</a> são duas das linguagens mais importantes para analistas de dados.</p><p>Neste artigo, mostrarei tudo que você precisa saber para conectar o Python e o SQL.</p><p>Você aprenderá a obter dados de bancos de dados relacionais diretamente de seus pipelines de aprendizado de máquina, armazenar dados de suas aplicações em Python em um banco de dados próprio ou qualquer outro caso de uso que possa surgir.</p><p>Juntos, vamos aprender:</p><ul><li>Por que aprender a usar Python e SQL juntos?</li><li>Como configurar seu ambiente Python e MySQL Server</li><li>Conectar ao MySQL Server usando Python</li><li>Criar um novo banco de dados</li><li>Criar tabelas e relacionamentos entre elas</li><li>Preencher as tabelas com dados</li><li>Ler dados</li><li>Atualizar registros</li><li>Apagar registros</li><li>Criar registros a partir de listas do Python</li><li>Criar funções reutilizáveis para fazer tudo isso por nós no futuro</li></ul><p>São muitas coisas úteis e interessantes. Vamos começar!</p><p>Um breve comentário antes de começarmos: um Jupyter Notebook com todos os códigos usados neste tutorial está disponível neste <a href="https://github.com/thecraigd/Python_SQL">repositório do GitHub</a>. Reproduzir os códigos enquanto lê este artigo é altamente recomendado!</p><p>O banco de dados e os códigos SQL usados aqui são todos provenientes da minha série <a href="https://towardsdatascience.com/tagged/sql-series">Introduction to SQL </a>(Introdução ao SQL) publicada (em inglês) no site <a href="https://towardsdatascience.com/">Towards Data Science</a> (<a href="https://www.craigdoesdata.de/contact.html">entre em contato</a> se tiver algum problema para visualizar os artigos e eu enviarei um link para que eles possam ser acessados gratuitamente).</p><p>Se não está acostumado com SQL e com os conceitos subjacentes aos bancos de dados relacionais, eu indicaria <a href="https://towardsdatascience.com/tagged/sql-series">essa série</a> (além disso, é claro que há uma enorme quantidade de artigos excelentes disponíveis aqui no <a href="https://www.freecodecamp.org/news/search/?query=sql">freeCodeCamp</a>!)</p><h2 id="por-que-python-com-sql">Por que Python com SQL?</h2><p>Para analistas de dados e cientistas de dados, o Python apresenta muitas vantagens. Uma enorme variedade de bibliotecas de código aberto o torna uma ferramenta incrivelmente útil para qualquer analista de dados.</p><p>Nós temos o <a href="https://pandas.pydata.org/">pandas</a>, o <a href="https://numpy.org/">NumPy</a> e o <a href="https://vaex.readthedocs.io/en/latest/">Vaex</a> para análise de dados, o <a href="https://matplotlib.org/">Matplotlib</a>, o <a href="https://seaborn.pydata.org/">seaborn</a> e o <a href="https://bokeh.org/">Bokeh</a> para visualização, além do <a href="https://www.freecodecamp.org/news/p/5fe3a414-f0df-488b-9402-44d8edc12652/www.tensorflow.org">TensorFlow</a>, do <a href="https://scikit-learn.org/stable/">scikit-learn</a> e do <a href="https://pytorch.org/">PyTorch</a> para aprendizagem de máquina (além de muitas, muitas outras).</p><p>Com sua curva de aprendizagem (relativamente) fácil e versatilidade, não é de admirar que o Python seja <a href="https://stackoverflow.blog/2017/09/06/incredible-growth-python/">uma das linguagens de programação que mais crescem</a>.</p><p>Portanto, se optar por usar Python para análise de dados, vale a pena perguntar: de onde vêm todos esses dados?</p><p>Embora haja uma enorme variedade de fontes para conjuntos de dados, em muitos casos – particularmente, em empresas - os dados são armazenados em um banco de dados relacional. Os bancos de dados relacionais são uma maneira extremamente eficiente, poderosa e amplamente utilizada para <a href="https://pt.wikipedia.org/wiki/CRUD">criar, ler, atualizar e excluir</a> dados de todos os tipos.</p><p>Os sistemas de gerenciamento de bancos de dados relacionais (SGBDR) mais utilizados - <a href="https://www.oracle.com/database/">Oracle</a>, <a href="https://www.mysql.com/">MySQL</a>, <a href="https://en.wikipedia.org/wiki/Microsoft_SQL_Server">Microsoft SQL Server</a>, <a href="https://www.oracle.com/database/what-is-a-relational-database/">PostgreSQL</a>, <a href="https://en.wikipedia.org/wiki/IBM_DB2">IBM DB2</a> - usam a Linguagem de Consulta Estruturada (SQL, da sigla em inglês, <a href="https://en.wikipedia.org/wiki/SQL">Structured Query Language</a>) para acessar e modificar os dados.</p><p>Observe que cada SGBDR usa um tipo um pouco diferente de SQL. Portanto, o código SQL escrito para um geralmente não funcionará com outro sem modificações (normalmente pequenas). No entanto, os conceitos, estruturas e operações são, em grande parte, idênticos.</p><p>Isso quer dizer que, para um analista de dados, uma sólida compreensão de SQL é de grande importância. Saber como usar Python e SQL juntos dará a você uma vantagem ainda maior na hora de trabalhar com os seus dados.</p><p>O restante deste artigo será dedicado a mostrar exatamente como podemos fazer isso.</p><h2 id="para-come-ar">Para começar</h2><h3 id="requisitos-e-instala-o">Requisitos e instalação</h3><p>Para programar junto com este tutorial, você precisará do seu próprio <a href="https://www.python.org/downloads/">ambiente Python</a> configurado.</p><p>Eu uso a distribuição <a href="https://www.anaconda.com/">Anaconda</a>, mas há muitas maneiras de fazer isso. Basta pesquisar no Google "como instalar o Python" se precisar de ajuda. Você também pode usar o <a href="https://mybinder.org/">Binder</a> para programar usando um <a href="https://github.com/thecraigd/Python_SQL">Jupyter Notebook</a> associado.</p><p>Nós vamos usar o <a href="https://dev.mysql.com/downloads/mysql/">MySQL Community Server</a>, que é gratuito e amplamente utilizado na indústria. Se estiver utilizando o Windows, <a href="https://www.youtube.com/watch?v=2HQC94la6go" rel="noopener nofollow">este guia</a> (em inglês) o ajudará na hora de configurar. Aqui estão os guias para os usuários de <a href="https://www.youtube.com/watch?v=5BQ5GvjiAR4" rel="noopener nofollow">Mac</a> e <a href="https://www.youtube.com/watch?v=0o0tSaVQfV4" rel="noopener nofollow">Linux</a> &nbsp;(embora as instruções possam variar de acordo com a distribuição Linux utilizada).</p><p>Depois de configurados, precisaremos fazer com que eles se comuniquem.</p><p>Para isso, precisaremos instalar a biblioteca <a href="https://dev.mysql.com/doc/connector-python/en/">MySQL Connector</a> para o Python. Faça isso seguindo <a href="https://dev.mysql.com/doc/connector-python/en/connector-python-installation.html">estas instruções</a>, ou simplesmente use o pip:</p><pre><code class="language-terminal">pip install mysql-connector-python</code></pre><p>Também utilizaremos a biblioteca <a href="https://pandas.pydata.org/pandas-docs/stable/getting_started/install.html">pandas</a>. Certifique-se de que ela também esteja instalada.</p><pre><code class="language-terminal">pip install pandas</code></pre><h3 id="importando-as-bibliotecas">Importando as bibliotecas</h3><p>Como em todo projeto em Python, a primeira coisa que devemos fazer é importar nossas bibliotecas.</p><p>É uma boa prática importar todas as bibliotecas que vamos usar no início do projeto. Assim, as pessoas que lerão ou revisarão nosso código saberão, até certo ponto, o que está por vir, sem surpresas.</p><p>Para este tutorial, utilizaremos apenas duas bibliotecas - o <a href="https://dev.mysql.com/doc/connector-python/en/">MySQL Connector</a> e o <a href="https://pandas.pydata.org/">pandas</a>.</p><pre><code class="language-python">import mysql.connector
from mysql.connector import Error
import pandas as pd</code></pre><p>Importamos a função Error separadamente para que tenhamos acesso fácil a ela em nossas funções.</p><h2 id="conectando-ao-mysql-server">Conectando ao MySQL Server</h2><p>A essa altura, já devemos ter o <a href="https://dev.mysql.com/downloads/mysql/">MySQL Community Server</a> configurado em nosso sistema. Agora, precisamos escrever um código em Python que nos permita estabelecer uma conexão com este servidor.</p><figure class="kg-card kg-code-card"><pre><code class="language-python">def create_server_connection(host_name, user_name, user_password):
    connection = None
    try:
        connection = mysql.connector.connect(
            host=host_name,
            user=user_name,
            passwd=user_password
        )
        print("MySQL Database connection successful")
    except Error as err:
        print(f"Error: '{err}'")

    return connection</code></pre><figcaption>Uma função para conectar ao nosso MySQL Server</figcaption></figure><p>É uma boa prática a criação de uma função para tornar reutilizável um código como esse, permitindo que ele seja utilizado repetidas vezes com o mínimo de esforço. Uma vez criado, você poderá reutilizá-lo em todos os seus projetos futuros e o seu “eu do futuro” será grato!</p><p>Vamos revisar o código, linha por linha, para entendermos o que está acontecendo aqui:</p><p>Na primeira linha, damos um nome à função (create_server_connection) e aos seus argumentos (host_name, user_name e user_password).</p><p>Na linha seguinte, encerramos quaisquer conexões existentes para que o servidor não fique confuso com várias conexões abertas.</p><p>Em seguida, usamos um &nbsp;<a href="https://www.w3schools.com/python/python_try_except.asp">bloco try-except</a> (texto em inglês) do Python para lidar com possíveis erros. A primeira parte tenta criar uma conexão com o servidor usando o <a href="https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysql-connector-connect.html">método mysql.connector.connect()</a> (texto em inglês) e os detalhes especificados pelo usuário nos argumentos da função. Se isso funcionar, a função imprime uma pequena mensagem de sucesso.</p><p>O código referente ao bloco except imprime o erro que o MySQL Server retorna se, infelizmente, houver um erro.</p><p>Por fim, se a conexão for bem-sucedida, a função retornará um <a href="https://dev.mysql.com/doc/connector-python/en/connector-python-example-connecting.html">objeto de conexão</a> (texto em inglês).</p><p>Na prática, atribuímos o resultado dessa função a uma variável, que então se torna o nosso objeto de conexão. Podemos, depois disso, aplicar outros métodos, como o <a href="https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor.html">cursor</a> (texto em inglês), a ele e criar outros objetos úteis.</p><figure class="kg-card kg-code-card"><pre><code class="language-python">connection = create_server_connection("localhost", "root", pw)</code></pre><figcaption>Aqui, pw é uma variável, do tipo string, contendo a senha do usuário root para o nosso MySQL Server</figcaption></figure><p>O código abaixo deve resultar em uma mensagem de sucesso:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-146.png" class="kg-image" alt="image-146" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/image-146.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-146.png 790w" width="790" height="79" loading="lazy"><figcaption>U-húúú!</figcaption></figure><h3 id="criando-um-novo-banco-de-dados">Criando um novo banco de dados</h3><p>Agora que estabelecemos uma conexão, nosso próximo passo é criar um banco de dados em nosso servidor.</p><p>Neste tutorial, faremos isso uma única vez, mas, novamente, criaremos uma função reutilizável de modo que tenhamos um código que possamos reutilizar em projetos futuros.</p><pre><code class="language-python">def create_database(connection, query):
    cursor = connection.cursor()
    try:
        cursor.execute(query)
        print("Database created successfully")
    except Error as err:
        print(f"Error: '{err}'")</code></pre><p>Essa função recebe dois argumentos, connection (nosso objeto de conexão) e query (um código SQL que escreveremos na próxima etapa). Ela executa a consulta no servidor através da conexão.</p><p>Usamos o método <a href="https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor.html">cursor</a> do nosso objeto de conexão para criar um objeto do tipo cursor (o MySQL Connector usa o <a href="https://www.freecodecamp.org/portuguese/news/como-explicar-conceitos-de-programacao-orientada-a-objetos-para-uma-crianca-de-6-anos/">paradigma de programação orientado a objetos</a>, portanto, há muitos objetos herdando propriedades de objetos pai).</p><p>Este objeto cursor possui métodos como <a href="https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html">execute</a>, <a href="https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-executemany.html">executemany</a> (que usaremos neste tutorial - textos em inglês) assim como vários outros métodos úteis.</p><p>Se ajudar, podemos pensar que o objeto cursor dá acesso ao cursor que fica piscando em um terminal do MySQL Server.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-148.png" class="kg-image" alt="image-148" width="104" height="32" loading="lazy"><figcaption>É disso que estamos falando.</figcaption></figure><p>Em seguida, definimos uma consulta para criar o banco de dados e executar a função:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-149-1.png" class="kg-image" alt="image-149-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/image-149-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-149-1.png 664w" width="664" height="100" loading="lazy"></figure><p>Todos os códigos SQL deste tutorial estão explicados <a href="https://towardsdatascience.com/tagged/sql-series">na minha série de tutoriais Introduction to SQL</a> (Introdução ao SQL, em inglês), e o código completo está disponível em um Jupyter Notebook neste <a href="https://github.com/thecraigd/Python_SQL">repositório do GitHub</a>. Portanto, não explicarei o que o código SQL faz neste tutorial.</p><p>No entanto, esse é talvez o código SQL mais simples possível. Se você pode ler em inglês, provavelmente pode descobrir o que ele faz!</p><p>Executar a função create_database com os argumentos acima resulta na criação de um banco de dados chamado 'school' em nosso servidor.</p><p>Por que nosso banco de dados é chamado de 'school' (escola)? Talvez agora seja um bom momento para examinarmos em mais detalhes o que vamos implementar exatamente neste tutorial.</p><h3 id="nosso-banco-de-dados">Nosso banco de dados</h3><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/ERD-1.png" class="kg-image" alt="ERD-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/ERD-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/02/ERD-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/02/ERD-1.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/ERD-1.png 1843w" sizes="(min-width: 1200px) 1200px" width="1843" height="1300" loading="lazy"><figcaption>Diagrama entidade-relacionamento do nosso banco de dados</figcaption></figure><p>Seguindo o exemplo da minha <a href="https://towardsdatascience.com/tagged/sql-series">série anterior</a>, implementaremos o banco de dados para a International Language School (Escola Internacional de Idiomas) - uma escola fictícia de treinamento de idiomas que oferece aulas de idiomas profissionais para clientes corporativos.</p><p>O <a href="https://www.lucidchart.com/pages/er-diagrams">Diagrama Entidade Relacionamento (DER)</a> (texto em inglês) apresenta as entidades (Teacher, Client, Course e Participant) e define as relações entre elas.</p><p>Todas as informações sobre o que é um DER e o que considerar ao criar um e projetar um banco de dados podem ser encontradas <a href="https://towardsdatascience.com/designing-a-relational-database-and-creating-an-entity-relationship-diagram-89c1c19320b2">neste artigo</a> (em inglês).</p><p>O código SQL, os requisitos do banco de dados e os dados para inclusão no banco de dados estão todos disponíveis <a href="https://github.com/thecraigd/SQL_School_Tutorial">neste repositório do GitHub</a>, mas você também verá tudo à medida que avançarmos neste tutorial.</p><h3 id="conectando-ao-banco-de-dados">Conectando ao banco de dados</h3><p>Agora que criamos um banco de dados no MySQL Server, podemos modificar nossa função create_server_connection para conectar diretamente a esse banco de dados.</p><p>Observe que é possível - comum, na verdade - ter vários bancos de dados em um servidor MySQL, então queremos nos conectar sempre e automaticamente ao banco de dados em que estamos interessados.</p><p>Podemos fazer da seguinte maneira:</p><pre><code class="language-python">def create_db_connection(host_name, user_name, user_password, db_name):
    connection = None
    try:
        connection = mysql.connector.connect(
            host=host_name,
            user=user_name,
            passwd=user_password,
            database=db_name
        )
        print("MySQL Database connection successful")
    except Error as err:
        print(f"Error: '{err}'")

    return connection</code></pre><p>Essa é exatamente a mesma função, mas agora temos mais um argumento - o nome do banco de dados - que é passado para o método connect().</p><h3 id="criando-uma-fun-o-para-execu-o-de-consultas">Criando uma função para execução de consultas</h3><p>A última função que criaremos (por enquanto) é extremamente vital - uma função de execução de consulta. Ela pegará nossas consultas SQL, armazenadas como strings do Python, e as passará para que o método cursor.execute() as execute no servidor.</p><pre><code class="language-python">def execute_query(connection, query):
    cursor = connection.cursor()
    try:
        cursor.execute(query)
        connection.commit()
        print("Query successful")
    except Error as err:
        print(f"Error: '{err}'")</code></pre><p>Essa função é idêntica à nossa função create_database, exceto por usar o método <a href="https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlconnection-commit.html">connection.commit()</a> para garantir que os comandos detalhados em nossas consultas SQL sejam implementados.</p><p>Essa função será nosso carro-chefe, que usaremos (junto com create_db_connection) para criar tabelas, estabelecer relacionamentos entre essas tabelas, preencher as tabelas com dados e atualizar e excluir registros em nosso banco de dados.</p><p>Se você for um especialista em SQL, essa função permitirá que você execute todos e quaisquer comandos e consultas complexas que você possa ter, diretamente de um script em Python. Ela pode ser uma ferramenta muito poderosa para gerenciar seus dados.</p><h2 id="criando-tabelas">Criando tabelas</h2><p>Agora estamos prontos para começar a executar comandos SQL em nosso servidor e começar a construir nosso banco de dados. A primeira coisa que queremos fazer é criar as tabelas necessárias.</p><p>Vamos começar com a tabela Teacher (professor, em inglês):</p><pre><code class="language-python">create_teacher_table = """
CREATE TABLE teacher (
  teacher_id INT PRIMARY KEY,
  first_name VARCHAR(40) NOT NULL,
  last_name VARCHAR(40) NOT NULL,
  language_1 VARCHAR(3) NOT NULL,
  language_2 VARCHAR(3),
  dob DATE,
  tax_id INT UNIQUE,
  phone_no VARCHAR(20)
  );
 """

connection = create_db_connection("localhost", "root", pw, db) # Connect to the Database
execute_query(connection, create_teacher_table) # Execute our defined query</code></pre><p>Primeiro, atribuímos nosso comando SQL (explicado em detalhes <a href="https://towardsdatascience.com/coding-and-implementing-a-relational-database-using-mysql-d9bc69be90f5">aqui</a>) a uma variável com um nome apropriado.</p><p>Neste caso, usamos a <a href="https://developers.google.com/edu/python/strings">notação de aspas triplas do Python para definir strings que se estendem por múltiplas linhas</a> (texto em inglês) para armazenar nossa consulta SQL. Então, nós a passamos para a função execute_query que a executará.</p><p>Observe que essa formatação de várias linhas é puramente para facilitar a leitura do código por humanos. Nem SQL nem Python 'se importam' se o comando SQL estiver distribuído dessa maneira. Desde que a sintaxe esteja correta, ambas as linguagens a aceitarão.</p><p>Para o bem dos humanos que lerão seu código (mesmo que seja apenas o você do futuro!), é muito útil empregar essa formatação para tornar o código mais legível e compreensível.</p><p>O mesmo vale para o uso de expressões do SQL em LETRAS MAIÚSCULAS. Esta é uma convenção amplamente usada e que é fortemente recomendada, mas o software real que executa o código não diferencia maiúsculas de minúsculas e tratará 'CREATE TABLE teacher' e 'create table teacher' como comandos idênticos.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-151.png" class="kg-image" alt="image-151" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/image-151.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/02/image-151.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-151.png 1084w" width="1084" height="118" loading="lazy"></figure><p>A execução deste código retorna nossas mensagens de sucesso. Também podemos verificar isso no client na linha de comando do MySQL Server:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-152.png" class="kg-image" alt="image-152" width="267" height="175" loading="lazy"></figure><p>Excelente! Agora vamos criar as tabelas restantes.</p><pre><code class="language-python">create_client_table = """
CREATE TABLE client (
  client_id INT PRIMARY KEY,
  client_name VARCHAR(40) NOT NULL,
  address VARCHAR(60) NOT NULL,
  industry VARCHAR(20)
);
 """

create_participant_table = """
CREATE TABLE participant (
  participant_id INT PRIMARY KEY,
  first_name VARCHAR(40) NOT NULL,
  last_name VARCHAR(40) NOT NULL,
  phone_no VARCHAR(20),
  client INT
);
"""

create_course_table = """
CREATE TABLE course (
  course_id INT PRIMARY KEY,
  course_name VARCHAR(40) NOT NULL,
  language VARCHAR(3) NOT NULL,
  level VARCHAR(2),
  course_length_weeks INT,
  start_date DATE,
  in_school BOOLEAN,
  teacher INT,
  client INT
);
"""


connection = create_db_connection("localhost", "root", pw, db)
execute_query(connection, create_client_table)
execute_query(connection, create_participant_table)
execute_query(connection, create_course_table)</code></pre><p>Esses comandos criarão as quatro tabelas necessárias para nossas quatro entidades.</p><p>Agora, vamos definir os relacionamentos entre elas e criar mais uma tabela para lidar com o relacionamento muitos-para-muitos entre as tabelas participant e course (participante e curso, em inglês, respectivamente). Veja mais detalhes <a href="https://towardsdatascience.com/designing-a-relational-database-and-creating-an-entity-relationship-diagram-89c1c19320b2">aqui</a> (texto em inglês).</p><p>Fazemos exatamente da mesma forma:</p><pre><code class="language-python">alter_participant = """
ALTER TABLE participant
ADD FOREIGN KEY(client)
REFERENCES client(client_id)
ON DELETE SET NULL;
"""

alter_course = """
ALTER TABLE course
ADD FOREIGN KEY(teacher)
REFERENCES teacher(teacher_id)
ON DELETE SET NULL;
"""

alter_course_again = """
ALTER TABLE course
ADD FOREIGN KEY(client)
REFERENCES client(client_id)
ON DELETE SET NULL;
"""

create_takescourse_table = """
CREATE TABLE takes_course (
  participant_id INT,
  course_id INT,
  PRIMARY KEY(participant_id, course_id),
  FOREIGN KEY(participant_id) REFERENCES participant(participant_id) ON DELETE CASCADE,
  FOREIGN KEY(course_id) REFERENCES course(course_id) ON DELETE CASCADE
);
"""

connection = create_db_connection("localhost", "root", pw, db)
execute_query(connection, alter_participant)
execute_query(connection, alter_course)
execute_query(connection, alter_course_again)
execute_query(connection, create_takescourse_table)</code></pre><p>Agora, nossas tabelas foram criadas, juntamente com as restrições apropriadas e as relações entre chaves primárias e chaves estrangeiras.</p><h3 id="preenchendo-as-tabelas">Preenchendo as tabelas</h3><p>A próxima etapa é adicionar alguns registros às tabelas. Novamente, usaremos a função execute_query para enviar nossos comandos SQL existentes ao servidor. Vamos começar mais uma vez com a tabela Teacher.</p><pre><code class="language-python">pop_teacher = """
INSERT INTO teacher VALUES
(1,  'James', 'Smith', 'ENG', NULL, '1985-04-20', 12345, '+491774553676'),
(2, 'Stefanie',  'Martin',  'FRA', NULL,  '1970-02-17', 23456, '+491234567890'), 
(3, 'Steve', 'Wang',  'MAN', 'ENG', '1990-11-12', 34567, '+447840921333'),
(4, 'Friederike',  'Müller-Rossi', 'DEU', 'ITA', '1987-07-07',  45678, '+492345678901'),
(5, 'Isobel', 'Ivanova', 'RUS', 'ENG', '1963-05-30',  56789, '+491772635467'),
(6, 'Niamh', 'Murphy', 'ENG', 'IRI', '1995-09-08',  67890, '+491231231232');
"""

connection = create_db_connection("localhost", "root", pw, db)
execute_query(connection, pop_teacher)</code></pre><p>Funcionou? Podemos verificar no cliente de linha de comando do MySQL:</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-153.png" class="kg-image" alt="image-153" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/image-153.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/02/image-153.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-153.png 1189w" width="1189" height="300" loading="lazy"><figcaption>Parece bom!</figcaption></figure><p>Agora, vamos preencher as tabelas restantes.</p><pre><code class="language-python">pop_client = """
INSERT INTO client VALUES
(101, 'Big Business Federation', '123 Falschungstraße, 10999 Berlin', 'NGO'),
(102, 'eCommerce GmbH', '27 Ersatz Allee, 10317 Berlin', 'Retail'),
(103, 'AutoMaker AG',  '20 Künstlichstraße, 10023 Berlin', 'Auto'),
(104, 'Banko Bank',  '12 Betrugstraße, 12345 Berlin', 'Banking'),
(105, 'WeMoveIt GmbH', '138 Arglistweg, 10065 Berlin', 'Logistics');
"""

pop_participant = """
INSERT INTO participant VALUES
(101, 'Marina', 'Berg','491635558182', 101),
(102, 'Andrea', 'Duerr', '49159555740', 101),
(103, 'Philipp', 'Probst',  '49155555692', 102),
(104, 'René',  'Brandt',  '4916355546',  102),
(105, 'Susanne', 'Shuster', '49155555779', 102),
(106, 'Christian', 'Schreiner', '49162555375', 101),
(107, 'Harry', 'Kim', '49177555633', 101),
(108, 'Jan', 'Nowak', '49151555824', 101),
(109, 'Pablo', 'Garcia',  '49162555176', 101),
(110, 'Melanie', 'Dreschler', '49151555527', 103),
(111, 'Dieter', 'Durr',  '49178555311', 103),
(112, 'Max', 'Mustermann', '49152555195', 104),
(113, 'Maxine', 'Mustermann', '49177555355', 104),
(114, 'Heiko', 'Fleischer', '49155555581', 105);
"""

pop_course = """
INSERT INTO course VALUES
(12, 'English for Logistics', 'ENG', 'A1', 10, '2020-02-01', TRUE,  1, 105),
(13, 'Beginner English', 'ENG', 'A2', 40, '2019-11-12',  FALSE, 6, 101),
(14, 'Intermediate English', 'ENG', 'B2', 40, '2019-11-12', FALSE, 6, 101),
(15, 'Advanced English', 'ENG', 'C1', 40, '2019-11-12', FALSE, 6, 101),
(16, 'Mandarin für Autoindustrie', 'MAN', 'B1', 15, '2020-01-15', TRUE, 3, 103),
(17, 'Français intermédiaire', 'FRA', 'B1',  18, '2020-04-03', FALSE, 2, 101),
(18, 'Deutsch für Anfänger', 'DEU', 'A2', 8, '2020-02-14', TRUE, 4, 102),
(19, 'Intermediate English', 'ENG', 'B2', 10, '2020-03-29', FALSE, 1, 104),
(20, 'Fortgeschrittenes Russisch', 'RUS', 'C1',  4, '2020-04-08',  FALSE, 5, 103);
"""

pop_takescourse = """
INSERT INTO takes_course VALUES
(101, 15),
(101, 17),
(102, 17),
(103, 18),
(104, 18),
(105, 18),
(106, 13),
(107, 13),
(108, 13),
(109, 14),
(109, 15),
(110, 16),
(110, 20),
(111, 16),
(114, 12),
(112, 19),
(113, 19);
"""

connection = create_db_connection("localhost", "root", pw, db)
execute_query(connection, pop_client)
execute_query(connection, pop_participant)
execute_query(connection, pop_course)
execute_query(connection, pop_takescourse)</code></pre><p>Surpreendente! Acabamos de criar um banco de dados completo com relações, restrições e registros no MySQL, usando apenas comandos em Python.</p><p>Fizemos isso passo a passo para que o processo fosse compreensível. Mas a esta altura você já deve ter percebido que todos esses comandos podem facilmente ser incluídos em um script em Python e executados em um único comando no terminal.</p><h2 id="lendo-os-dados">Lendo os dados</h2><p>Agora, temos um banco de dados funcional com o qual podemos trabalhar. Como analista de dados, é provável que você entre em contato com bancos de dados existentes nas organizações em que trabalha. Será muito útil saber como extrair dados desses bancos de dados para que possam ser alimentados em seu pipeline de dados em Python. É nisso que vamos trabalhar a seguir.</p><p>Para isso, precisaremos de mais uma função, desta vez, usando <a href="https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-fetchall.html">cursor.fetchall()</a> em vez de <a href="https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlconnection-commit.html">cursor.commit()</a> (textos das duas funções em inglês). Com esta função, leremos dados do banco de dados sem fazer nenhuma alteração.</p><pre><code class="language-python">def read_query(connection, query):
    cursor = connection.cursor()
    result = None
    try:
        cursor.execute(query)
        result = cursor.fetchall()
        return result
    except Error as err:
        print(f"Error: '{err}'")</code></pre><p>Novamente, vamos implementar isso de uma maneira muito semelhante ao execute_query. Vamos testar com uma consulta simples para ver como funciona.</p><pre><code class="language-python">q1 = """
SELECT *
FROM teacher;
"""

connection = create_db_connection("localhost", "root", pw, db)
results = read_query(connection, q1)

for result in results:
  print(result)</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-154.png" class="kg-image" alt="image-154" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/image-154.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/02/image-154.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-154.png 1171w" width="1171" height="454" loading="lazy"></figure><p>Exatamente o que estávamos esperando. A função também funciona com consultas mais complexas, como esta envolvendo um JOIN entre as tabelas de course e client (curso e cliente, em inglês, respectivamente).</p><pre><code class="language-python">q5 = """
SELECT course.course_id, course.course_name, course.language, client.client_name, client.address
FROM course
JOIN client
ON course.client = client.client_id
WHERE course.in_school = FALSE;
"""

connection = create_db_connection("localhost", "root", pw, db)
results = read_query(connection, q5)

for result in results:
  print(result)</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-155.png" class="kg-image" alt="image-155" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/image-155.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/02/image-155.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-155.png 1188w" width="1188" height="240" loading="lazy"></figure><p>Muito bom.</p><p>Para nossos pipelines de dados e fluxos de trabalho em Python, podemos querer obter esses resultados em formatos diferentes para torná-los mais úteis ou prontos para manipulação.</p><p>Vamos ver alguns exemplos para entender como podemos fazer isso.</p><h3 id="formatando-os-resultados-em-uma-lista">Formatando os resultados em uma lista</h3><pre><code class="language-python">#Inicializa uma lista vazia 
from_db = []

# Percorrer os resultados e inseri-los à lista

# Retorna uma lista de tuplas
for result in results:
  result = result
  from_db.append(result)</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-156.png" class="kg-image" alt="image-156" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/image-156.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/02/image-156.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-156.png 1387w" sizes="(min-width: 1200px) 1200px" width="1387" height="171" loading="lazy"></figure><h3 id="formatando-o-resultado-em-uma-lista-de-listas">Formatando o resultado em uma lista de listas</h3><pre><code class="language-python"># Retorna uma lista de listas
from_db = []

for result in results:
  result = list(result)
  from_db.append(result)</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-157.png" class="kg-image" alt="image-157" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/image-157.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/02/image-157.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-157.png 1376w" sizes="(min-width: 1200px) 1200px" width="1376" height="169" loading="lazy"></figure><h3 id="formatando-o-resultado-em-um-dataframe-do-pandas">Formatando o resultado em um <a href="https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html">DataFrame do Pandas</a></h3><p>Para os analistas de dados usando Python, o <a href="https://pandas.pydata.org/pandas-docs/stable/index.html">pandas</a> (texto em inglês) é o nosso velho amigo, belo e confiável. É muito simples converter a saída do nosso banco de dados em um DataFrame. A partir daí, as possibilidades são infinitas!</p><pre><code class="language-python"># Retorna uma lista de listas e cria um DataFrame do Pandas
from_db = []

for result in results:
  result = list(result)
  from_db.append(result)


columns = ["course_id", "course_name", "language", "client_name", "address"]
df = pd.DataFrame(from_db, columns=columns)</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-158.png" class="kg-image" alt="image-158" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/image-158.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-158.png 927w" width="927" height="316" loading="lazy"></figure><p>Espero que possa ver as possibilidades se desdobrando diante de você. Com apenas algumas linhas de código, podemos extrair facilmente todos os dados que podemos manipular dos bancos de dados relacionais em que eles residem e trazê-los para nossos pipelines de análise de dados de última geração. Isso é algo realmente útil.</p><h2 id="atualizando-registros">Atualizando registros</h2><p>Quando mantemos um banco de dados, às vezes precisaremos fazer alterações nos registros existentes. Nesta seção, veremos como fazer isso.</p><p>Digamos que a ILS seja notificada de que um de seus clientes existentes, a Big Business Federation, está mudando de escritório para 23 Fingiertweg, 14534 Berlin. Nesse caso, o administrador do banco de dados (nós!) precisará fazer algumas alterações.</p><p>Felizmente, podemos fazer isso com nossa função execute_query junto com a instrução <a href="https://dev.mysql.com/doc/refman/8.0/en/update.html">UPDATE</a> (texto em inglês) do SQL.</p><pre><code class="language-python">update = """
UPDATE client 
SET address = '23 Fingiertweg, 14534 Berlin' 
WHERE client_id = 101;
"""

connection = create_db_connection("localhost", "root", pw, db)
execute_query(connection, update)</code></pre><p>Note que a cláusula WHERE é muito importante. Se executarmos esse comando sem a cláusula WHERE, todos os endereços de todos os registros em nossa tabela Client serão atualizados para 23 Fingiertweg. Não é exatamente isso que queremos fazer.</p><p>Observe também que usamos "WHERE client_id = 101" na consulta UPDATE. Também seria possível usar "WHERE client_name = 'Big Business Federation'" ou "WHERE address = '123 Falschungstraße, 10999 Berlin'" ou mesmo "WHERE address LIKE '%Falschung%'".</p><p>O importante é que a cláusula WHERE nos permite identificar exclusivamente o registro (ou registros) que queremos atualizar.</p><h2 id="apagando-registros">Apagando registros</h2><p>Também é possível usar nossa função execute_query para excluir registros, usando <a href="https://dev.mysql.com/doc/refman/8.0/en/delete.html">DELETE</a> (texto em inglês).</p><p>Ao usar SQL com bancos de dados relacionais, precisamos ter cuidado ao usar o operador DELETE. Este não é o Windows. Não há um alerta dizendo "Tem certeza de que deseja excluir isso?" em uma janela de pop-up e não há uma lixeira para a reciclagem. Uma vez que excluímos algo, esse algo realmente se foi.</p><p>Dito isso, nós às vezes realmente precisamos apagar coisas. Então, vamos ver isso na prática, apagando um curso da nossa tabela Course.</p><p>Antes de mais nada, vamos nos lembrar dos cursos que temos.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-174.png" class="kg-image" alt="image-174" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/image-174.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/02/image-174.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-174.png 1082w" width="1082" height="558" loading="lazy"></figure><p>Digamos que o curso 20, 'Fortgeschrittenes Russisch' (que é 'Russo avançado' para você e para mim), está chegando ao fim. Então, precisamos removê-lo do nosso banco de dados.</p><p>A essa altura, você não ficará surpreso com a forma como fazemos isso - salve o comando SQL como uma string e, em seguida, passe-o para a nossa função execute_query.</p><pre><code class="language-python">delete_course = """
DELETE FROM course 
WHERE course_id = 20;
"""

connection = create_db_connection("localhost", "root", pw, db)
execute_query(connection, delete_course)</code></pre><p>Vamos verificar para confirmar que obtivemos o resultado pretendido:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-175.png" class="kg-image" alt="image-175" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/image-175.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/02/image-175.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-175.png 1068w" width="1068" height="538" loading="lazy"></figure><p>'Russo avançado' se foi, como esperávamos.</p><p>Esse comando também funciona para apagar colunas inteiras, usando <a href="https://www.w3schools.com/sql/sql_ref_drop_column.asp">DROP COLUMN</a> e tabelas inteiras, usando <a href="https://www.w3schools.com/sql/sql_ref_drop_table.asp">DROP TABLE</a> (ambos os textos de referência em inglês), mas não abordaremos esses comandos neste tutorial.</p><p>No entanto, vá em frente e experimente-os - não importa se você excluir uma coluna ou tabela de um banco de dados para uma escola fictícia. É uma boa ideia se familiarizar com esses comandos antes de passar para um ambiente de produção.</p><h3 id="e-o-crud">E o <a href="https://pt.wikipedia.org/wiki/CRUD">CRUD</a>?</h3><p>A essa altura, já podemos concluir as quatro operações principais para o armazenamento de dados persistentes.</p><p>Aprendemos a:</p><ul><li>Create (Criar) - bancos de dados, tabelas e registros inteiramente novos</li><li>Read (Ler) - extrair dados de um banco de dados e armazenar em diversos formatos</li><li>Update (Atualizar) - fazer alterações nos registros existentes no banco de dados</li><li>Delete (Apagar) - remover registros que não são mais necessários</li></ul><p>Poder fazer essas coisas é incrivelmente útil.</p><p>Antes de concluirmos, temos mais uma habilidade muito importante para aprender.</p><h2 id="criando-registros-a-partir-de-listas">Criando registros a partir de listas</h2><p>Vimos, ao preencher nossas tabelas, que podemos utilizar o comando SQL INSERT em nossa função execute_query para inserir registros em nosso banco de dados.</p><p>Dado que estamos usando Python para manipular nosso banco de dados SQL, seria útil poder obter uma estrutura de dados do Python, tal como uma <a href="https://www.w3schools.com/python/python_lists.asp">lista</a> (texto em inglês), e inseri-la diretamente em nosso banco de dados.</p><p>Isso pode ser útil quando queremos armazenar logs de atividade do usuário em um aplicativo de mídia social que escrevemos em Python ou entradas de usuários em uma página Wiki que criamos, por exemplo. Existem tantos usos possíveis para isso quantos você possa imaginar.</p><p>Esse método também é mais seguro se nosso banco de dados estiver aberto para nossos usuários a qualquer momento, pois ajuda a prevenir ataques de <a href="https://pt.wikipedia.org/wiki/Inje%C3%A7%C3%A3o_de_SQL">injeção de SQL</a>, que podem <a href="https://www.lucidchart.com/pages/er-diagrams">danificar ou até destruir</a> (texto em inglês) todo o nosso banco de dados.</p><p>Para fazer isso, escreveremos uma função usando o método <a href="https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-executemany.html">executemany()</a>, em vez do método <a href="https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html">execute()</a> (textos de referência em inglês), mais simples, que usamos até agora.</p><pre><code class="language-python">def execute_list_query(connection, sql, val):
    cursor = connection.cursor()
    try:
        cursor.executemany(sql, val)
        connection.commit()
        print("Query successful")
    except Error as err:
        print(f"Error: '{err}'")</code></pre><p>Agora temos a função, precisamos definir um comando SQL ('sql') e uma lista contendo os valores que desejamos inserir no banco de dados ('val'). Os valores devem ser armazenados em uma <a href="https://www.w3schools.com/python/python_lists.asp">lista</a> de <a href="https://www.w3schools.com/python/python_tuples.asp">tuplas</a> (textos de referência em inglês), que é uma maneira bastante comum de armazenar dados em Python.</p><p>Para adicionar dois novos professores ao banco de dados, podemos escrever um código como este:</p><pre><code class="language-python">sql = '''
    INSERT INTO teacher (teacher_id, first_name, last_name, language_1, language_2, dob, tax_id, phone_no) 
    VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
    '''
    
val = [
    (7, 'Hank', 'Dodson', 'ENG', None, '1991-12-23', 11111, '+491772345678'), 
    (8, 'Sue', 'Perkins', 'MAN', 'ENG', '1976-02-02', 22222, '+491443456432')
]</code></pre><p>Observe aqui que no código 'sql' usamos o '%s' como um espaço reservado para nosso valor. A semelhança com o <a href="https://stackoverflow.com/questions/4288973/whats-the-difference-between-s-and-d-in-python-string-formatting/48660475">'%s'</a> para uma string em Python é apenas coincidência (e francamente, muito confusa), pois devemos usar '%s' para todos os tipos de dados (strings, inteiros, datas etc) com o MySQL Python Conector.</p><p>Você pode ver vários casos no <a href="https://stackoverflow.com/questions/20818155/not-all-parameters-were-used-in-the-sql-statement-python-mysql/20818201">Stackoverflow</a> em que alguém ficou confuso e tentou usar <a href="https://stackoverflow.com/questions/4288973/whats-the-difference-between-s-and-d-in-python-string-formatting/48660475">'%d'</a> para inteiros porque estava acostumado a fazer isso em Python. Isso não funcionará aqui - precisamos usar um '%s' para cada coluna para qual queremos adicionar um valor.</p><p>A função executemany, então, pega cada tupla em nossa lista 'val' e insere o valor relevante para aquela coluna no lugar do espaço reservado e executa o comando SQL para cada tupla contida na lista.</p><p>Isso pode ser feito para várias linhas de dados, desde que sejam formatadas corretamente. Em nosso exemplo, adicionaremos apenas dois novos professores, para fins ilustrativos, mas em princípio podemos adicionar quantos quisermos.</p><p>Vamos executar este comando e adicionar os professores ao nosso banco de dados.</p><pre><code class="language-python">connection = create_db_connection("localhost", "root", pw, db)
execute_list_query(connection, sql, val)</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-177.png" class="kg-image" alt="image-177" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/image-177.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/02/image-177.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/image-177.png 1178w" width="1178" height="526" loading="lazy"></figure><p>Boas-vindas à ILS, Hank e Sue!</p><p>Esta é mais uma função muito útil, permitindo-nos pegar dados gerados em nossos scripts e aplicativos Python e inseri-los diretamente em nosso banco de dados.</p><h2 id="conclus-o">Conclusão</h2><p>Abordamos muitas coisas neste tutorial.</p><p>Aprendemos como usar o Python e o MySQL Connector para criar um banco de dados totalmente novo no MySQL Server, criar tabelas dentro desse banco de dados, definir as relações entre elas e preenchê-las com dados.</p><p>Abordamos como <a href="https://pt.wikipedia.org/wiki/CRUD">Criar, Ler, Atualizar e Apagar</a> dados em nosso banco de dados.</p><p>Vimos como extrair dados de bancos de dados existentes e carregá-los em pandas DataFrames, prontos para análise e trabalho adicional, aproveitando todas as possibilidades oferecidas pela stack <a href="https://www.pluralsight.com/guides/a-lap-around-the-pydata-stack">PyData</a> (texto em inglês).</p><p>Indo na outra direção, também aprendemos como pegar dados gerados por nossos scripts e aplicativos Python e gravá-los em um banco de dados onde eles podem ser armazenados com segurança para recuperação e manipulação posteriores.</p><p>Espero que este tutorial tenha ajudado você a ver como podemos usar Python e SQL juntos para poder manipular dados de forma ainda mais eficaz!</p><p>Se você quiser ver mais sobre os projetos e trabalhos do autor, visite o site do autor em <em><a href="https://www.craigdoesdata.de/">craigdoesdata.de</a>. </em>Se você tiver algum feedback sobre este tutorial, <em><a href="https://www.craigdoesdata.de/contact.html">entre em contato</a> com ele - </em>todos os comentários serão bem recebidos<em>!</em></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/02/logo.png" class="kg-image" alt="logo" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/02/logo.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/02/logo.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/02/logo.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/02/logo.png 2156w" sizes="(min-width: 720px) 720px" width="2156" height="400" loading="lazy"></figure> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Tutorial de Group By do SQL: Count, Sum, Average e instrução Having explicadas ]]>
                </title>
                <description>
                    <![CDATA[ A instrução GROUP BY é poderosa, mas, às vezes, pode causar confusão. Mesmo após oito anos, sempre que utilizo o GROUP BY, eu tenho de parar e pensar o que exatamente está ocorrendo. Neste artigo, nós vamos ver como criar uma instrução GROUP BY, o que ela faz em sua ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/tutorial-de-group-do-sql-count-sum-average-e-instrucao-having-explicadas/</link>
                <guid isPermaLink="false">61f456f053557304fa19c686</guid>
                
                    <category>
                        <![CDATA[ SQL ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Arian Vitor Brito Carvalho ]]>
                </dc:creator>
                <pubDate>Sat, 29 Jan 2022 22:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/01/5f9c98d4740569d1a4ca1c42.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/sql-group-by-clauses-explained/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">SQL Group By Tutorial: Count, Sum, Average, and Having Clauses Explained</a>
      </p><p>A instrução <code>GROUP BY</code> é poderosa, mas, às vezes, pode causar confusão.</p><p>Mesmo após oito anos, sempre que utilizo o <code>GROUP BY</code>, eu tenho de parar e pensar o que exatamente está ocorrendo.</p><p>Neste artigo, nós vamos ver como criar uma instrução <code>GROUP BY</code>, o que ela faz em sua consulta e como você pode utilizá-la para gerar agregações e coletar insights sobre os seus dados. </p><p>O que vamos fazer:</p><ul><li>Configurar o banco de dados. </li><li>Configurar os dados (criar vendas). </li><li>Como funciona um <a href="https://www.freecodecamp.org/news/sql-group-by-clauses-explained/#how-does-a-group-by-work"><code>GROUP BY</code></a>?.</li><li>Escrever instruções <code>GROUP BY</code> .</li><li>Agregações (<code>COUNT</code>, <code>SUM</code>, <code>AVG</code>).</li><li>Trabalhar com diversos grupos.</li><li>Utilizar funções dentro do <code>GROUP BY</code>.</li><li>Filtrar grupos com <code>HAVING</code>.</li><li>Agregar com agrupamentos implícitos.</li></ul><h2 id="configurar-o-banco-de-dados">Configurar o banco de dados</h2><p>Antes de escrever nossas consultas, precisamos configurar nosso banco de dados.</p><p>Para os exemplos, vamos utilizar o PostgreSQL, mas as consultas e conceitos mostrados serão de fácil compreensão para qualquer sistema de banco de dados moderno (como o MySQL, o SQL Server e assim por diante).</p><p>Para trabalhar com nosso banco de dados PostgreSQL, podemos utilizar <a href="https://www.postgresql.org/docs/current/app-psql.html">psql</a> — o comando de linha interativo do PostgreSQL. Se você possui outro serviço de banco de dados de sua preferência, não há problema de trabalhar nele também.</p><p>Para começar, vamos criar nossa tabela de dados. Com o <a href="https://www.postgresql.org/download/">PostgreSQL</a> instalado, podemos usar o comando &nbsp;<code>createdb &lt;database-name&gt;</code> no console para criar um novo banco de dados. Chamei o meu de <code>fcc</code>:</p><pre><code>$ createdb fcc
</code></pre><p>Agora, vamos iniciar o nosso console interativo utilizando o comando <code>psql</code>, e nos conectar ao banco de dados que acabamos de fazer <code>\c &lt;nome-do-banco&gt;</code>:</p><pre><code>$ psql
psql (11.5)
Type "help" for help.

john=# \c fcc
You are now connected to database "fcc" as user "john".
fcc=#
</code></pre><blockquote><strong>Observação<strong>:</strong></strong> eu limpei a saída do <code>psql</code> nestes exemplos para facilitar a leitura, então não se preocupe se as saídas mostradas aqui não sejam exatamente iguais ao que você verá no seu terminal.</blockquote><p>Eu encorajo você a acompanhar estes exemplos e a fazer as consultas por conta própria. Você vai aprender e lembrar bem mais trabalhando nos exemplos ao invés de apenas lê-los.</p><h2 id="configurar-os-dados-criar-vendas-"><strong>Configurar os dados (criar vendas).</strong></h2><p>Para os nossos exemplos, vamos utilizar um banco que guarde o histórico de vendas de vários produtos através de diferentes localizações.</p><p>Iremos chamar esta tabela de <code>vendas</code>. Ela será uma representação simples de uma loja: nome do local, nome do produto, preço e a data em que o produto foi vendido.</p><p>Se fossemos construir este banco em uma aplicação real, configuraríamos as chaves estrangeiras para outras tabelas (como <code>local</code> ou <code>produtos</code>). No entanto, para ilustrar os conceitos de <code>GROUP BY</code>, vamos utilizar apenas colunas do tipo <code>TEXT</code>.</p><p>Vamos criar a tabela e inserir alguns dados de vendas:</p><pre><code class="language-sql">CREATE TABLE vendas(
  local TEXT,
  produto TEXT,
  preco DECIMAL,
  vendido_em TIMESTAMP
);

INSERT INTO vendas(local, produto, preco, vendido_em) VALUES
('Central', 'Café', 2, NOW()),
('Central', 'Café', 2, NOW() - INTERVAL '1 hora'),
('Centro', 'Biscoito', 3, NOW() - INTERVAL '2 hora'),
('Centro', 'Café', 2, NOW() - INTERVAL '1 dia'),
('Central', 'Biscoito', 2, NOW() - INTERVAL '2 dias'),
('Rua 1', 'Biscoito', 3, NOW() - INTERVAL '2 dias' - INTERVAL '1 hora'),
('Rua 1', 'Café', 2, NOW() - INTERVAL '3 dias'),
('Central', 'Biscoito', 3, NOW() - INTERVAL '3 dias' - INTERVAL '1 hora');
</code></pre><p>Temos 3 localizações: Central, Centro e Rua 1<em><em>.</em></em></p><p>Nós temos dois produtos, Café e Biscoito, e inserimos diferentes valores em <code>vendido_em</code> para representar os itens sendo vendidos em dias e horas diferentes.</p><p>Existem algumas vendas na data de hoje, algumas na data de ontem, e algumas em dias anteriores a ontem.</p><h2 id="como-funciona-um-group-by"><strong>Como funciona um <code>GROUP BY</code>?</strong></h2><p>Para ilustrar como as instruções <code>GROUP BY</code> funcionam, vamos primeiro falar através de um exemplo.</p><p>Imagine que temos um quarto cheio de pessoas que nasceram em países diferentes.</p><p>Se quiséssemos descobrir a <strong>média da altura</strong> das pessoas no quarto <strong>por país</strong>, primeiro, pediríamos para as pessoas se separarem em grupos baseados no país em que nasceram. </p><p>Uma vez separados em seus devidos grupos, poderíamos calcular a média de altura de qualquer um desses grupos.</p><p>É assim que funcionam as instruções <code>GROUP BY</code>. Primeiro, definimos como queremos agrupar as informações – então, podemos realizar cálculos ou agregações nos grupos.</p><h3 id="diversos-grupos"><strong>Diversos grupos</strong></h3><p>Podemos agrupar os dados em quantos grupos ou subgrupos quisermos.</p><p>Por exemplo, depois de pedirmos para as pessoas se separarem baseados no seu país de nascimento, podemos dizer para cada um desses grupos que se separem em grupos baseados na cor de seus olhos.</p><p>Ao fazer isso, temos grupos de pessoas baseados na combinação do seu país de nascimento <em>e</em> na cor de seus olhos.</p><p>Agora, podemos encontrar a média da altura dentro de cada um desses pequenos grupos. Teremos um resultado mais específico: média de altura <em>por país e cor dos olhos</em>.</p><p>As instruções <code>GROUP BY</code> são frequentemente usadas para situações onde você utiliza a frase <strong>por </strong>alguma coisa ou <strong>para cada</strong> alguma coisa:</p><ul><li>Média de altura <em>por</em> país</li><li>Número total de pessoas <em>para cada</em> combinação de cor de olhos e cor de cabelo</li><li>Total de vendas <em>por </em>produto</li></ul><h2 id="escrever-instru-es-group-by"><strong>Escrever instruções <code>GROUP BY</code> </strong></h2><p>Uma instrução <code>GROUP BY</code> é muito fácil de escrever — apenas utilizamos a palavra chave <code>GROUP BY</code> e então especificamos os campos que queremos agrupar:</p><pre><code class="language-sql">SELECT ...
FROM vendas
GROUP BY local;</code></pre><p>Esta consulta simples agrupa nossos dados de &nbsp;<code>vendas</code> pela coluna do <code>local</code>.</p><p>Fizemos o agrupamento — mas e agora? O que colocamos em nosso <code>SELECT</code>?</p><p>A coisa mais clara para selecionar é o nosso <code>local</code>— nós agrupamos para que ao menos vejamos o nome dos grupos que fizemos:</p><pre><code class="language-sql">SELECT location
FROM sales
GROUP BY location;
</code></pre><p>O resultado é as nossas três localizações:</p><pre><code>  local
------------
 Rua 1
 Central
 Centro
(3 rows)
</code></pre><p>Se olharmos para a tabela bruta de dados &nbsp;(<code>SELECT * FROM vendas;</code>), veremos que temos 4 linhas com o local Central, duas linhas com o local Centro, e duas linhas com o local Rua 1<em><em>:</em></em></p><pre><code> produto 	|    local 	| preco |          vendido_em
---------+---------+------------+-------+----------------------------
 Cafe    	| Central    	|     2 | 2020-09-01 09:42:33.085995
 Cafe  	 	| Central    	|     2 | 2020-09-01 08:42:33.085995
 Biscoito	| Centro     	|     3 | 2020-09-01 07:42:33.085995
 Cafe  	 	| Centro     	|     2 | 2020-08-31 09:42:33.085995
 Biscoito	| Central    	|     2 | 2020-08-30 09:42:33.085995
 Biscoito	| Rua 1   	|     3 | 2020-08-30 08:42:33.085995
 Cafe  	 	| Rua 1		|     2 | 2020-08-29 09:42:33.085995
 Biscoito	| Central    	|     3 | 2020-08-29 08:42:33.085995
(8 rows)
</code></pre><p>Agrupando na coluna <code>local</code>, nosso banco de dados pega essas linhas de input e identifica locais únicos dentre eles — estes locais únicos servem como nosso <em>"grupo"</em>.</p><p>E quanto às outras colunas da nossa tabela?</p><p>Se tentarmos selecionar a coluna <code>produto</code> que não agrupamos...</p><pre><code class="language-sql">SELECT
  local,
  produto
FROM vendas
GROUP BY local;
</code></pre><p>...receberemos o seguinte erro:</p><pre><code>ERROR:  column "vendas.produto" must appear in the GROUP BY clause or be used in an aggregate function
</code></pre><p>O problema aqui é que pegamos oito linhas e as esprememos ou as transformamos em três<em><em>.</em></em></p><p>Não podemos apenas retornar o resto das colunas como normalmente fazíamos — nós possuíamos oito linhas, e agora temos três.</p><p>O que faremos com as cincos linhas restantes de dados? Quais das oito linhas de dados devem ser mostradas nestas três linhas de locais distintos?</p><p>Não há uma resposta clara e definitiva aqui.</p><p>Para utilizar o resto da nossa tabela de dados, nós também temos de analisar os dados do restante das colunas dentro dos nossos três grupos de local.</p><p>Isto significa que temos de <strong>agregar</strong> ou realizar um cálculo para produzir um tipo de resumo das informações sobre os dados restantes.</p><h2 id="agrega-es-count-sum-avg-"><strong>Agregações (<code>COUNT</code>, <code>SUM</code>, <code>AVG</code>)</strong></h2><p>Uma vez que definimos como agrupar nossos dados, podemos realizar agregações com as colunas restantes.</p><p>São coisas como contar o número de linhas por grupo, somar um valor em específico através do grupo, ou calcular a média das informações dentro do grupo.</p><p>Para começar, vamos encontrar o número de vendas <em>por </em>local.</p><p>Como cada gravação em nossa tabela de <code>vendas</code> é uma venda, o número de vendas por local seria <strong>o número de linhas dentro de cada local do grupo<strong>.</strong></strong></p><p>Para fazer isto, utilizaremos a função de agregação <code>COUNT()</code> para contar o número de linhas de cada grupo:</p><pre><code class="language-sql">SELECT
  local,
  COUNT(*) AS numero_de_vendas
FROM vendas
GROUP BY local;
</code></pre><p>Nós usamos <code>COUNT(*)</code>, que conta todas as linhas de input por grupo (<code>COUNT()</code> também funciona com expressões, mas possui um comportamento levemente diferente).</p><p>Abaixo, vemos como o banco de dados executa esta consulta:</p><ul><li><code>FROM vendas</code> — Primeiro, retornamos todos os dados da tabela <code>vendas</code> </li><li><code>GROUP BY local</code> — Em seguida, determinamos os grupos únicos de <code>local</code></li><li><code>SELECT ...</code> — Finalmente, selecionamos o nome do local e contamos o número de linhas daquele grupo</li></ul><p>Nomearemos a contagem de linhas usando <code>AS numero_de_vendas</code> para fazer uma saída de dados mais legível. Se parecerá com o seguinte:</p><pre><code>   local    | numero_de_vendas
------------+-----------------
 Rua 1      |       2
 Central    |       4
 Centro     |       2
(3 rows)
</code></pre><p>O local Rua 1 possui duas vendas, Central possui quatro, e Centro possui duas.</p><p>Aqui, podemos ver como pegamos as demais colunas de dados das nossas oito linhas independentes e as colocamos em um resumo das informações para cada local: o número de vendas.</p><p>De um jeito similar, ao invés de contar o número de linha em um grupo, podemos somar as informações dentro do grupo — como o dinheiro total ganho nesses locais.</p><p>Para fazer isto, utilizamos a função <code>SUM()</code> :</p><pre><code class="language-sql">SELECT
  local,
  SUM(preco) AS ganho_total
FROM vendas
GROUP BY local;
</code></pre><p>No lugar de contar o número de linhas em cada grupo, somamos o total de ganhos de cada venda. Isto mostra o ganho total por local:</p><pre><code>  local	    | ganho_total
------------+---------------
 Rua 1      |             5
 Central    |             9
 Centro     |             5
(3 rows)
</code></pre><h3 id="m-dia-avg-"><strong>Média (<code>AVG</code>)</strong></h3><p>Encontrar a média do valor de vendas por local significa apenas que trocaremos a função <code>SUM()</code> para a função <code>AVG()</code>:</p><pre><code class="language-sql">SELECT
  local,
  AVG(preco) AS media_de_ganho
FROM vendas
GROUP BY local;
</code></pre><h2 id="trabalhar-com-diversos-grupos"><strong>Trabalhar com diversos grupos</strong></h2><p>Até o momento, temos trabalho apenas com um grupo: local.</p><p>E se quisermos subdividir o grupo ainda mais?</p><p>É semelhante ao cenário "País de nascimento e cor dos olhos" com o qual começamos. E se quiséssemos encontrar o número de vendas <strong>por produto e por local<strong>?</strong></strong></p><p>Para fazermos tudo isso, precisamos adicionar uma segunda condição de agregação ao declararmos o <code>GROUP BY</code> :</p><pre><code class="language-sql">SELECT ...
FROM vendas
GROUP BY local, produto;</code></pre><p>Ao adicionarmos uma segunda coluna <code>GROUP BY</code>, nós subdividimos ainda mais o nosso grupo de locais em grupo de locais por produto.</p><p>Agora que estamos agrupando também pela coluna <code>produto</code>, podemos retornar ao nosso <code>SELECT</code> (adicionarei a instrução <code>ORDER BY</code> nestas consultas para facilitar a leitura dos dados de saída.)</p><pre><code class="language-sql">SELECT
  local,
  produto
FROM vendas
GROUP BY local, produto
ORDER BY local, produto;
</code></pre><p>Olhando para o resultado de nosso novo agrupamento, podemos ver nossas combinações únicas de local/produto:</p><pre><code>  local     | produto
------------+---------
 Rua 1      | Biscoito
 Rua 1      | Café
 Centro     | Biscoito
 Centro     | Café
 Central    | Biscoito
 Central    | Café
(6 rows)
</code></pre><p>Agora que temos nossos grupos, o que queremos fazer com o resto das nossas colunas de dados?</p><p>Bem, podemos encontrar o número de vendas por produto e por local utilizando a mesma função de agregação utilizada antes:</p><pre><code class="language-sql">SELECT
  local,
  produto,
  COUNT(*) AS numero_de_vendas
FROM vendas
GROUP BY local, produto
ORDER BY local, produto;
</code></pre><pre><code>  local  | produto    | numero_de_vendas
------------+---------+-----------------
 Rua 1   | Biscoito   |               1
 Rua 1   | Café       |               1
 Centro  | Biscoito   |               1
 Centro  | Café       |               1
 Central | Biscoito   |               2
 Central | Café       |               2
(6 rows)
</code></pre><blockquote>Como exercício para o leitor<em><em>™:</em> encontre o total de ganhos (soma) de cada produto por local</em>.</blockquote><h2 id="utilizar-fun-es-dentro-do-group-by"><strong>Utilizar funções dentro do <code>GROUP BY</code></strong></h2><p>Agora, tentaremos achar o número total de vendas <strong>por dia</strong>.</p><p>Se seguirmos padrões similares como fizemos com os nossos locais e agrupamos pela nossa coluna <code>vendido_em</code>...</p><pre><code class="language-sql">SELECT
  vendido_em,
  COUNT(*) AS vendas_por_dia
FROM vendas
GROUP BY vendido_em
ORDER BY vendido_em;
</code></pre><p>...esperamos que o resultado seja ter cada grupo em um único dia— no entanto, temos isso:</p><pre><code>          vendido_em        | vendas_por_dia
----------------------------+---------------
 2020-08-29 08:42:33.085995 |             1
 2020-08-29 09:42:33.085995 |             1
 2020-08-30 08:42:33.085995 |             1
 2020-08-30 09:42:33.085995 |             1
 2020-08-31 09:42:33.085995 |             1
 2020-09-01 07:42:33.085995 |             1
 2020-09-01 08:42:33.085995 |             1
 2020-09-01 09:42:33.085995 |             1
(8 rows)
</code></pre><p>Parece que nossos dados não estão agrupados — temos cada linha individualmente.</p><p>Nossos dados, no entanto, estão agrupados! O problema é que cada linha de <code>vendido_em</code> possui um valor único — então, nossas linhas são seus próprios grupos!</p><p>O <code>GROUP BY</code> está funcionando corretamente, mas não é a saída que queremos.</p><p>O que ocasiona esta situação é a informação extra do carimbo de data e hora.</p><p>Cada um destes carimbos se diferenciam por horas, minutos ou segundos — assim, eles são colocados em seu devido lugar em seu próprio grupo.</p><p>Precisamos converter cada um dos valores de data e hora para apenas data:</p><ul><li><code>2020-09-01 08:42:33.085995</code> =&gt; <code>2020-09-01</code></li><li><code>2020-09-01 09:42:33.085995</code> =&gt; <code>2020-09-01</code></li></ul><p>Convertido para uma data, todos os carimbos do mesmo dia retornarão apenas a referência do valor da data em que foi efetuada a compra—e será colocado dentro do mesmo grupo.</p><p>Para fazermos isso, converteremos os dados de <code>vendido_em</code> para data:</p><pre><code class="language-sql">SELECT
  vendido_em::DATE AS date,
  COUNT(*) AS vendas_por_dia
FROM vendas
GROUP BY vendido_em::DATE
ORDER BY vendido_em::DATE;
</code></pre><p>Em nossa instrução <code>GROUP BY</code>, utilizamos <code>::DATE</code> para cortar uma parte do carimbo de data/hora para apenas dia. Isto corta efetivamente as horas/minutos/segundos do carimbo e retorna apenas o dia.</p><p>No nosso <code>SELECT</code>, retornamos a mesma expressão e damos a ela um nome para deixar o resultado mais bonito.</p><p>Pela mesma razão, não podemos retornar o <code>produto</code> sem agrupar ou realizar algum tipo de agrupamento. O banco de dados não deixará retornar apenas o <code>vendido_em</code> — tudo que está no <code>SELECT</code> deve estar dentro do <code>GROUP BY</code> ou em algum tipo de agregação nos grupos resultantes.</p><p>O resultado de vendas por dia que originalmente queríamos ver:</p><pre><code class="language-sql">    date    | vendas_por_dia
------------+---------------
 2020-08-29 |             2
 2020-08-30 |             2
 2020-08-31 |             1
 2020-09-01 |             3
(4 rows)
</code></pre><h2 id="filtrar-grupos-com-having"><strong>Filtrar grupos com <code>HAVING</code></strong></h2><p>Dando continuidade, vamos verificar como filtrar nossas linhas agrupadas.</p><p>Para fazer isso, vamos tentar encontrar dias onde houve <em>mais</em> de uma venda<em><em>.</em></em></p><p>Sem agrupar, normalmente filtraríamos nossas linhas utilizando a instrução. Por exemplo:</p><pre><code class="language-sql">SELECT *
FROM vendas
WHERE produto = 'Café';
</code></pre><p>Com nossos grupos, utilizaremos algo parecido com isso para filtrá-los com base na quantidade de linhas...</p><pre><code class="language-sql">SELECT
  vendido_em::DATE AS date,
  COUNT(*) AS vendas_por_dia
FROM vendas
WHERE COUNT(*) &gt; 1      -- filtrar os grupos?
GROUP BY vendido_em::DATE;
</code></pre><p>Infelizmente, isso não funciona e recebemos este erro:</p><p><code>ERROR: &nbsp;aggregate functions are not allowed in WHERE</code></p><p>Funções agregadas não são permitidas dentro da instrução <code>WHERE</code>, pois ela é avaliada <strong>antes </strong>da instrução <code>GROUP BY</code>—não há nenhum grupo para realizar os cálculos.</p><p>Existe, contudo, um tipo de instrução que nos permite filtrar e realizar agregações. Ela é avaliada depois da instrução <code>GROUP BY</code>: a instrução <code>HAVING</code>.</p><p><strong>A instrução <strong><code>HAVING</code> </strong>é como a instrução<strong> <code>WHERE</code> </strong>para os seus grupos<strong>.</strong></strong></p><p>Para encontrar os dias em que houve mais de uma venda, adicionamos a instrução <code>HAVING</code> que verificará a quantidade de linhas dentro do grupo:</p><pre><code class="language-sql">SELECT
  vendido_em::DATE AS date,
  COUNT(*) AS vendas_por_dia
FROM sales
GROUP BY vendido_em::DATE
HAVING COUNT(*) &gt; 1;
</code></pre><p>A instrução <code>HAVING</code> filtra qualquer linha onde a contagem de linhas deste grupo não é maior que um. Vemos isso no nosso resultado:</p><pre><code>    date    | vendas_por_dia
------------+---------------
 2020-09-01 |             3
 2020-08-29 |             2
 2020-08-30 |             2
(3 rows)
</code></pre><p>Apenas para deixar completo, segue em ordem a execução de todas as partes de uma instrução SQL:</p><ul><li><code>FROM</code> — Retorna todas as linhas da tabela <code>FROM</code> </li><li><code>JOIN</code> — Realiza quaisquer junções</li><li><code>WHERE</code> — Filtra linhas</li><li><code>GROUP BY</code> — Forma grupos</li><li><code>HAVING</code> — Filtra grupos</li><li><code>SELECT</code> — Seleciona os dados a serem retornados</li><li><code>ORDER BY</code> — Ordena a saída de linhas</li><li><code>LIMIT</code> — Retorna uma certa quantidade de linhas</li></ul><h2 id="agrega-es-com-agrupamentos-impl-citos"><strong>Agregações com agrupamentos implícitos</strong></h2><p>O último tópico que veremos é a agregação que pode ser realizada sem o <code>GROUP BY</code>— ou, melhor dizendo, que possui um agrupamento implícito<em><em>.</em></em></p><p>Estas agregações são úteis em cenários em que você quer encontrar um agrupamento específico dentro de uma tabela — como o total de ganhos ou o maior ou menor valor da coluna.</p><p>Por exemplo, podemos encontrar o total de ganhos de todos os locais selecionando a soma da tabela inteira:</p><pre><code class="language-sql">SELECT SUM(preco)
FROM vendas;
</code></pre><pre><code> sum
-----
  19
(1 row)
</code></pre><p>Até o momento fizemos $19 de vendas em todos os locais (<em>vivaaaaa<em>!</em></em>).</p><p>Outra coisa útil que podemos consultar é o primeiro ou o último valor de algo.</p><p>Por exemplo, qual a data da nossa primeira venda?</p><p>Para encontrá-la, basta utilizarmos a função &nbsp;<code>MIN()</code>:</p><pre><code class="language-sql">SELECT MIN(vendido_em)::DATE AS primeira_venda
FROM vendas;
</code></pre><pre><code> primeira_venda
------------
 2020-08-29
(1 row)
</code></pre><p>(Para encontrar a data da última venda, bastar substituir <code>MIN()</code> por <code>MAX()</code>.)</p><h3 id="como-usar-min-max"><strong>Como usar <code>MIN</code> / <code>MAX</code></strong></h3><p>Embora essas consultas simples possam ser utilizadas em consultas independentes, elas são frequentemente parte de filtros de consultas maiores.</p><p>Por exemplo, vamos tentar encontrar o total de vendas do último dia em que tivemos vendas.</p><p>Um jeito de podermos escrever esta consulta seria o seguinte:</p><pre><code class="language-sql">SELECT
  SUM(preco)
FROM vendas
WHERE vendido_em::DATE = '2020-09-01';
</code></pre><p>Esta consulta funciona, mas obviamente codificando a data de <code>2020-09-01</code>.</p><p><em><em>09/01/2020</em></em> talvez seja o último dia em que tivemos uma venda, mas nem sempre será essa data. Precisamos de uma solução dinâmica.</p><p>Conseguimos isto através da combinação desta consulta com a função <code>MAX()</code> em uma subconsulta:</p><pre><code class="language-sql">SELECT
  SUM(preco)
FROM venda
WHERE vendido_em::DATE = (
  SELECT MAX(vendido_em::DATE)
  FROM vendas
);
</code></pre><p>Na nossa instrução <code>WHERE</code>, encontramos a data mais antiga dentro da tabela utilizando a subconsulta: <code>SELECT MAX(vendido_em::DATE) FROM vendas</code>.</p><p>Então, utilizamos esta "data máxima" como um valor para filtrar a tabela, e somamos cada uma das vendas.</p><h3 id="agrupamento-impl-cito">Agrupamento implícito</h3><p>Chamamos de agrupamento implícito, pois, se tentarmos selecionar e agregar &nbsp;o valor com uma coluna não agregada dessa forma...</p><pre><code class="language-sql">SELECT
  SUM(preco),
  local
FROM vendas;
</code></pre><p>...teremos um erro familiar:</p><pre><code>ERROR:  column "vendas.local" must appear in the GROUP BY clause or be used in an aggregate function
</code></pre><h2 id="group-by-uma-ferramenta"><strong><code>GROUP BY</code> é uma ferramenta</strong></h2><p>Como muitos dos tópicos em desenvolvimento de software, <code>GROUP BY</code> é uma ferramenta.</p><p>Existem várias maneiras de escrever e reescrever estas consultas utilizando a combinação de &nbsp;<code>GROUP BY</code>, funções agregadas ou outras ferramentas como &nbsp;<code>DISTINCT</code>, <code>ORDER BY</code> e <code>LIMIT</code>.</p><p>Entender e trabalhar com o <code>GROUP BY</code> requer um pouco de pratica, mas ao aprender, você descobrirá um conjunto inteiramente novo de problemas que você poderá resolver!</p><p>Se gostou deste post, você pode seguir o autor deste artigo no Twitter, onde ele fala sobre banco de dados e sobre como ter sucesso na carreira como desenvolvedor.</p><p>Obrigado pela leitura!</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
