sql >> Databasteknik >  >> RDS >> Mysql

Sammanfoga tabeller baserat på maxvärdet

Svarar på den REDIGERADE frågan (d.v.s. för att också få tillhörande kolumner).

I SQL Server 2005+ skulle det bästa tillvägagångssättet vara att använda en ranking/fönster funktion i samband med en CTE , så här:

with exam_data as
(
    select  r.student_id, r.score, r.date,
            row_number() over(partition by r.student_id order by r.score desc) as rn
    from    exam_results r
)
select  s.name, d.score, d.date, d.student_id
from    students s
join    exam_data d
on      s.id = d.student_id
where   d.rn = 1;

För en ANSI-SQL-kompatibel lösning fungerar en underfråga och självanslutning, så här:

select  s.name, r.student_id, r.score, r.date
from    (
            select  r.student_id, max(r.score) as max_score
            from    exam_results r
            group by r.student_id
        ) d
join    exam_results r
on      r.student_id = d.student_id
and     r.score = d.max_score
join    students s
on      s.id = r.student_id;

Den sista förutsätter att det inte finns dubbletter av student_id/max_score-kombinationer, om det finns och/eller du vill planera att de-duplicera dem, måste du använda en annan underfråga för att ansluta till med något deterministiskt för att bestämma vilken post som ska hämtas . Om du till exempel antar att du inte kan ha flera poster för en given student med samma datum, om du vill bryta en oavgjord nivå baserat på det senaste max_score, skulle du göra något i stil med följande:

select  s.name, r3.student_id, r3.score, r3.date, r3.other_column_a, ...
from    (
            select  r2.student_id, r2.score as max_score, max(r2.date) as max_score_max_date
            from    (
                        select  r1.student_id, max(r1.score) as max_score
                        from    exam_results r1
                        group by r1.student_id
                    ) d
            join    exam_results r2
            on      r2.student_id = d.student_id
            and     r2.score = d.max_score
            group by r2.student_id, r2.score
        ) r
join    exam_results r3
on      r3.student_id = r.student_id
and     r3.score = r.max_score
and     r3.date = r.max_score_max_date
join    students s
on      s.id = r3.student_id;

EDIT:Lade till korrekt de-dupliceringsfråga tack vare Marks goda fångst i kommentarer



  1. Frågan sammanfogar allt till en rad snarare än i separata rader

  2. Är det möjligt att stänga av offertbehandling i Postgres COPY-kommandot med CSV-format?

  3. kopiera data från en mysql-databas till en annan mysql-databas med java

  4. Kryptera datatrafik mellan c# och mysql