Desafio 12

Author

Maria Eduarda Villéla Silva

Este relatório foi compilado em: 09/10/2025 10:21:52.

library(reticulate) #para usar o python no RStudio

#garantir que o reticulate vai usar o Python 3.12 que está presente nos pcs do lab
use_virtualenv("~/.virtualenvs/r-reticulate", required = TRUE)
py_run_string("import polars as pl; print(pl.__version__)")
1.33.1

SQLite e Polars

import polars as pl #importando polars
import sqlite3 #importando SQLite no python

Iniciando a conexão com o banco

conn = sqlite3.connect('data.db') #a conexão com o banco de dados é feita com o método connect
cursor = conn.cursor() #obtemos também o cursor, que é um objeto que permite interagir com o banco de dados

Criação manual de uma tabela

#o método execute é empregado para executar comandos dentro do banco SQL
cursor.execute('''
CREATE TABLE vendas (
    id INTEGER PRIMARY KEY,
    vendedor TEXT,
    produto TEXT,
    valor REAL,
    data_venda DATE
)
''')
<sqlite3.Cursor object at 0x0000013677673540>

Inserção de dados em uma tabela

#ao realizar uma inserção, deve-se executar o commit, que fará a confirmação da operação
cursor.execute('''
INSERT INTO vendas (vendedor, produto, valor, data_venda)
VALUES
    ('Ana', 'Produto A', 120.5, '2024-09-01'),
    ('Carlos', 'Produto B', 200.0, '2024-10-02'),
    ('Ana', 'Produto C', 150.0, '2024-09-03'),
    ('Bruno', 'Produto A', 300.0, '2024-11-04'),
    ('Carlos', 'Produto C', 100.0, '2024-10-05');
''')
<sqlite3.Cursor object at 0x0000013677673540>
conn.commit()

Consulta simples no SQLite

#executa um comando SQL diretamente no banco, selecionando todas as colunas e linhas da tabela 'vendas'
cursor.execute("SELECT * FROM vendas")
<sqlite3.Cursor object at 0x0000013677673540>
#busca (lê) todos os resultados retornados pela consulta e armazena numa lista chamada 'rows'
rows = cursor.fetchall()
for row in rows: #inicia um loop para percorrer cada linha retornada
  print(row)
(1, 'Ana', 'Produto A', 120.5, '2024-09-01')
(2, 'Carlos', 'Produto B', 200.0, '2024-10-02')
(3, 'Ana', 'Produto C', 150.0, '2024-09-03')
(4, 'Bruno', 'Produto A', 300.0, '2024-11-04')
(5, 'Carlos', 'Produto C', 100.0, '2024-10-05')

Integração com Polars

import polars as pl
#executa a mesma consulta SQL, mas usando polars para ler diretamente os dados do banco via a conexão 'conn'
#o resultado já vem como um data frame do polars
dados = pl.read_database("SELECT * FROM vendas", conn)
print(dados)
shape: (5, 5)
┌─────┬──────────┬───────────┬───────┬────────────┐
│ id  ┆ vendedor ┆ produto   ┆ valor ┆ data_venda │
│ --- ┆ ---      ┆ ---       ┆ ---   ┆ ---        │
│ i64 ┆ str      ┆ str       ┆ f64   ┆ str        │
╞═════╪══════════╪═══════════╪═══════╪════════════╡
│ 1   ┆ Ana      ┆ Produto A ┆ 120.5 ┆ 2024-09-01 │
│ 2   ┆ Carlos   ┆ Produto B ┆ 200.0 ┆ 2024-10-02 │
│ 3   ┆ Ana      ┆ Produto C ┆ 150.0 ┆ 2024-09-03 │
│ 4   ┆ Bruno    ┆ Produto A ┆ 300.0 ┆ 2024-11-04 │
│ 5   ┆ Carlos   ┆ Produto C ┆ 100.0 ┆ 2024-10-05 │
└─────┴──────────┴───────────┴───────┴────────────┘

Exemplos

Qual é o total de vendas por vendedor?

#executa uma consulta SQL que agrupa as vendas por 'vendedor' e soma o valor total de cada um
vendas_total = pl.read_database('''
   SELECT vendedor, SUM(valor) as total_vendas
   FROM vendas
   GROUP BY vendedor;
''', conn)
print(vendas_total)
shape: (3, 2)
┌──────────┬──────────────┐
│ vendedor ┆ total_vendas │
│ ---      ┆ ---          │
│ str      ┆ f64          │
╞══════════╪══════════════╡
│ Ana      ┆ 270.5        │
│ Bruno    ┆ 300.0        │
│ Carlos   ┆ 300.0        │
└──────────┴──────────────┘

Qual é o valor médio de venda por vendedor?

