Preencher tabela com comandos SQL e realizar operações matemáticas com esses comandos

Olá pessoal!

Primeiramente gostaria de dizer que sou um aprendiz de Java.

Estou tentando fazer um programa de estatística bem simples, que constitui em uma tabela com as colunas “Alternativas”, “Entrevistados” e “Frequência Relativa”, além de possuir quatro linhas, pois a tabela será em função das alternativas “A”, “B”, “C” e “D”.

A ideia é a seguinte: na coluna “Entrevistados”, cada linha mostrará o total de pessoas que assinalaram a alternativa correspondente (A, B, C ou D) e na coluna “Frequência Relativa”, cada linha mostrará o número de pessoas que responderam a alternativa dividido pelo total de pessoas que responderam o questionário.

Para obter o resultado que almejo na coluna “Entrevistados”, precisarem utilizar um comando SQL, que é o COUNT. Na coluna “Frequência Relativa”, terei que pegar o resultado do comando SQL da coluna “Entrevistados” e dividir pelo comando SQL COUNT que contará o total de questões na entidade “questionario”, que é onde estão armazenadas as respostas do questionário.

A minha dúvida é: como posso dividir um resultado de comando SQL por outro (operações matemáticas) e como posso preencher a tabela com o resultado desses comandos?

Tentei montar o seguinte código, vendo algumas videoaulas, porém falhei miseravelmente.

    public void preencherTabela(String SQL){
            ArrayList dados = new ArrayList();
            
            String [] Colunas = new String[]{"Alternativas","Entrevistados","Frequência Relativa"};
            
            conecta.executaSQL(SQL);
            try {
                conecta.rs.first();
                
                PreparedStatement entQ1 = conecta.conn.prepareStatement("select count(q1) from questionario");
                entQ1.executeQuery();
                PreparedStatement fra = conecta.conn.prepareStatement("select count(*) from 
                questionario where q1='A'");
                fra.executeQuery();
                //String frA = fra/entQ1;
                do {
                    dados.add(new Object[]{"A",entQ1,fra});
                } while (conecta.rs.next());
            } catch (SQLException ex) {
                JOptionPane.showMessageDialog(null, "Erro ao preencher o ArrayList!\nERRO: "+ex);
            }
            
            ModeloTabela modelo = new ModeloTabela(dados, Colunas);
            tblQ1.setModel(modelo);
            tblQ1.getColumnModel().getColumn(0).setPreferredWidth(200);
            tblQ1.getColumnModel().getColumn(0).setResizable(false);
            tblQ1.getColumnModel().getColumn(1).setPreferredWidth(200);
            tblQ1.getColumnModel().getColumn(1).setResizable(false);
            tblQ1.getColumnModel().getColumn(2).setPreferredWidth(200);
            tblQ1.getColumnModel().getColumn(2).setResizable(false);
            tblQ1.getTableHeader().setReorderingAllowed(false);
            tblQ1.setAutoResizeMode(tblQ1.AUTO_RESIZE_OFF);
            tblQ1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            
        }

Olá!
Resumindo, quando usa o COUNT em queries normalmente atribui-se o resultado à uma ALIAS SQL (nome temporário) e depois utiliza este AS para o cálculo.

Exemplificando, no seu caso, a sua string sql neste ponto:

Ficaria:

SELECT COUNT(q1) AS quantEnt FROM questionario

E neste ponto:

Ficaria:

SELECT COUNT(q1) AS quantQ1 FROM questionario WHERE q1='A'

Depois utiliza-se os dois AS para realizar seus cálculos.

Aqui também está errado:

Vai ajustando aí que vou lhe ajudando no aprendizado.

Olá!

Obrigado pela resposta!

Porém, me surgiram duas dúvidas.

A primeira é: como posso trabalhar com ALIAS SQL, uma vez que a mesma se encontra na string sql? Como posso manipulá-la, se faz parte da query?

A segunda dúvida é: nesta linha do código

dados.add(new Object[]{"A",conecta.rs.getString("q1"),conecta.rs.getString("q2")});

não mostra o resultado que quero, obviamente, porém só a fiz como exemplo. Nesse caso, pelo que entendi, estou preenchendo as linhas da tabela com os dados que foram passados dentro dos colchetes, onde cada vírgula indica uma nova coluna em que esses dados serão inseridos na mesma linha. Quando eu digito “conecta.rs.getString(“q1”)”, por exemplo, estou buscando no banco de dados os valores de todas as linhas da coluna “q1”, que estão em formato de String.

Resumindo, a minha dúvida é como eu posso passar os valores das variáveis que estão armazenando as query’s para obter o resultado dessas na tabela? Quando eu coloco o nome delas, igual fiz no primeiro código que postei, o resultado que obtenho nas linhas da tabela são parecidos com isto:

com.mysql.jdbc.JDBC4PreparedStatement@5b542949: query

onde a query é a string sql utilizada. Sei que o PreparedStatement prepara e realiza as pesquisas no banco de dados, porém como posso mostrar o resultado dessa pesquisa na tabela?

O código que tentei continuar segue abaixo.

    public void preencherTabela(String SQL){
            ArrayList dados = new ArrayList();
            
            String [] Colunas = new String[]{"Alternativas","Entrevistados","Frequência Relativa"};
            
            conecta.executaSQL(SQL);
            try {
                conecta.rs.first();
                
                PreparedStatement entQ1 = conecta.conn.prepareStatement("select count(q1) as quantEntQ1 from questionario");
                entQ1.executeQuery();
                
                PreparedStatement fra = conecta.conn.prepareStatement("select count(*) as quantQ1 from questionario where q1='A'");
                fra.executeQuery();
                do {
                    dados.add(new Object[ {"A",conecta.rs.getString("q1"),conecta.rs.getString("q2")});
                } while (conecta.rs.next());
            } catch (SQLException ex) {
                JOptionPane.showMessageDialog(null, "Erro ao preencher o ArrayList!\nERRO: "+ex);
            }
            
            ModeloTabela modelo = new ModeloTabela(dados, Colunas);
            tblQ1.setModel(modelo);
            tblQ1.getColumnModel().getColumn(0).setPreferredWidth(200);
            tblQ1.getColumnModel().getColumn(0).setResizable(false);
            tblQ1.getColumnModel().getColumn(1).setPreferredWidth(200);
            tblQ1.getColumnModel().getColumn(1).setResizable(false);
            tblQ1.getColumnModel().getColumn(2).setPreferredWidth(200);
            tblQ1.getColumnModel().getColumn(2).setResizable(false);
            tblQ1.getTableHeader().setReorderingAllowed(false);
            tblQ1.setAutoResizeMode(tblQ1.AUTO_RESIZE_OFF);
            tblQ1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            
        }

Trabalha-se com o AS como um campo do BD.
int numeroEnt = conecta.rs.getInt("quantEnt");
Faz o mesmo para quantQ1 e depois raliza o cálculo que precisa.
int resultadoA = numeroEnt / numeroQ1;
Daí terá os dados para colocar na tabela.

Obrigado novamente pela ajuda!

Porém, ao utilizar o comando:

o código está considerando o quantEnt e o quantQ1 como se fossem colunas no banco de dados, da tabela questionario.

Quando executo o arquivo recebo a seguinte mensagem de erro:

java.sql.SQLException: Column 'quantEnt' not found.

Claro! Olha como você escreveu sua SQL:

Adeque o código.

Desculpa, mas como seria esse adequamento do código?

Vou mostrar o que já tentei fazer…

Primeiramente, fazendo uma busca, encontrei a seguinte sintaxe a utilizei, porém continuou dando a mensagem de erro.

PreparedStatement ent = conecta.conn.prepareStatement("select count(*) as \"quantEnt\" from questionario");

Também utilizei no lugar de\"quantEnt\" o "+quantEnt+", criando uma variável. Porém pedia para inicializá-la e resultava em erro.

Em seguida, tentei dividir a query, fazendo o seguinte código, que também falhou.

    String query = "select count(*) as \"quantEnt\"";
              query += "from questionario";
    PreparedStatement ent = conecta.conn.prepareStatement(query);

Seguindo sua ideia de código, faz assim:

String query = "SELECT count(id_chave_primaria_do_banco) AS quantEnt FROM questionario"; PreparedStatement ent = conecta.conn.prepareStatement(query);

Substitua este texto (id_chave_primaria_do_banco) na string pelo identificado de registro de seu banco de dados.

Fiz uma adaptação deste código

pegando algumas coisas deste tópico aqui do GUJ: https://www.guj.com.br/t/select-count-nome-from-usuario-como-pegar-o-resultado/28584/4 e cheguei a este código:

try {
            conecta.rs.first();
            
            String query = "SELECT COUNT(idQUESTIONARIO) AS quantEnt FROM questionario";
            PreparedStatement ent = conecta.conn.prepareStatement(query);
            ResultSet rs = ent.executeQuery();
            int numeroEnt = 0;
            if(rs.next()){
                numeroEnt = rs.getInt("quantEnt");
            }

            String query1 = "SELECT COUNT(idQUESTIONARIO) AS quantQ1a FROM questionario WHERE q1='A'";
            PreparedStatement fra = conecta.conn.prepareStatement(query1);
            ResultSet rs1 = fra.executeQuery();
            int numeroQ1A = 0;
            if(rs1.next()){
                numeroQ1A = rs1.getInt("quantQ1a");
            }
            
            int resultadoA = numeroQ1A/numeroEnt;
            
            do {
                dados.add(new Object[]{"A",numeroQ1A,resultadoA});
            } while (rs.next());
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, "Erro ao preencher o ArrayList!\nERRO: "+ex);
        }

Obtive êxito ao mostrar o número de pessoas que responderam a alternativa A da Questão 1, na coluna Entrevistados. Porém, na linha:

int resultadoA = numeroQ1A/numeroEnt;

a variável resultadoA retorna sempre 0, mesmo modificando a mesma para double ou fazendo:

int resultadoA = (numeroQ1A/numeroEnt)*100;

Acredito que isso aconteça porque defini:

int numeroEnt = 0; e int numeroQ1A = 0;

Porém, se o if foi verdadeiro, pois mostra o valor na tabela, tanto de numeroEnt quanto de numeroQ1A, por que a variável resultadoA sempre retorna 0, sendo que ela está recebendo valores diferentes de 0?

E em questão de sintaxe estaria correto este do-while?

do {
                dados.add(new Object[]{"A",numeroQ1A,resultadoA});
            } while (rs.next());

Já que possuo tanto as variáveis rs quanto rs1, do tipo ResultSet? É que graças a elas os dados da tabela não ficam repetidos.

As variáveis nesta expressão terão que ser float para gerar resultados com casas decimais.

O Do … While irá repetir pela quantidade de registros existentes.

Agora deu certo…

Muito obrigado, principalmente pela paciência!

Disponha.