Uppgift 3 - tentan

  • Författare
  • Meddelande

johre

på gång

  • Inlägg: 2
  • Blev medlem: 26 mar 2020, 17:08

Uppgift 3 - tentan

Inlägg26 mar 2020, 17:10

Det vore toppen om någon kunde posta en lösning för uppgift 3 på databastentan!
Tack!
/Johan
Användarvisningsbild

mos

dbwebb

  • Inlägg: 11180
  • Blev medlem: 10 nov 2011, 09:52
  • Ort: Ronneby / Bankeryd

Re: Uppgift 3 - tentan

Inlägg26 mar 2020, 17:15

Då satsar vi på det under morgondagen när tentan är avklarad.
...
..:
.... /mos
Användarvisningsbild

abbe

html-kodare

  • Inlägg: 12
  • Blev medlem: 01 sep 2019, 20:30

Re: Uppgift 3 - tentan

Inlägg27 mar 2020, 01:10

Eftersom mysql inte har `full outer join` funktionen fick jag använda `union` istället. Jag använde det för att kombinera mina två SELECT-satser som är LEFT och RIGHT join. Logiken med om det är höger eller vänster-join är inte där än, så fick bli lite trial and error. Resten är att sortera och formatera utskriften.

Kod: Markera allt
SELECT
    a.namn AS "Artist",
    CONCAT(a.ort, "/", lk.namn , "(", lk.kod, ")") AS "Ort",
    sd.namn AS "Dag",
    DATE_FORMAT(sd.datum, "%D %M") as "Spelning",
    s.klockslag as "Tid"
FROM
    artist AS a
    LEFT OUTER JOIN landskod AS lk
    ON
    lk.kod = a.landskod
    LEFT OUTER JOIN spelning AS s
    ON
    s.artist_id = a.id
    LEFT OUTER JOIN speldag AS sd
    ON
    sd.id = s.speldag_id

UNION

SELECT
    a.namn AS "Artist",
    CONCAT(a.ort, "/", lk.namn , "(", lk.kod, ")") AS "Ort",
    sd.namn AS "Dag",
    DATE_FORMAT(sd.datum, "%D %M") as "Spelning",
    s.klockslag as "Tid"
FROM
    artist AS a
    LEFT OUTER JOIN landskod AS lk
    ON
    lk.kod = a.landskod
    LEFT OUTER JOIN spelning AS s
    ON
    s.artist_id = a.id
    RIGHT OUTER JOIN speldag AS sd
    ON
    sd.id = s.speldag_id

ORDER BY
   Spelning ASC,
   Tid ASC;
What if people flew before Newton discovered gravity.
Användarvisningsbild

mos

dbwebb

  • Inlägg: 11180
  • Blev medlem: 10 nov 2011, 09:52
  • Ort: Ronneby / Bankeryd

Re: Uppgift 3 - tentan

Inlägg27 mar 2020, 10:18

Som vanligt när det gäller sista uppgiften så försökte jag klura ut nåt som kunde vara lite lurigare att lösa men ändå inte jättesvårt. Denna gången ville jag undvika GROUP_CONCAT då ni säkert alla har full koll på det. Jag funderade på en blandning av JOINS och tänkte mig en SUBQUERY för att krånga lite.

När man tittade på lösningen för sista uppgiften så satt jag själv med två konstruktioner som gav olika delar av lösningen. En SELECT som gav halva lösningen inkl en av raderna med NULL och en annan SELECT som gav den andra halvan av lösningen med den andra raden av NULL.

Men hur man än gör, LEFT/RIGHT OUTER JOIN så går de två inte att kombinera på ett bra sätt när det vara fyra tabeller inblandade.

Ah, kombinera två resultset -> UNION/UNION ALL. Wips så hade man svaret.

Jag tänkte, om de (studenterna) bara klurar tillräckligt länge, och inser att de har två lösningar som behöver slås samman, så kanske de kommer ihåg UNION från guiden. Jag gissar att den kan upplevas som lite trixig, men troligen en "Ah, så kan man göra-känsla" när (om) man ser lösningen.


En annan variant vore, om man inser problemställningen och kan formulera att det är en FULL OUTER JOIN som krävs, ungefär som Abbe gjorde ovan. En googling hur man löser den i MySQL och så kommer förslag på UNION, tex via StackOverflow "How to do a FULL OUTER JOIN in MySQL".

Här är min kod när jag gjorde lösningsförslaget inför tentan, oklart om jag lyckades optimera det (jag försökte inte...). Jag tog helt enkelt samma SQL-sats, den ena använde LEFT OUTER på den kritiska biten (speldag) och den andra använda RIGHT OUTER på samma plats.
Kod: Markera allt
SELECT * FROM
(
SELECT
    a.namn AS Artist,
    CONCAT(a.ort, "/", lk.namn, "(", a.landskod, ")") AS Ort,
    sd.namn AS Dag,
    DATE_FORMAT(sd.datum, "%D %M") AS Spelning,
    s.klockslag AS Tid
FROM artist AS a
    INNER JOIN landskod as lk
        ON a.landskod = lk.kod
    LEFT OUTER JOIN spelning AS s
        ON a.id = s.artist_id
    LEFT OUTER JOIN speldag AS sd
        ON sd.id = s.speldag_id

UNION

SELECT
    a.namn AS Artist,
    CONCAT(a.ort, "/", lk.namn, "(", a.landskod, ")") AS Ort,
    sd.namn AS Dag,
    DATE_FORMAT(sd.datum, "%D %M") AS Spelning,
    s.klockslag AS Tid
FROM artist AS a
    INNER JOIN landskod as lk
        ON a.landskod = lk.kod
    LEFT OUTER JOIN spelning AS s
        ON a.id = s.artist_id
    RIGHT OUTER JOIN speldag AS sd
        ON sd.id = s.speldag_id
) AS t
ORDER BY
    Spelning, Tid
;


Kikar man på min lösning så ser man att jag faktiskt fick in en subquery, paranteserna runt SELECT UNION SELECT, för att lyckas sortera i rätt ordning.
...
..:
.... /mos

tikktakk79

css-hackare

  • Inlägg: 24
  • Blev medlem: 03 sep 2018, 14:48

Re: Uppgift 3 - tentan

Inlägg27 mar 2020, 12:30

Ah! Jag som trodde att min lösning med Union (som jag enbart hittade tack vare googling på full outer join) var onödigt komplicerad och att det var meningen att man skulle pussla ihop det med outer joins. Kred till tentamakarna för att ha hittat på en klurig uppgift.

johre

på gång

  • Inlägg: 2
  • Blev medlem: 26 mar 2020, 17:08

Re: Uppgift 3 - tentan

Inlägg29 mar 2020, 11:33

Tack för lösningsförslagen! Lurigt!

Vilka är online

Användare som besöker denna kategori: Inga registrerade användare och 15 gäster