#agrupa por 'vendedor' e calcula a média (AVG) dos valores de venda de cada um
vendas_medias = pl.read_database('''
   SELECT vendedor, AVG(valor) as total_vendas
   FROM vendas
   GROUP BY vendedor;
''', conn)
print(vendas_medias)
shape: (3, 2)
┌──────────┬──────────────┐
│ vendedor ┆ total_vendas │
│ ---      ┆ ---          │
│ str      ┆ f64          │
╞══════════╪══════════════╡
│ Ana      ┆ 135.25       │
│ Bruno    ┆ 300.0        │
│ Carlos   ┆ 150.0        │
└──────────┴──────────────┘

Crie uma tabela contendo o nome do vendedor, o número de vendas realizadas, o total vendido e o valor médio por venda.

vendas_comb = pl.read_database("""
SELECT vendedor, 
       COUNT(*) as numero_vendas,  -- conta quantas vendas cada vendedor fez
       SUM(valor) as total_vendas, -- soma o valor total das vendas
       AVG(valor) as media_vendas  -- calcula o valor médio por venda
FROM vendas
GROUP BY vendedor;
""", conn)
print(vendas_comb)
shape: (3, 4)
┌──────────┬───────────────┬──────────────┬──────────────┐
│ vendedor ┆ numero_vendas ┆ total_vendas ┆ media_vendas │
│ ---      ┆ ---           ┆ ---          ┆ ---          │
│ str      ┆ i64           ┆ f64          ┆ f64          │
╞══════════╪═══════════════╪══════════════╪══════════════╡
│ Ana      ┆ 2             ┆ 270.5        ┆ 135.25       │
│ Bruno    ┆ 1             ┆ 300.0        ┆ 300.0        │
│ Carlos   ┆ 2             ┆ 300.0        ┆ 150.0        │
└──────────┴───────────────┴──────────────┴──────────────┘

Quais foram as vendas de, pelo menos, $200.00?

#seleciona apenas as vendas cujo valor é maior ou igual a 200
ticket_alto = pl.read_database("""
SELECT * FROM vendas WHERE valor >= 200
""", conn)
print(ticket_alto)
shape: (2, 5)
┌─────┬──────────┬───────────┬───────┬────────────┐
│ id  ┆ vendedor ┆ produto   ┆ valor ┆ data_venda │
│ --- ┆ ---      ┆ ---       ┆ ---   ┆ ---        │
│ i64 ┆ str      ┆ str       ┆ f64   ┆ str        │
╞═════╪══════════╪═══════════╪═══════╪════════════╡
│ 2   ┆ Carlos   ┆ Produto B ┆ 200.0 ┆ 2024-10-02 │
│ 4   ┆ Bruno    ┆ Produto A ┆ 300.0 ┆ 2024-11-04 │
└─────┴──────────┴───────────┴───────┴────────────┘

Qual foi o volume mensal de vendas?

#agrupa as vendas por mês (extraído da data) e soma o total de cada mês
#'strftime' converte a data para o formato 'YYYY-MM' (ano-mês)
vendas_mensais = pl.read_database("""
SELECT strftime('%Y-%m', data_venda) AS mes, SUM(valor) AS total_vendas
FROM vendas GROUP BY mes ORDER BY mes
""", conn)
print(vendas_mensais)
shape: (3, 2)
┌─────────┬──────────────┐
│ mes     ┆ total_vendas │
│ ---     ┆ ---          │
│ str     ┆ f64          │
╞═════════╪══════════════╡
│ 2024-09 ┆ 270.5        │
│ 2024-10 ┆ 300.0        │
│ 2024-11 ┆ 300.0        │
└─────────┴──────────────┘

Criando a tabela de produtos

#cria a tabela 'produtos' no banco caso ela ainda não exista, com colunas de id, nome, categoria, preço e estoque
cursor.execute('''
CREATE TABLE IF NOT EXISTS produtos (
    id INTEGER PRIMARY KEY,
    nome TEXT NOT NULL,
    categoria TEXT NOT NULL,
    preco REAL NOT NULL,
    estoque INTEGER NOT NULL
);
''')
<sqlite3.Cursor object at 0x0000013677673540>
#insere registros iniciais na tabela de produtos, com nome, categoria, preço e quantidade em estoque
cursor.execute('''
INSERT INTO produtos (nome, categoria, preco, estoque) VALUES
    ('Produto A', 'Categoria 1', 100.0, 50),
    ('Produto B', 'Categoria 2', 150.0, 30),
    ('Produto C', 'Categoria 1', 200.0, 20),
    ('Produto D', 'Categoria 2', 250.0, 10),
    ('Produto E', 'Categoria 3', 300.0, 0);
''')
<sqlite3.Cursor object at 0x0000013677673540>
conn.commit() #salva as alterações (inserções) no banco de dados

