AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 176581
Accepted
SS'
SS'
Asked: 2017-06-19 08:21:15 +0800 CST2017-06-19 08:21:15 +0800 CST 2017-06-19 08:21:15 +0800 CST

Encontre o aluno com a nota mais alta em cada estado, usando Álgebra Relacional

  • 772

Suponha que eu tenha uma tabela de alunos, contendo seu ID, série e estado:

-------------------------
| id  |  grade  | state |
------------------------
|  1  |    83   |   CA  |
|  2  |    94   |   TX  |
|  3  |    92   |   WA  |
|  4  |    78   |   CA  |

E eu quero o ID dos alunos de cada estado com a nota mais alta (ex. 1, 2 e 3), como eu faria isso?

Eu sei como encontrar o máximo (pode fazer o produto cruzado (renomeando como R1 e R2) e então selecionar R1.grade < R2.grade para aqueles que não estão no topo, e subtrair isso do banco de dados original). Mas estou confuso sobre como fazer isso para cada estado.

relational-theory relational-algebra
  • 2 2 respostas
  • 6269 Views

2 respostas

  • Voted
  1. Best Answer
    joanolo
    2017-06-21T12:25:14+08:002017-06-21T12:25:14+08:00

    Na verdade, não me sinto muito confortável com álgebra relacional, então, farei isso primeiro usando SQL padrão e depois usarei uma ferramenta chamada RelaX - calculadora de álgebra relacional 0.18.2 para fazer a tradução.

    Primeiro, a tabela que você escreveu, vou chamá-la de alunos, defini-la e preenchê-la com:

    CREATE TABLE students
    (
        id INTEGER PRIMARY KEY,
        grade INTEGER,
        state TEXT
    ) ;
    
    INSERT INTO students
        (id, grade, state)
    VALUES
        (1, 83, 'CA'),
        (2, 94, 'TX'),
        (3, 92, 'WA'),
        (4, 78, 'CA') ;
    

    O RelaX traduzirá isso em um conjunto de dados, representado pelas seguintes tuplas:

    group: Joan (imported from SQL)
    
    students = {
        id:number, grade:number, state:string
        1        , 83          , 'CA'        
        2        , 94          , 'TX'        
        3        , 92          , 'WA'        
        4        , 78          , 'CA'        
    }
    

    Para encontrar o que você procura, primeiro precisamos de uma tabela com tuplas no formato (state, grade), tendo a nota máxima de cada estado. Essa consulta é feita, em SQL com um MAX(grade)per stateusando um GROUPs BY state. Você escreveria assim:

    SELECT
        state, max(grade) AS grade
    FROM 
        students AS s2 
    GROUP BY
        state ;
    

    Em seguida, você precisa JOINdessa tabela (que se chama max_grades) para studentsaquela, e você faz isso com ONestados iguais e nota igual (ou seja: a nota máxima por estado) ...

    SELECT
        s1.id
    FROM
        students AS s1
        JOIN 
        (
            SELECT
                state, max(grade) AS grade
            FROM 
                students
            GROUP BY
                state
        ) AS max_grades 
        ON s1.state = max_grades.state AND s1.grade = max_grades.grade
    

    ... e isso é traduzido pelo RelaX para a seguinte expressão e resposta de álgebra relacional:

    π s1.id ρ s1 alunos ⨝ s1.state = max_grades.state e s1.grade = max_grades.grade ρ max_grades ( π state, grade γ estado; MAX(nota)→nota ρ s2 alunos)

    s1.id
    1
    2
    3

    insira a descrição da imagem aqui

    NOTA 1:

    1. Se vários alunos de um estado tivessem a nota máxima, essa expressão retornaria TODOS eles, não apenas um arbitrário desse estado.

    Alternativo:

    Se você não puder GROUP BY, você pode usar outra construção:

    SELECT DISTINCT
        id
    FROM
        students
    EXCEPT
    SELECT
        s1.id
    FROM
        students AS s1
        JOIN students AS s2 ON s1.state = s2.state AND s1.grade < s2.grade
    

    Isso vai um pouco mais de acordo com o seu pensamento original, embora eu pessoalmente ache menos claro ...

    A tradução para álgebra relacional é:

    π id alunos - π s1.id ρ s1 alunos ⨝ s1.estado = s2.estado e s1.série < s2.série ρ s2 alunos

    insira a descrição da imagem aqui

    • 2
  2. MSIS
    2017-06-19T16:13:31+08:002017-06-19T16:13:31+08:00

    EDIT: não li com atenção e dei uma resposta para SQL, caso o pôster se interesse. Por favor, deixe-me saber se você não está interessado e então eu vou excluir.

    SQL: Acho que usar uma tabela derivada funciona. Vamos chamar sua mesa de 'Alunos':

    SELECT id FROM Students JOIN
      (SELECT State, Max(Grade) AS MaxGrade FROM Students GROUP BY State ) AS T 
      ON T.State=Students.State  
    WHERE Students.Grade >= T.MaxGrade
     ;
    
    • 1

relate perguntas

  • Como projetar relacionamentos para dados variantes?

  • De que escopo(s) "hasMany" faz parte?

  • Design Relacional - Várias tabelas em uma coluna de chave estrangeira?

  • Qual padrão devo seguir ao nomear tabelas e exibições?

  • Como estruturar um modelo para representar de forma adequada e eficiente dados em forma de árvore em bancos de dados relacionais?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve