{"id":18357747,"url":"https://github.com/andreadcsousa/alura_postgresql-introducao_sql","last_synced_at":"2025-10-11T07:40:17.599Z","repository":{"id":168043345,"uuid":"610393155","full_name":"andreadcsousa/alura_postgresql-introducao_sql","owner":"andreadcsousa","description":"Este projeto faz parte do plano de estudos elaborado pela Alura para o programa de formação Desenvolve (3ª edição), trilha de dados, em parceria com a Boticário.","archived":false,"fork":false,"pushed_at":"2023-03-06T17:26:00.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-10T02:56:50.475Z","etag":null,"topics":["alura","aprendendo","boticario","dados","desenvolve-2023","desenvolve-3-edicao","postgresql","sql"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andreadcsousa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-06T17:23:29.000Z","updated_at":"2023-03-06T17:24:41.000Z","dependencies_parsed_at":"2023-07-16T12:45:11.894Z","dependency_job_id":null,"html_url":"https://github.com/andreadcsousa/alura_postgresql-introducao_sql","commit_stats":null,"previous_names":["andreadcsousa/alura_postgresql-introducao_sql"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/andreadcsousa/alura_postgresql-introducao_sql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreadcsousa%2Falura_postgresql-introducao_sql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreadcsousa%2Falura_postgresql-introducao_sql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreadcsousa%2Falura_postgresql-introducao_sql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreadcsousa%2Falura_postgresql-introducao_sql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andreadcsousa","download_url":"https://codeload.github.com/andreadcsousa/alura_postgresql-introducao_sql/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andreadcsousa%2Falura_postgresql-introducao_sql/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279006626,"owners_count":26084131,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-11T02:00:06.511Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alura","aprendendo","boticario","dados","desenvolve-2023","desenvolve-3-edicao","postgresql","sql"],"created_at":"2024-11-05T22:15:20.858Z","updated_at":"2025-10-11T07:40:17.585Z","avatar_url":"https://github.com/andreadcsousa.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# PostgreSQL\n\nCriando a estrutura de uma tabela; realizando consultas; adicionando dados no banco; atualizando e apagando dados; filtrando os registros; ordenando os dados; e juntando registros de tabelas.\n\n1. [Primeiros passos com PostgreSQL](#1-primeiros-passos-com-postgresql)\n2. [Executando operações CRUD](#2-executando-operações-crud)\n3. [Consultas com filtros](#3-consultas-com-filtros)\n4. [Trabalhando com relacionamentos](#4-trabalhando-com-relacionamentos)\n5. [Usando CASCADE](#5-usando-cascade)\n6. [Avançando com consultas](#6-avançando-com-consultas)\n\nSaiba mais sobre o curso [aqui](https://cursos.alura.com.br/course/introducao-postgresql-primeiros-passos) ou acompanhe minhas anotações abaixo. ⬇️\n\n## 1. Primeiros passos com PostgreSQL\n\n### **Criando um banco de dados**\n\n***SGBD utilizado no curso: [PostgreSQL](https://www.postgresql.org/)***\n\nPara criar um banco de dados no PostgreSQL, basta utilizar um dos códigos abaixo:\n\n```sql\nCREATE DATABASE alura;\n\nCREATE DATABASE alura\n    WITH\n    OWNER = postgres\n    ENCODING = 'UTF8'\n    CONNECTION LIMIT = -1;\n```\n\nJá para excluir um banco de dados, utiliza-se o `DROP DATABASE alura;`.\n\n### **Criando uma tabela**\n\nAntes de criar uma tabela, adicionando suas colunas, é necessário saber que tipos de dados elas receberão. Na documentação do PostgreSQL existe uma lista com principais tipo de dados que as colunas das tabelas recebem. Veja a lista [aqui](https://www.postgresql.org/docs/current/datatype.html) e os tipos mais comuns com suas características, logo abaixo:\n\nTipo      | Descrição\n--------- | -------------------------------\ninteger   | números inteiros\nserial    | números inteiros com incremento\nreal      | números decimais fixos\nnumeric   | números decimais variáveis\nchar      | textos fixos\nvarchar   | textos variáveis\ntext      | textos longos\nboolean   | verdadeiro ou falso\ndate      | data do calendário\ntime      | hora do dia\ntimestamp | data e hora\n\n```sql\nCREATE TABLE aluno (\n\tid SERIAL,\n\tnome VARCHAR(255),\n\tcpf CHAR(11),\n\tobservacao TEXT,\n\tidade INTEGER,\n\tdinheiro NUMERIC(10,2),\n\taltura REAL,\n\tativo BOOLEAN,\n\tdata_nascimento DATE,\n\thora_aula TIME,\n\tmatricula TIMESTAMP\n);\n```\n\nApós criar a tabela é possível visualizá-la com o comando `SELECT * FROM aluno;`. Mesmo que ainda sem dados inseridos, pode-se visualizar as colunas criadas.\n\n## 2. Executando operações CRUD\n\n### **Incluindo um registro na tabela**\n\nO comando `INSERT INTO ... VALUES (...)` insere dados na tabela. Isso pode ser feito declarando as colunas e seus respectivos valores ou apenas declarando os valores na ordem em que aparecem na tabela.\n\n```sql\nINSERT INTO aluno (\n    nome,\n    cpf,\n    observacao,\n    idade,\n    dinheiro,\n    altura,\n    ativo,\n    data_nascimento,\n    hora_aula,\n    matricula\n) VALUES (\n    'Diogo',\n    '12345678901',\n    'Mussum Ipsum, cacilds vidis litro abertis. Quem manda na minha terra sou euzis!Nec orci ornare consequat. Praesent lacinia ultrices consectetur. Sed non ipsum felis.Admodum accumsan disputationi eu sit. Vide electram sadipscing et per.Em pé sem cair, deitado sem dormir, sentado sem cochilar e fazendo pose.',\n    35,\n    100.50,\n    1.81,\n    TRUE,\n    '1984-08-27',\n    '17:30:00',\n    '2020-02-08 12:32:45'\n);\n```\n\n### **Atualizando um registro na tabela**\n\nA atualização serve para modificar os valores de uma linha e recebe o comando `UPDATE ... SET ... WHERE ...`. No caso abaixo, todos os dados foram alterados, mas poderia ser apenas um. Importante indicar que registro da tabela será alterado.\n\n```sql\nUPDATE aluno SET\n    nome = 'Nico',\n    cpf = '10987654321',\n    observacao = 'Teste',\n    idade = 38,\n    dinheiro = 15.23,\n    altura = 1.90,\n    ativo = FALSE,\n    data_nascimento = '1980-01-15',\n    hora_aula = '13:00:00',\n    matricula = '2020-01-02 15:00:00'\nWHERE id = 1;\n```\n\n### **Excluindo um registro da tabela**\n\nNo caso de querer excluir um registro, pode-se usar o comando `DELETE FROM ... WHERE ...`, sendo imprescindível indicar que registro será deletado, pois sem o where, todos os registros serão excluídos.\n\n```sql\nDELETE FROM aluno WHERE nome = 'Nico';\n```\n\n## 3. Consultas com filtros\n\n### **Selecionando colunas específicas da tabela**\n\nAlém de consultar todos os registros de uma tabela, é possível selecionar que campos retornar na consulta. Basta indicar o nome da coluna no lugar do asterisco.\n\n```sql\n-- Consultando 1 campo específico\nSELECT nome FROM aluno;\n\n-- Consultando 2 e 3 campos\nSELECT nome, idade FROM aluno;\nSELECT nome, idade, matricula FROM aluno;\n\n-- Consultando e renomeando campos\nSELECT\n\tnome \"Nome do aluno\",\n\tidade,\n\tmatricula AS quando_se_matriculou\nFROM aluno;\n```\n\nNo último exemplo acima foram utilizadas duas formas de renomear as colunas de uma tabela, ao realizar uma consulta. Quando colocado entre aspas duplas, pode-se dar espaço entre as palavras. Caso não use as aspas, deve-se unir as palavras com underscore. O comando `AS` é responsável pela ação de renomear.\n\nPs. O nome dos campos na tabela permanece o mesmo, apenas o nome da coluna na consulta será alterado.\n\n### **Filtrando registros de campos do tipo texto**\n\nO filtro `WHERE` pode ser utilizado de diversas formas. Pode-se usar tanto operadores quanto outros comandos para complementar a consulta.\n\n```sql\n-- Inserindo mais registros na tabela para trabalhar tais consultas\nINSERT INTO aluno (nome) VALUES ('Vinicius Dias');\nINSERT INTO aluno (nome) VALUES ('Nico Steppat');\nINSERT INTO aluno (nome) VALUES ('João Roberto');\nINSERT INTO aluno (nome) VALUES ('Diego');\n\n-- Filtrando nomes com operadores\nSELECT * FROM aluno WHERE nome = 'Diogo';   -- igual\nSELECT * FROM aluno WHERE nome != 'Diogo';  -- diferente\nSELECT * FROM aluno WHERE nome \u003c\u003e 'Diogo';  -- diferente também\n\n-- Filtrando nomes com like\nSELECT * FROM aluno WHERE nome LIKE 'Diogo';     -- semelhante a\nSELECT * FROM aluno WHERE nome NOT LIKE 'Diogo'; -- diferente de\n\n-- Filtrando nomes complementos do like\nSELECT * FROM aluno WHERE nome LIKE 'Di_go';    -- qualquer letra onde está o underscore\nSELECT * FROM aluno WHERE nome LIKE 'D%';       -- qualquer nome que comece com D\nSELECT * FROM aluno WHERE nome LIKE '%s';       -- qualquer nome que termine com s\nSELECT * FROM aluno WHERE nome LIKE '% %';      -- qualquer nome que contenha espaço\nSELECT * FROM aluno WHERE nome LIKE '%i%a%';    -- quando nome que possua i e a em quaquer posição\n```\n\n### **Filtrando registros de campos do tipo numérico, data e booleano**\n\nQuando um registro é inserido com valores nulos, ou seja, não é inserido determinado campo do registro e ele fica em branco, pode-se consultar esses valores ou o inverso filtrando da seguinte forma:\n\n    SELECT * FROM aluno WHERE cpf IS NULL;\n    SELECT * FROM aluno WHERE cpf IS NOT NULL;\n\nNo caso de consultas com registros de outros tipos que não texto, pode ser utilizar outros operadores e comandos para realizar a consulta como, por exemplo, maior e menor que, e verdadeiro ou falso.\n\n```sql\n-- Filtrando se existe valor igual, maior, menor ou diferente do valor da consulta\nSELECT * FROM aluno WHERE nome = 35;\nSELECT * FROM aluno WHERE nome \u003c\u003e 35;\nSELECT * FROM aluno WHERE nome != 35;\nSELECT * FROM aluno WHERE nome \u003e= 35;\nSELECT * FROM aluno WHERE nome \u003c= 35;\nSELECT * FROM aluno WHERE nome \u003e 35;\nSELECT * FROM aluno WHERE nome \u003c 35;\n\n-- Filtrando uma faixa de valores\nSELECT * FROM aluno WHERE nome BETWEEN 30 AND 40;\n\n-- Filtrando se o registro é verdadeiro ou falso\nSELECT * FROM aluno WHERE ativo = TRUE;\nSELECT * FROM aluno WHERE ativo = FALSE;\n\n-- Filtrando se existe tal registro no campo\nSELECT * FROM aluno WHERE ativo IS NULL;\n```\n\n### **Filtrando utilizando operadores E e OU**\n\nOs operadores E e OU servem para comparar registros ao realizar consultas. Eles funcionam como a tabela verdade e para cada comparação, trazem um resultado diferente.\n\n```sql\n-- O nome precisa começar com D e o CPF não pode ser nulo\nSELECT * FROM aluno WHERE\n    nome LIKE 'D%' AND\n    cpf IS NOT NULL;\n\n-- Vai trazer um registro ou outro, se ambos estiverem, traz o que aparecer primeiro\nSELECT * FROM aluno WHERE\n\tnome LIKE 'Diogo' OR\n\tnome LIKE 'Rodrigo';\n\n-- Traz registros que contenham as duas cláusulas\nSELECT * FROM aluno WHERE\n\tnome LIKE 'Nico' AND\n\tnome LIKE 'Steppat';\n```\n\n***Conjunção (E) na tabela verdade:***\n\nA     | B     | A^B\n:---: | :---: | :---:\nV     | V     | V\nV     | F     | F\nF     | V     | F\nF     | F     | F\n\n***Disjunção (OU) na tabela verdade:***\n\nA     | B     | AvB\n:---: | :---: | :---:\nV     | V     | V\nV     | F     | V\nF     | V     | V\nF     | F     | F\n\n## 4. Trabalhando com relacionamentos\n\n### **Criando tabela com chave primária**\n\nAo criar uma tabela e definir seus campos, alguns comandos podem ser atribuídos às colunas para adicionar características que diferenciem os registros da tabela.\n\n```sql\n-- Criando uma tabela e inserindo dados nulos\nCREATE TABLE curso (\n\tid INTEGER,\n\tnome VARCHAR(255)\n);\n\nINSERT INTO curso (id, nome) VALUES (NULL, NULL);\n\nSELECT * FROM curso;\n\n-- Recriando a tabela, impedindo inserção de dados nulos\nDROP TABLE curso;\n\nCREATE TABLE curso (\n\tid INTEGER NOT NULL,\n\tnome VARCHAR(255) NOT NULL\n);\n\nINSERT INTO curso (id, nome) VALUES (1, 'HTML');\nINSERT INTO curso (id, nome) VALUES (1, 'CSS');\n\nSELECT * FROM curso;\n\n-- Definindo o campo id como único, impedindo repetição\nDROP TABLE curso;\n\nCREATE TABLE curso (\n\tid INTEGER NOT NULL UNIQUE,\n\tnome VARCHAR(255) NOT NULL\n);\n\nINSERT INTO curso (id, nome) VALUES (1, 'HTML');\nINSERT INTO curso (id, nome) VALUES (2, 'CSS');\nINSERT INTO curso (id, nome) VALUES (3, 'JavaScript');\n\nSELECT * FROM curso;\n\n-- Definindo o campo id como chave primária\nDROP TABLE curso;\n\nCREATE TABLE curso (\n\tid INTEGER NOT NULL PRIMARY KEY,\n\tnome VARCHAR(255) NOT NULL\n);\n\nINSERT INTO curso (id, nome) VALUES (1, 'HTML');\nINSERT INTO curso (id, nome) VALUES (2, 'CSS');\nINSERT INTO curso (id, nome) VALUES (3, 'JavaScript');\n\nSELECT * FROM curso;\n```\n\nA chave primária serve para relacionar uma tabela com outra, o campo que recebe a chave primária será o conector dos registros. Podendo, assim, relacionar a tabela aluno com a tabela curso.\n\n### **Criando tabela com chave estrangeira**\n\nA chave estrangeira serve para extender a ligação entre tabelas. A chave primária de uma tabela é utilizada em outra tabela para referenciar um registro.\n\n```sql\n-- Recriando a tabela aluno com chave primária\nDROP TABLE aluno;\n\nCREATE TABLE aluno (\n\tid SERIAL PRIMARY KEY,\n\tnome VARCHAR(255) NOT NULL\n);\n\nINSERT INTO aluno (nome) VALUES ('Diogo');\nINSERT INTO aluno (nome) VALUES ('Vinicius');\n\n-- Criando uma tabela que relaciona cursos com alunos\nCREATE TABLE aluno_curso (\n\taluno_id INTEGER,\n\tcurso_id INTEGER,\n\tPRIMARY KEY (aluno_id, curso_id)\n);\n\nINSERT INTO aluno_curso (aluno_id, curso_id) VALUES (1,1);\nINSERT INTO aluno_curso (aluno_id, curso_id) VALUES (2,1);\n\nSELECT * FROM aluno WHERE id = 1;\nSELECT * FROM aluno WHERE id = 2;\nSELECT * FROM curso WHERE id = 1;\n\n-- Recriando a tabela, adicionando chaves estrangeiras\nDROP TABLE aluno_curso;\n\nCREATE TABLE aluno_curso (\n\taluno_id INTEGER,\n\tcurso_id INTEGER,\n\tPRIMARY KEY (aluno_id, curso_id),\n\t\n\tFOREIGN KEY (aluno_id) REFERENCES aluno (id),\n\tFOREIGN KEY (curso_id) REFERENCES curso (id)\n);\n\nINSERT INTO aluno_curso (aluno_id, curso_id) VALUES (1,1);\nINSERT INTO aluno_curso (aluno_id, curso_id) VALUES (2,1);\n\n-- Se não existe o aluno 3 na tabela aluno, retorna erro\nINSERT INTO aluno_curso (aluno_id, curso_id) VALUES (3,1);\n```\n\n### **Consultas com relacionamentos**\n\nAs consultas com relacinamento são feitas a partir do comando `JOIN ... ON ...`. Ele serve para unir os registros de uma tabela e criar relatórios mais precisos com os dados obtidos.\n\n```sql\n-- Inserindo um aluno existente em outro curso\nINSERT INTO aluno_curso (aluno_id, curso_id) VALUES (2,2);\n\n-- Consultando registros com a união das tabelas existentes\nSELECT\n\taluno.nome as \"Nome do aluno\",\n\tcurso.nome as \"Nome do curso\"\nFROM aluno\nJOIN aluno_curso\n\tON aluno_curso.aluno_id = aluno.id\nJOIN curso\n\tON curso.id = aluno_curso.curso_id;\n```\n\n### **Left, Right, Cross e Full joins**\n\nOutros tipos de junções trazem resultados diferentes nas consultas. Eles são utilizados quando se quer dados mais precisos ou quando se quer filtrar registros específicos.\n\n```sql\n-- Pega o nome dos alunos e os cursos que eles fazem ou se não fazem\nSELECT aluno.nome as \"Nome do aluno\", curso.nome as \"Nome do curso\"\nFROM aluno\nLEFT JOIN aluno_curso ON aluno_curso.aluno_id = aluno.id\nLEFT JOIN curso ON curso.id = aluno_curso.curso_id;\n\n-- Pega os cursos e mostra os alunos que fazem cada um\nSELECT aluno.nome as \"Nome do aluno\", curso.nome as \"Nome do curso\"\nFROM aluno\nRIGHT JOIN aluno_curso ON aluno_curso.aluno_id = aluno.id\nRIGHT JOIN curso ON curso.id = aluno_curso.curso_id;\n\n-- Pega tudo, ambos alunos e cursos\nSELECT aluno.nome as \"Nome do aluno\", curso.nome as \"Nome do curso\"\nFROM aluno\nFULL JOIN aluno_curso ON aluno_curso.aluno_id = aluno.id\nFULL JOIN curso ON curso.id = aluno_curso.curso_id;\n\n-- Mostra todas as possibilidades de cursos que cada um pode fazer\nSELECT aluno.nome as \"Nome do aluno\", curso.nome as \"Nome do curso\"\nFROM aluno\nCROSS JOIN curso;\n```\n\n## 5. Usando CASCADE\n\n### **DELETE CASCADE**\n\nO cascade altera a forma de trabalhar as chaves estrangeiras de modo que seja possível deletar registros de ambas as tabelas pela chave primária. No modo restrito isso não é possível, pois não se consegue excluir apenas de uma tabela, retornando erro.\n\n```sql\nDROP TABLE aluno_curso;\n\nCREATE TABLE aluno_curso (\n\taluno_id INTEGER,\n\tcurso_id INTEGER,\n\tPRIMARY KEY (aluno_id, curso_id),\n\t\n\tFOREIGN KEY (aluno_id) REFERENCES aluno (id) ON DELETE CASCADE,\n\tFOREIGN KEY (curso_id) REFERENCES curso (id) ON DELETE CASCADE\n);\n\nINSERT INTO aluno_curso (aluno_id, curso_id) VALUES (1,1);\nINSERT INTO aluno_curso (aluno_id, curso_id) VALUES (2,1);\nINSERT INTO aluno_curso (aluno_id, curso_id) VALUES (3,1);\nINSERT INTO aluno_curso (aluno_id, curso_id) VALUES (1,3);\n\nSELECT * FROM aluno_curso;\n\nDELETE FROM aluno WHERE id = 1;\n\nSELECT\n\taluno.nome as \"Nome do aluno\",\n\tcurso.nome as \"Nome do curso\"\nFROM aluno\nJOIN aluno_curso\n\tON aluno_curso.aluno_id = aluno.id\nJOIN curso\n\tON curso.id = aluno_curso.curso_id;\n```\n\n### **UPDATE CASCADE**\n\nAssim como no delete cascade, o update cascade reflete as alterações de uma tabela em outra que esteja relacionada pela chave estrangeira.\n\n```sql\nDROP TABLE aluno_curso;\n\nCREATE TABLE aluno_curso (\n\taluno_id INTEGER,\n\tcurso_id INTEGER,\n\tPRIMARY KEY (aluno_id, curso_id),\n\t\n\tFOREIGN KEY (aluno_id) REFERENCES aluno (id)\n\tON DELETE CASCADE\n\tON UPDATE CASCADE,\n\t\n\tFOREIGN KEY (curso_id) REFERENCES curso (id)\n\tON DELETE CASCADE\n\tON UPDATE CASCADE\n);\n\nINSERT INTO aluno_curso (aluno_id, curso_id) VALUES (2,1);\nINSERT INTO aluno_curso (aluno_id, curso_id) VALUES (3,1);\n\nSELECT * FROM aluno_curso;\n\nSELECT\n\taluno.id AS \"ID do aluno\",\n\taluno.nome AS \"Nome do aluno\",\n\tcurso.id AS \"ID do curso\",\n\tcurso.nome AS \"Nome do curso\"\nFROM aluno\nJOIN aluno_curso\n\tON aluno_curso.aluno_id = aluno.id\nJOIN curso\n\tON curso.id = aluno_curso.curso_id;\n\nUPDATE aluno SET id = 10 WHERE id = 2;\n```\n\n## 6. Avançando com consultas\n\n### **Ordenando as consultas**\n\nO comando `ORDER BY ...` organiza os registros em ordem ascendente ou descendente e de acordo com o nome ou posição da coluna. Além disso, ordena também de acordo com a tabela, caso haja junção entre duas ou mais tabelas na consulta em questão. Sendo possível, também, ordernar o registro de várias colunas.\n\n```sql\nCREATE TABLE funcionario (\n\tid SERIAL PRIMARY KEY,\n\tmatricula VARCHAR(10),\n\tnome VARCHAR(255),\n\tsobrenome VARCHAR(255)\n);\n\nINSERT INTO funcionario (matricula, nome, sobrenome) VALUES ('M001', 'Diogo', 'Mascarenhas');\nINSERT INTO funcionario (matricula, nome, sobrenome) VALUES ('M002', 'Vinícius', 'Dias');\nINSERT INTO funcionario (matricula, nome, sobrenome) VALUES ('M003', 'Nico', 'Steppat');\nINSERT INTO funcionario (matricula, nome, sobrenome) VALUES ('M004', 'João', 'Roberto');\nINSERT INTO funcionario (matricula, nome, sobrenome) VALUES ('M005', 'Diogo', 'Mascarenhas');\nINSERT INTO funcionario (matricula, nome, sobrenome) VALUES ('M006', 'Alberto', 'Martins');\n\n-- Ordenando pelo nome da coluna\nSELECT * FROM funcionario ORDER BY nome;\nSELECT * FROM funcionario ORDER BY nome DESC;\nSELECT * FROM funcionario ORDER BY nome, matricula;\n\n-- Ordenando pela posição da coluna\nSELECT * FROM funcionario ORDER BY 4;\nSELECT * FROM funcionario ORDER BY 3, 4, 2;\n\n-- Mesclando a ordenação\nSELECT * FROM funcionario ORDER BY 4 DESC, nome DESC, 2 ASC;\n\n-- Ordenando de acordo com a tabela\nSELECT * FROM funcionario ORDER BY funcionario.nome;\n```\n\n### **Limitando as consultas**\n\nÉ possível limitar uma consulta e existem várias formas para isso. O comando `LIMIT` é uma delas, ele traz a quantidade de registros indicados e nada mais que isso. É possível ainda combinar ele com o comando `OFFSET` para determinar que ponto esse limite irá começar a contar.\n\n```sql\n-- Traz todos os registros ordenado pela coluna nome\nSELECT * FROM funcionario ORDER BY nome;\n\n-- Traz apenas os 5 primeiros registros ordernados por nome\nSELECT * FROM funcionario ORDER BY nome LIMIT 5;\n\n-- Traz 5 registros ordenados por nome a partir da posição 0 e da posição 3\nSELECT * FROM funcionario ORDER BY id LIMIT 5 OFFSET 0;\nSELECT * FROM funcionario ORDER BY id LIMIT 5 OFFSET 3;\n```\n\n### **Funções de agregação**\n\nAs funções de agregação realizam operações que agrupam dados nas consultas para trazer valores específicos nos registros.\n\n- `COUNT` Retorna a quantidade de registros\n- `SUM` Retorna a soma dos registros\n- `MAX` Retorna o maior valor dos registros\n- `MIN` Retorna o menor valor dos registros\n- `AVG` Retorna a média dos registros\n\n```sql\nSELECT\n\tCOUNT(id),\n\tSUM(id),\n\tMAX(id),\n\tMIN(id),\n\tAVG(id),\n\tROUND(AVG(id),2),\n\tROUND(AVG(id),0)\nFROM funcionario;\n```\n\nO comando `ROUND` arredonda um valor que está retornando uma dízima periódica para quantas casas decimais for definida em seu uso. Podendo retornar, inclusive, um número inteiro no registro.\n\nOutras funções de agregação podem ser vistas [aqui](https://www.postgresql.org/docs/12/functions-aggregate.html).\n\n### **Agrupando consultas**\n\nÉ possível agrupar o registros de uma consulta de duas formas. A primeira é trazendo valores distintos, a segundo é agrupando pela coluna.\n\n```sql\n-- O distinct traz valores repetidos em um único registro\nSELECT DISTINCT nome FROM funcionario ORDER BY nome;\nSELECT DISTINCT nome, sobrenome FROM funcionario ORDER BY nome;\n\n-- Não é possível contar os registros sem agrupá-los antes\nSELECT nome, COUNT(id) FROM funcionario GROUP BY nome ORDER BY nome;\n\n-- É necessário agrupar todas as colunas que foram definidas na consulta\nSELECT nome, sobrenome, COUNT(id) FROM funcionario GROUP BY 1, 2 ORDER BY nome;\n\n-- Essa consulta retornará os cursos a quantidade de alunos matriculados neles\nSELECT curso.nome, COUNT(aluno.id) FROM aluno\nJOIN aluno_curso ON aluno.id = aluno_curso.aluno_id\nJOIN curso ON curso.id = aluno_curso.curso_id\nGROUP BY 1 ORDER BY 1;\n```\n\n### **Filtrando consultas agrupadas**\n\nQuando se quer filtrar campos, utiliza-se o comando `WHERE`. Porém quando se quer filtrar funções de agregação, utiliza-se o comando `HAVING`.\n\n```sql\n-- Traz registros sem alunos\nSELECT curso.nome, COUNT(aluno.id) FROM curso\nLEFT JOIN aluno_curso ON aluno_curso.curso_id = curso.id\nLEFT JOIN aluno ON aluno.id = aluno_curso.aluno_id\nGROUP BY 1 HAVING COUNT(aluno.id) = 0;\n\n-- Traz registros com pelo menos 1 aluno\nSELECT curso.nome, COUNT(aluno.id) FROM curso\nLEFT JOIN aluno_curso ON aluno_curso.curso_id = curso.id\nLEFT JOIN aluno ON aluno.id = aluno_curso.aluno_id\nGROUP BY 1 HAVING COUNT(aluno.id) \u003e 0;\n\n-- Conta funcionarios com nomes únicos\nSELECT nome, COUNT(id) FROM funcionario\nGROUP BY nome HAVING COUNT(id) = 1;\n\n-- Conta funcionarios com nome duplicado\nSELECT nome, COUNT(id) FROM funcionario\nGROUP BY nome HAVING COUNT(id) \u003e 1;\n```\n\n⬆️ [Voltar ao topo](#postgresql) ⬆️","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreadcsousa%2Falura_postgresql-introducao_sql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandreadcsousa%2Falura_postgresql-introducao_sql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreadcsousa%2Falura_postgresql-introducao_sql/lists"}