#consultando a tabela de produtos
prods = pl.read_database("SELECT * FROM produtos", conn) 
print(prods)
shape: (25, 5)
┌─────┬───────────┬─────────────┬───────┬─────────┐
│ id  ┆ nome      ┆ categoria   ┆ preco ┆ estoque │
│ --- ┆ ---       ┆ ---         ┆ ---   ┆ ---     │
│ i64 ┆ str       ┆ str         ┆ f64   ┆ i64     │
╞═════╪═══════════╪═════════════╪═══════╪═════════╡
│ 1   ┆ Produto A ┆ Categoria 1 ┆ 100.0 ┆ 50      │
│ 2   ┆ Produto B ┆ Categoria 2 ┆ 150.0 ┆ 30      │
│ 3   ┆ Produto C ┆ Categoria 1 ┆ 200.0 ┆ 20      │
│ 4   ┆ Produto D ┆ Categoria 2 ┆ 250.0 ┆ 10      │
│ 5   ┆ Produto E ┆ Categoria 3 ┆ 300.0 ┆ 0       │
│ …   ┆ …         ┆ …           ┆ …     ┆ …       │
│ 21  ┆ Produto A ┆ Categoria 1 ┆ 100.0 ┆ 50      │
│ 22  ┆ Produto B ┆ Categoria 2 ┆ 150.0 ┆ 30      │
│ 23  ┆ Produto C ┆ Categoria 1 ┆ 200.0 ┆ 20      │
│ 24  ┆ Produto D ┆ Categoria 2 ┆ 250.0 ┆ 10      │
│ 25  ┆ Produto E ┆ Categoria 3 ┆ 300.0 ┆ 0       │
└─────┴───────────┴─────────────┴───────┴─────────┘

JOINs de vendas e produtos

  • A coluna valor em vendas representa o valor de venda do respectivo produto.
  • A coluna preco em produtos representa o valor de compra do respectivo produto.
  • Apresente uma tabela com o nome do produto, seu valor de compra e venda, além do lucro no momento da venda.
lucros = pl.read_database("""
SELECT produto, valor AS compra, preco AS venda, preco-valor AS lucro
FROM vendas
INNER JOIN produtos ON vendas.produto = produtos.nome
""", conn)
print(lucros)
shape: (25, 4)
┌───────────┬────────┬───────┬───────┐
│ produto   ┆ compra ┆ venda ┆ lucro │
│ ---       ┆ ---    ┆ ---   ┆ ---   │
│ str       ┆ f64    ┆ f64   ┆ f64   │
╞═══════════╪════════╪═══════╪═══════╡
│ Produto A ┆ 120.5  ┆ 100.0 ┆ -20.5 │
│ Produto A ┆ 120.5  ┆ 100.0 ┆ -20.5 │
│ Produto A ┆ 120.5  ┆ 100.0 ┆ -20.5 │
│ Produto A ┆ 120.5  ┆ 100.0 ┆ -20.5 │
│ Produto A ┆ 120.5  ┆ 100.0 ┆ -20.5 │
│ …         ┆ …      ┆ …     ┆ …     │
│ Produto C ┆ 100.0  ┆ 200.0 ┆ 100.0 │
│ Produto C ┆ 100.0  ┆ 200.0 ┆ 100.0 │
│ Produto C ┆ 100.0  ┆ 200.0 ┆ 100.0 │
│ Produto C ┆ 100.0  ┆ 200.0 ┆ 100.0 │
│ Produto C ┆ 100.0  ┆ 200.0 ┆ 100.0 │
└───────────┴────────┴───────┴───────┘

#Exemplo

Qual foi o lucro médio por vendedor?

#agrupa por vendedor e calcula o lucro médio (diferença entre preço de venda e compra)
#usa um JOIN para combinar as informações das duas tabelas
lucro_medio = pl.read_database("""
SELECT vendedor, produto, AVG(preco-valor) AS lucro_medio
FROM vendas
INNER JOIN produtos ON vendas.produto = produtos.nome
GROUP BY vendedor
""", conn)
print(lucro_medio)
shape: (3, 3)
┌──────────┬───────────┬─────────────┐
│ vendedor ┆ produto   ┆ lucro_medio │
│ ---      ┆ ---       ┆ ---         │
│ str      ┆ str       ┆ f64         │
╞══════════╪═══════════╪═════════════╡
│ Ana      ┆ Produto A ┆ 14.75       │
│ Bruno    ┆ Produto A ┆ -200.0      │
│ Carlos   ┆ Produto B ┆ 25.0        │
└──────────┴───────────┴─────────────┘