QUESTÃO 1: A Secretaria Municipal de Mobilidade e Trânsito de uma Prefeitura solicitou um estudo para determinar a melhor rota entre dois bairros (A e B) considerando diversos fatores, tais como distância, tempo estimado de viagem, condições da estrada e custo do combustível. Os dados estão nas duas tabelas seguintes de um Banco de Dados Relacional Oracle:
■ Bairros: Contém informações sobre cada bairro, incluindo um 1D único, nome e coordenadas geográficas.
■ Rotas: Contém informações sobre as rotas existentes entre os bairros, como 1D da rota, bairro de origem, bairro de destino, distância, tempo estimado, condição da estrada e custo estimado.
Em uma consulta utilizando INNER JOIN, a expressão SQL correta para encontrar a rota mais eficiente entre dois bairros específicos, com base nos critérios definidos pelo órgão, é
A- SELECT * FROM ROTAS WHERE bairro_origem = 'Bairro A' AND bairro_destino = 'Bairro B' AND MIN (r . distancia) INNER JOIN ROTAS AND BAIRROS;
B- SELECT r . id_rota, MIN (r . distancia) FROM ROTAS r INNER JOIN BAIRROS b ON r . bairro_ origem - b . id bairro WHERE b . nome= 'Bairro A' GROUP BY r . id rota ;
C- SELECT r . id_rota , r .distancia, r . tempo_estimado FROM ROTAS r INNER JOIN BAIRROS b ON r . bairro_origem = b . id_bairro WHERE b . nome= 'Bairro A' AND r . bairro_destino = 'Bairro B' ORDER BY r . distancia ASC, r . tempo_estimado ASC;
D- SELECT INNER JOIN r . id_rota, r . distancia, r . tempo_estimado FROM ROTAS r WHERE bairro_origem = 'Bairro A' ANDAND bairro_destino = 'Bairro B' ORDER BY r . distancia ASC;
E- SELECT r . id_rota , r . distancia, r . tempo_estimado FROM ROTAS r INNER JOIN BAIRROS b ON r .bairro_origem = b . id_bairro WHERE b . nome= 'Bairro A';
Por que a alternativa C está correta?
O comando da alternativa C é o único que atende a todos os requisitos do enunciado com uma sintaxe SQL válida:
- A Junção (
INNER JOIN):FROM ROTAS r INNER JOIN BAIRROS b ON r.bairro_origem = b.id_bairroIsso conecta as duas tabelas corretamente, cruzando a informação de quem é o bairro de origem na tabela de rotas com o ID correspondente na tabela de bairros. - Os Filtros (
WHERE):WHERE b.nome = 'Bairro A' AND r.bairro_destino = 'Bairro B'Isso garante que estamos olhando apenas para as rotas que começam no Bairro A e terminam no Bairro B, exatamente como a prefeitura pediu. - O Critério de Eficiência (
ORDER BY):ORDER BY r.distancia ASC, r.tempo_estimado ASCComo a prefeitura quer a rota "mais eficiente", precisamos ordenar os resultados do menor para o maior (ASC- ascendente). Assim, o banco de dados colocará no topo da lista a rota com a menor distância e o menor tempo, resolvendo o problema de negócio.
Por que as outras alternativas estão incorretas?
Em questões de banco de dados, muitas alternativas são eliminadas apenas por erros crassos de digitação ou estruturação da linguagem SQL. Veja os problemas:
- A: ❌ Erro de Sintaxe Grave. O comando coloca a cláusula
INNER JOINno final da instrução (depois doWHERE), o que é proibido no SQL. Além disso, a funçãoMIN()não pode ser usada solta no meio doWHEREdaquela forma. - B: ❌ Erro de Operador e Lógica. Há um erro de digitação proposital da banca no
ON r.bairro_origem - b.id_bairro(usaram um sinal de menos-em vez de igual=). Além disso, ela filtra apenas a origem, esquecendo completamente de filtrar o destino (Bairro B). - D: ❌ Erros de Sintaxe Absurdos. O comando já começa errado escrevendo
SELECT INNER JOIN. OINNER JOINdeve vir na cláusulaFROM. Além disso, há um erro de digitação gritante (ANDAND) no meio da cláusulaWHERE. - E: ❌ Incompleta. Embora a sintaxe SQL não tenha erros, a lógica não atende ao pedido. Ela filtra apenas as rotas que saem do 'Bairro A', mas ignora para onde elas vão (não filtra o Bairro B) e não faz nenhuma ordenação para descobrir qual é a mais eficiente.
QUESTÃO 2: Para atender aos requisitos de um departamento municipal de produtos agrícolas sobre a movimentação temporal entre locais dos produtos estocados, uma Analista criou e populou as seguintes tabelas Fato e Dimensões usando o modelo snowflake:
Tabela Fato:
CREATE TABLE FatoEstoque (
id INT PRIMARY KEY,
data DATE,
local_id INT,
produto_id INT,
volume lNT
);
Tabelas Dimensões:
CREATE TABLE DimLocal (
local_id INT PRIMARY KEY,
nome_ local VARCHAR(100),
endereco VARCHAR(255)
);
CREATE TABLE DimProduto (
produto_ id INT PRIMARY KEY,
nome_produto VARCHAR(100),
categoria VARCHAR(100)
);
CREATE TABLE DimData (
data DATE PRIMARY KEY,
ano INT,
mes INT,
dia INT
);
A seguir, ela escreveu corretamente a seguinte consulta SQL, que somou os produtos estocados em cada local para os anos de 2023 e 2024 e ordenou os resultados do local mais movimentado para o menos movimentado:
A
SELECT l. nome_ local, SUM ( f . volume) AS total_ volume
FROM FatoEstoque f
JOIN DimLocal l LIKE f . local id = l . local id
JOIN DimData d LIKE f . dat a = d .data
WHERE d . ano SUM (2023, 2024)
GROUP BY l . nome local
ORDER BY total_volume DESC;
B
SELECT l. nome_ local, ON(f.volume) AS total_ volume
FROM FatoEstoque f
JOIN DimLocal l ON f . local id = l. local id
JOIN DimData d ON f .data = d .data
WHERE d . ano MAX(2023, 2024)
GROUP BY l . nome local
ORDER BY total_volume DESC;
C
SELECT l. nome_ local, FOR ( f . volume) AS total volume
FROM FatoEstoque f
JOIN DimLocal l WITH f . local id = l. local id
JOIN DimData d WITH f . data = d .data
WHERE d . ano IN (2023, 2024)
GROUP BY l . nome local
ORDER BY total_volume DESC;
D
SELECT l. nome_ local, SUM (f . volume) AT total volume
FROM FatoEstoque f
JOIN DimLocal l IN f . local- id = l . local-id
JOIN DimData d IN f . data = d . data
WHERE d . ano SUM(2023, 2024)
GROUP BY l . nome local
ORDER BY total_volume DESC;
E
SELECT l. nome_ local, SUM ( f . volume) AS total volume
FROM FatoEstoque f
JOIN DimLocal l ON f . local id = l. local id
JOIN DimData d ON f .data = d .data
WHERE d . ano IN (2023, 2024)
GROUP BY l . nome local
ORDER BY total_volume DESC;
Por que a alternativa E está correta?
Ela é a única que utiliza as palavras-chave do SQL da maneira correta para atingir o objetivo:
A Soma e o Apelido (
SUMeAS):SELECT l.nome_local, SUM(f.volume) AS total_volumeIsso soma corretamente a coluna de volume e dá o "apelido" (alias) detotal_volumepara essa nova coluna, usando a palavra-chaveAS.As Junções (
JOIN ... ON):JOIN DimLocal l ON f.local_id = l.local_idA palavra-chave para definir a condição de união entre duas tabelas é oON. O comando liga a tabela FatoEstoque com as tabelas de Dimensão (Local e Data) perfeitamente através de suas chaves.O Filtro de Anos (
IN):WHERE d.ano IN (2023, 2024)A cláusulaINé a maneira correta no SQL de dizer "onde o ano seja um desses valores dentro da lista".Agrupamento e Ordenação (
GROUP BYeORDER BY ... DESC): OGROUP BY l.nome_localgarante que a soma será feita por local. OORDER BY total_volume DESCordena do maior para o menor (descendente), cumprindo a regra de mostrar do "mais movimentado para o menos movimentado".
Por que as outras alternativas estão erradas?
Assim como na questão anterior, a banca brincou com a sintaxe para criar comandos inválidos. Veja os absurdos em cada uma:
A: ❌ Erros de Junção e Filtro. Usa a palavra
LIKEpara fazer a junção das tabelas (o correto éON). Além disso, tenta filtrar os anos usando a função de soma noWHERE(WHERE d.ano SUM(2023, 2024)), o que não faz nenhum sentido lógico ou sintático.B: ❌ Funções no lugar errado. Inventa uma função chamada
ON(f.volume)noSELECT(deveria serSUM). E noWHERE, tenta usar a funçãoMAX(2023, 2024)em vez do operadorIN.C: ❌ Palavras inventadas para o contexto. Usa um suposto
FOR(f.volume)em vez deSUMpara somar. Para fazer a junção das tabelas, usa a palavraWITH(JOIN DimLocal l WITH...), quando o correto éON.D: ❌ Festival de erros de sintaxe. Tenta criar o alias da coluna usando
ATem vez deAS(AT total volume). Faz a junção das tabelas usandoINem vez deON(JOIN DimLocal l IN...). E, assim como na A, erra o filtro doWHEREusandoSUM(2023, 2024).