Thread View: pl.comp.bazy-danych
13 messages
13 total messages
Started by kamil.sobczyk
Mon, 17 Oct 2016 18:02
[mysql] Łączenie danych z wielu tabel
Author: kamil.sobczyk
Date: Mon, 17 Oct 2016 18:02
Date: Mon, 17 Oct 2016 18:02
45 lines
2161 bytes
2161 bytes
Witam, Mam tabele: ||=Zawodnik ||id_zawodnik (pk) ||imie_nazwisko ||=Klub ||id_klub (pk) ||grupa_wiekowa ||nazwa ||=BIEG5 ||id_zawodnik (pk) ||id_szkolka (pk) ||rok (pk) ||kwartal (pk) ||punkty_b5 ||=BIEG10 ||id_zawodnik (pk) ||id_szkolka (pk) ||rok (pk) ||kwartal (pk) ||punkty_b10 ||=BIEG30 ||id_zawodnik (pk) ||id_szkolka (pk) ||rok (pk) ||kwartal (pk) ||punkty_b30 Szukam pomocy w stworzeniu zapytania SQL (mysql) zwracającego dla grupy wiekowej 11 lat (pole w tabeli **Klub**) w roku 2012 i kwartale 3 coś na podobieństwo: ||=id_zawodnik||id_szkolka||grupa_wiekowa||rok||kwartal||punkty_b5||punty_b10||punkty_30||SUMA ||1||2||11||2012||3||null||20||5||25 ||2||2||11||2012||3||null||null||5||5 ||3||2||11||2012||3||15||20||5||40 ||4||2||11||2012||3||null||null||null||0 oraz zapytania zwracającego wszelkie dostępne daty (rok, kwartal) jakie występują w tabelach **BIEG5**, **BIEG10**, **BIEG30** ? Będę wdzięczny za wszelką pomoc.
Re: [mysql] Łączenie danych z wielu tabel
Author: geos
Date: Mon, 17 Oct 2016 20:38
Date: Mon, 17 Oct 2016 20:38
54 lines
3500 bytes
3500 bytes
On 17.10.2016 20:02, kamil.sobczyk@gmail.com wrote: > Szukam pomocy w stworzeniu zapytania SQL (mysql) zwracającego dla grupy wiekowej 11 lat (pole w tabeli **Klub**) w roku 2012 i kwartale 3 coś na podobieństwo: > > ||=id_zawodnik||id_szkolka||grupa_wiekowa||rok||kwartal||punkty_b5||punty_b10||punkty_30||SUMA > ||1||2||11||2012||3||null||20||5||25 > ||2||2||11||2012||3||null||null||5||5 > ||3||2||11||2012||3||15||20||5||40 > ||4||2||11||2012||3||null||null||null||0 > > oraz zapytania zwracającego wszelkie dostępne daty (rok, kwartal) jakie występują w tabelach **BIEG5**, **BIEG10**, **BIEG30** ? > > Będę wdzięczny za wszelką pomoc. tak na pierwszy rzut oka to trochę nieintuicyjnie sobie zaprojektowałeś te biegi. czemu trzy osobne tabele a nie jedna z kolumną np. dystans o wartościach 5, 10, 30 (czy jakie tam kiedyś w przyszłości dodatkowe będą)? albo jedna partycjonowana po tej kolumnie jeśli zależy Ci na osobnych segmentach danych. wracając do pytania - spróbuj napisać sobie taki widok w mysql: select b.dst, b.idz, b.idsz, k.gw, b.rok, b.kw , max(case when dystans = 5 then punkty end) p5 , max(case when dystans = 10 then punkty end) p10 , max(case when dystans = 30 then punkty end) p30 from ( select idz, idsz, rok, kw, punkty_5 pkt, 5 dst from bieg5 union all select idz, idsz, rok, kw, punkty_10 pkt, 10 dst from bieg10 union all select idz, idsz, rok, kw, punkty_30 pkt, 30 dst from bieg30 ) b left join klub k on b.idk = k.idk left join zawodnik z on b.idz = z.idz group by b.dst, b.idz, b.idsz, k.gw, b.rok, b.kw ; i dalej z tego widoku odpytuj o rok, kwartał czy co tam chcesz. a jak nie chcesz widoku to dodaj pożądane warunki do tego zapytania powyżej. sumę też możesz obliczać albo w zapytaniu do widoku albo w definicji widoku. wygląda na to, że start zawodnika ze szkółki w biegu X jest raz na kwartał. nie wnikam dalej w to, ale jeśli jest inaczej to ten max oczywiście nie zadziała, potrzebna byłaby dodatkowa kolumna np. numer_startu. ewentualnie jeśli mysql obsługuje pivot to możesz skorzystać z pivota. jeśli chodzi o dostępne kombinacje rok/kwartał to wykorzystaj fragment "b" powyżej, zamień union all na union i usuń kolumny poza rok i kw. łubu dubu, łubu dubu, niech nam żyje prezes klubu! pozdrawiam geos
Re: [mysql] Łączenie danych z wielu tabel
Author: geos
Date: Mon, 17 Oct 2016 20:42
Date: Mon, 17 Oct 2016 20:42
17 lines
1693 bytes
1693 bytes
On 17.10.2016 22:38, geos wrote: > select > b.dst, b.idz, b.idsz, k.gw, b.rok, b.kw > , max(case when dystans = 5 then punkty end) p5 > , max(case when dystans = 10 then punkty end) p10 > , max(case when dystans = 30 then punkty end) p30 > from > ( select idz, idsz, rok, kw, punkty_5 pkt, 5 dst from bieg5 union all > select idz, idsz, rok, kw, punkty_10 pkt, 10 dst from bieg10 union all > select idz, idsz, rok, kw, punkty_30 pkt, 30 dst from bieg30 ) b > left join klub k on b.idk = k.idk > left join zawodnik z on b.idz = z.idz > group by b.dst, b.idz, b.idsz, k.gw, b.rok, b.kw > ; drobna korekta: wywal to b.dst z select i group by, jakoś mi się zaplątało przy wypisywaniu kolumn.
Re: [mysql] Łączenie danych z wielu tabel
Author: geos
Date: Mon, 17 Oct 2016 20:45
Date: Mon, 17 Oct 2016 20:45
19 lines
1783 bytes
1783 bytes
On 17.10.2016 22:38, geos wrote: > select > b.dst, b.idz, b.idsz, k.gw, b.rok, b.kw > , max(case when dystans = 5 then punkty end) p5 > , max(case when dystans = 10 then punkty end) p10 > , max(case when dystans = 30 then punkty end) p30 > from > ( select idz, idsz, rok, kw, punkty_5 pkt, 5 dst from bieg5 union all > select idz, idsz, rok, kw, punkty_10 pkt, 10 dst from bieg10 union all > select idz, idsz, rok, kw, punkty_30 pkt, 30 dst from bieg30 ) b > left join klub k on b.idk = k.idk > left join zawodnik z on b.idz = z.idz > group by b.dst, b.idz, b.idsz, k.gw, b.rok, b.kw > ; drobna korekta: wywal to b.dst z select i group by, jakoś mi się zaplątało przy wypisywaniu kolumn. no i ten "dystans" to jest "dst" - nie zmieniłem tego, ale chyba się domyśliłbyś.
Re: [mysql] Łączenie danych z wielu tabel
Author: M.M.
Date: Tue, 18 Oct 2016 03:23
Date: Tue, 18 Oct 2016 03:23
43 lines
2262 bytes
2262 bytes
On Monday, October 17, 2016 at 8:02:33 PM UTC+2, kamil....@gmail.com wrote: > Witam, > > Mam tabele: > ||=Zawodnik > ||id_zawodnik (pk) > ||imie_nazwisko > > ||=Klub > ||id_klub (pk) > ||grupa_wiekowa > ||nazwa > > ||=BIEG5 > ||id_zawodnik (pk) > ||id_szkolka (pk) > ||rok (pk) > ||kwartal (pk) > ||punkty_b5 > > ||=BIEG10 > ||id_zawodnik (pk) > ||id_szkolka (pk) > ||rok (pk) > ||kwartal (pk) > ||punkty_b10 > > ||=BIEG30 > ||id_zawodnik (pk) > ||id_szkolka (pk) > ||rok (pk) > ||kwartal (pk) > ||punkty_b30 > > > Szukam pomocy w stworzeniu zapytania SQL (mysql) zwracającego dla grupy wiekowej 11 lat (pole w tabeli **Klub**) w roku 2012 i kwartale 3 coś na podobieństwo: > > ||=id_zawodnik||id_szkolka||grupa_wiekowa||rok||kwartal||punkty_b5||punty_b10||punkty_30||SUMA Nie wiem czy w mysqlu są unie - myślę że są. Jeśli są, to przy Twojej strukturze tabel chyba tylko unia pomoże. Pozdrawiam
Re: [mysql] Łączenie danych z wielu tabel
Author: kamil.sobczyk
Date: Tue, 18 Oct 2016 08:50
Date: Tue, 18 Oct 2016 08:50
75 lines
4646 bytes
4646 bytes
W dniu poniedziałek, 17 października 2016 22:38:41 UTC+2 użytkownik geos napisał:
> On 17.10.2016 20:02, kamil.sobczyk@gmail.com wrote:
>
> > Szukam pomocy w stworzeniu zapytania SQL (mysql) zwracającego dla grupy wiekowej 11 lat (pole w tabeli **Klub**) w roku 2012 i kwartale 3 coś na podobieństwo:
> >
> > ||=id_zawodnik||id_szkolka||grupa_wiekowa||rok||kwartal||punkty_b5||punty_b10||punkty_30||SUMA
> > ||1||2||11||2012||3||null||20||5||25
> > ||2||2||11||2012||3||null||null||5||5
> > ||3||2||11||2012||3||15||20||5||40
> > ||4||2||11||2012||3||null||null||null||0
> >
> > oraz zapytania zwracającego wszelkie dostępne daty (rok, kwartal) jakie występują w tabelach **BIEG5**, **BIEG10**, **BIEG30** ?
> >
> > Będę wdzięczny za wszelką pomoc.
>
> tak na pierwszy rzut oka to trochę nieintuicyjnie sobie zaprojektowałeś
> te biegi. czemu trzy osobne tabele a nie jedna z kolumną np. dystans o
> wartościach 5, 10, 30 (czy jakie tam kiedyś w przyszłości dodatkowe
> będą)? albo jedna partycjonowana po tej kolumnie jeśli zależy Ci na
> osobnych segmentach danych.
>
> wracając do pytania - spróbuj napisać sobie taki widok w mysql:
>
> select
> b.dst, b.idz, b.idsz, k.gw, b.rok, b.kw
> , max(case when dystans = 5 then punkty end) p5
> , max(case when dystans = 10 then punkty end) p10
> , max(case when dystans = 30 then punkty end) p30
> from
> ( select idz, idsz, rok, kw, punkty_5 pkt, 5 dst from bieg5 union all
> select idz, idsz, rok, kw, punkty_10 pkt, 10 dst from bieg10 union all
> select idz, idsz, rok, kw, punkty_30 pkt, 30 dst from bieg30 ) b
> left join klub k on b.idk = k.idk
> left join zawodnik z on b.idz = z.idz
> group by b.dst, b.idz, b.idsz, k.gw, b.rok, b.kw
> ;
>
> i dalej z tego widoku odpytuj o rok, kwartał czy co tam chcesz. a jak
> nie chcesz widoku to dodaj pożądane warunki do tego zapytania powyżej.
> sumę też możesz obliczać albo w zapytaniu do widoku albo w definicji widoku.
>
> wygląda na to, że start zawodnika ze szkółki w biegu X jest raz na
> kwartał. nie wnikam dalej w to, ale jeśli jest inaczej to ten max
> oczywiście nie zadziała, potrzebna byłaby dodatkowa kolumna np.
> numer_startu.
>
> ewentualnie jeśli mysql obsługuje pivot to możesz skorzystać z pivota.
>
> jeśli chodzi o dostępne kombinacje rok/kwartał to wykorzystaj fragment
> "b" powyżej, zamień union all na union i usuń kolumny poza rok i kw.
>
> łubu dubu, łubu dubu, niech nam żyje prezes klubu!
>
> pozdrawiam
> geos
Ogólnie problem jest taki, że tych "konkurencji" jest wiele. Dzieciaki oprócz biegów rywalizują też w rzucie piłką lekarską, skoku w dal itp. A liczba tych konkurencji może się zmieniać (pól/kategorii oceniania w danej konkurencji może być wiele, choć w każdej jest pole SUMA/PUNKTY). I pomiary są robione raz na kwartał.
Zastanawiam się czy nie będzie lepiej jak stworzę sobie dodatkową tabelę, powiedzmy:
Wyniki
id_zawodnik (pk)
id_szkolka (pk)
rok (pk)
kwartal (pk)
punkty_b10 {default 0}
punkty_b20 {default 0}
punkty_b30 {default 0}
...
punkty_skok {default 0}
i w niej będę sobie na bieżąco aktualizował dane.
Pewnie dla bazodanowych wyjadaczy ;) jest to podejście mało profesjonalne, ale... ;)
Dziękuję za pomoc!
Re: [mysql] Łączenie danych z wielu tabel
Author: geos
Date: Tue, 18 Oct 2016 10:18
Date: Tue, 18 Oct 2016 10:18
37 lines
2562 bytes
2562 bytes
On 18.10.2016 10:50, kamil.sobczyk@gmail.com wrote:
> Ogólnie problem jest taki, że tych "konkurencji" jest wiele. Dzieciaki oprócz biegów rywalizują też w rzucie piłką lekarską, skoku w dal itp. A liczba tych konkurencji może się zmieniać (pól/kategorii oceniania w danej konkurencji może być wiele, choć w każdej jest pole SUMA/PUNKTY). I pomiary są robione raz na kwartał.
>
> Zastanawiam się czy nie będzie lepiej jak stworzę sobie dodatkową tabelę, powiedzmy:
>
> Wyniki
> id_zawodnik (pk)
> id_szkolka (pk)
> rok (pk)
> kwartal (pk)
> punkty_b10 {default 0}
> punkty_b20 {default 0}
> punkty_b30 {default 0}
> ...
> punkty_skok {default 0}
>
> i w niej będę sobie na bieżąco aktualizował dane.
takie podejście jest podejściem hurtownianym. wydaje mi się, że narobisz
sobie w ten sposób więcej pracy, bo każde dodanie dyscypliny będzie
wymuszało dodanie kolumny dla odpowiednich punktów, tabela będzie się
rozrastać wszerz, wiele kolumn z punktami będzie pustych.
na Twoim miejscu kierowałbym się raczej w stronę postaci znormalizowanej
i zrobiłbym tak:
tabela zawodnicy(idz,...)
tabela kluby(idk,...)
tabela dyscypliny(idd,...)
tabela przejścia z kluczami (idz,idk,idd,idsz,rok,kw) i kolumnami (pkt,...)
w takiej konfiguracji dodanie dyscypliny to byłby jeden insert do tabeli
dyscypliny. z tabeli przejściowej stosunkowo łatwo też będzie zrobić
odpowiedni widok aby prezentował dane tak jak powyżej.
pozdrawiam,
geos
Re: [mysql] Łączenie danych z wielu tabel
Author: artiun
Date: Tue, 18 Oct 2016 10:40
Date: Tue, 18 Oct 2016 10:40
44 lines
2258 bytes
2258 bytes
W dniu 2016-10-17 o 20:02, kamil.sobczyk@gmail.com pisze: > Witam, > > Mam tabele: > ||=Zawodnik > ||id_zawodnik (pk) > ||imie_nazwisko > > ||=Klub > ||id_klub (pk) > ||grupa_wiekowa > ||nazwa > > ||=BIEG5 > ||id_zawodnik (pk) > ||id_szkolka (pk) > ||rok (pk) > ||kwartal (pk) > ||punkty_b5 > > ||=BIEG10 > ||id_zawodnik (pk) > ||id_szkolka (pk) > ||rok (pk) > ||kwartal (pk) > ||punkty_b10 > > ||=BIEG30 > ||id_zawodnik (pk) > ||id_szkolka (pk) > ||rok (pk) > ||kwartal (pk) > ||punkty_b30 > > W jaki sposób zawodnik łączy się z klubem. Rok, kwartał to chyba określenie kiedy odbywają się zawody. Więc jak przypisać zawodnikowi grupę wiekową, jak przypisać do szkółki (id_szkolka, id_klub). Rozpisz to jeszcze raz. Co wg Ciebie znaczy pk? Ile pk może być w jednej tabeli? Sam CHAOS. -- Artur
Re: [mysql] Łączenie danych z wielu tabel
Author: kamil.sobczyk
Date: Tue, 18 Oct 2016 11:00
Date: Tue, 18 Oct 2016 11:00
108 lines
4155 bytes
4155 bytes
W dniu wtorek, 18 października 2016 12:42:04 UTC+2 użytkownik artiun napisał:
> W dniu 2016-10-17 o 20:02, kamil.sobczyk@gmail.com pisze:
> > Witam,
> >
> > Mam tabele:
> > ||=Zawodnik
> > ||id_zawodnik (pk)
> > ||imie_nazwisko
> >
> > ||=Klub
> > ||id_klub (pk)
> > ||grupa_wiekowa
> > ||nazwa
> >
> > ||=BIEG5
> > ||id_zawodnik (pk)
> > ||id_szkolka (pk)
> > ||rok (pk)
> > ||kwartal (pk)
> > ||punkty_b5
> >
> > ||=BIEG10
> > ||id_zawodnik (pk)
> > ||id_szkolka (pk)
> > ||rok (pk)
> > ||kwartal (pk)
> > ||punkty_b10
> >
> > ||=BIEG30
> > ||id_zawodnik (pk)
> > ||id_szkolka (pk)
> > ||rok (pk)
> > ||kwartal (pk)
> > ||punkty_b30
> >
> >
> W jaki sposób zawodnik łączy się z klubem.
> Rok, kwartał to chyba określenie kiedy odbywają się zawody.
> Więc jak przypisać zawodnikowi grupę wiekową, jak przypisać do szkółki
> (id_szkolka, id_klub). Rozpisz to jeszcze raz.
> Co wg Ciebie znaczy pk? Ile pk może być w jednej tabeli?
> Sam CHAOS.
>
> --
> Artur
Rozwiązanie tego chaosu ;)
SELECT
Z.ID_ZAWODNIK
,S.ID_SZKOLKA
,S.GUPA_WIEKOWA
,B.ROK
,B.KWARTAL
,SUM(B.PB5) AS PUNKTY_B5
,SUM(B.PB10) AS PUNKTY_B10
,SUM(B.PB30) AS PUNKTY_B30
,SUM(B.PB) AS SUMA
FROM
ZAWODNIK AS Z
INNER JOIN (
SELECT
ID_ZAWODNIK
,ID_SZKOLKA
,ROK
,KWARTAL
,PUNKTY_B5 AS PB5
,0 AS PB10
,0 AS PB30
,PUNKTY_B5 AS PB
FROM
BIEG5
UNION ALL
SELECT
ID_ZAWODNIK
,ID_SZKOLKA
,ROK
,KWARTAL
,0 AS PB5
,PUNKTY_B10 AS PB10
,0 AS PB30
,PUNKTY_B10 AS PB
FROM
BIEG10
UNION ALL
SELECT
ID_ZAWODNIK
,ID_SZKOLKA
,ROK
,KWARTAL
,0 AS PB5
,0 AS PB10
,PUNKTY_B30 AS PB30
,PUNKTY_B30 AS PB
FROM
BIEG30
) AS B ON B.ID_ZAWODNIK = Z.ID_ZAWODNIK
INNER JOIN KLUB AS S ON S.ID_KLUB = B.ID_SZKOLKA
WHERE
B.ROK=2012
AND B.KWARTAL=3
AND S.GRUPA_WIEKOWA = 11
GROUP BY
Z.ID_ZAWODNIK
,S.ID_SZKOLKA
,S.GUPA_WIEKOWA
,B.ROK
,B.KWARTAL
Re: [mysql] Łączenie danych z wielu tabel
Author: kamil.sobczyk
Date: Tue, 18 Oct 2016 11:04
Date: Tue, 18 Oct 2016 11:04
40 lines
3444 bytes
3444 bytes
W dniu wtorek, 18 października 2016 12:19:21 UTC+2 użytkownik geos napisał:
> On 18.10.2016 10:50, kamil.sobczyk@gmail.com wrote:
> > Ogólnie problem jest taki, że tych "konkurencji" jest wiele. Dzieciaki oprócz biegów rywalizują też w rzucie piłką lekarską, skoku w dal itp. A liczba tych konkurencji może się zmieniać (pól/kategorii oceniania w danej konkurencji może być wiele, choć w każdej jest pole SUMA/PUNKTY). I pomiary są robione raz na kwartał.
> >
> > Zastanawiam się czy nie będzie lepiej jak stworzę sobie dodatkową tabelę, powiedzmy:
> >
> > Wyniki
> > id_zawodnik (pk)
> > id_szkolka (pk)
> > rok (pk)
> > kwartal (pk)
> > punkty_b10 {default 0}
> > punkty_b20 {default 0}
> > punkty_b30 {default 0}
> > ...
> > punkty_skok {default 0}
> >
> > i w niej będę sobie na bieżąco aktualizował dane.
>
> takie podejście jest podejściem hurtownianym. wydaje mi się, że narobisz
> sobie w ten sposób więcej pracy, bo każde dodanie dyscypliny będzie
> wymuszało dodanie kolumny dla odpowiednich punktów, tabela będzie się
> rozrastać wszerz, wiele kolumn z punktami będzie pustych.
>
> na Twoim miejscu kierowałbym się raczej w stronę postaci znormalizowanej
> i zrobiłbym tak:
>
> tabela zawodnicy(idz,...)
> tabela kluby(idk,...)
> tabela dyscypliny(idd,...)
> tabela przejścia z kluczami (idz,idk,idd,idsz,rok,kw) i kolumnami (pkt,...)
>
> w takiej konfiguracji dodanie dyscypliny to byłby jeden insert do tabeli
> dyscypliny. z tabeli przejściowej stosunkowo łatwo też będzie zrobić
> odpowiedni widok aby prezentował dane tak jak powyżej.
>
> pozdrawiam,
> geos
Teraz już wiem, że takie podejście byłoby najwłaściwsze. Muszę się z tym zmierzyć ;) Dzięki!
Re: [mysql] Łączenie danych z wielu tabel
Author: Kamil Sobczyk
Date: Wed, 28 Jun 2017 07:56
Date: Wed, 28 Jun 2017 07:56
58 lines
4232 bytes
4232 bytes
W dniu wtorek, 18 października 2016 12:19:21 UTC+2 użytkownik geos napisał:
> On 18.10.2016 10:50, kamil.sobczyk@gmail.com wrote:
> > Ogólnie problem jest taki, że tych "konkurencji" jest wiele. Dzieciaki oprócz biegów rywalizują też w rzucie piłką lekarską, skoku w dal itp. A liczba tych konkurencji może się zmieniać (pól/kategorii oceniania w danej konkurencji może być wiele, choć w każdej jest pole SUMA/PUNKTY). I pomiary są robione raz na kwartał.
> >
> > Zastanawiam się czy nie będzie lepiej jak stworzę sobie dodatkową tabelę, powiedzmy:
> >
> > Wyniki
> > id_zawodnik (pk)
> > id_szkolka (pk)
> > rok (pk)
> > kwartal (pk)
> > punkty_b10 {default 0}
> > punkty_b20 {default 0}
> > punkty_b30 {default 0}
> > ...
> > punkty_skok {default 0}
> >
> > i w niej będę sobie na bieżąco aktualizował dane.
>
> takie podejście jest podejściem hurtownianym. wydaje mi się, że narobisz
> sobie w ten sposób więcej pracy, bo każde dodanie dyscypliny będzie
> wymuszało dodanie kolumny dla odpowiednich punktów, tabela będzie się
> rozrastać wszerz, wiele kolumn z punktami będzie pustych.
>
> na Twoim miejscu kierowałbym się raczej w stronę postaci znormalizowanej
> i zrobiłbym tak:
>
> tabela zawodnicy(idz,...)
> tabela kluby(idk,...)
> tabela dyscypliny(idd,...)
> tabela przejścia z kluczami (idz,idk,idd,idsz,rok,kw) i kolumnami (pkt,...)
>
> w takiej konfiguracji dodanie dyscypliny to byłby jeden insert do tabeli
> dyscypliny. z tabeli przejściowej stosunkowo łatwo też będzie zrobić
> odpowiedni widok aby prezentował dane tak jak powyżej.
>
> pozdrawiam,
> geos
Witam,
I po kliku miesiącach okazało się, że miałeś racje - takie podejście było bardzo niewłaściwe. Do tego stopnia, że chce to zrobić od zera. Tylko potrzebowałbym pomocy bo mam braki w wiedzy ;)
Z zaproponowanego przez Ciebie rozwiązania:
1) oczywiste
tabela zawodnicy (idz, nazwiskoimie)
tabela kluby (idk, nazwaklubu)
tabela dyscypliny (idd, nazwadyscypliny)
2) mniej oczywiste dla mnie - prośba o pomoc z tymi tabelami przejścia czy dobrze kombinuje (założenie /na przykładzie biugu na 5m/ - test wykonywany jest raz na kwartał, przy czym dzieciak ma 3 próby i wyniki tych trzech prób musi być zapamiętany; dla innych konkurencji np. rzut piłką lekarską zapamiętywany jest wynik tylko 1 próby)
tabela przejscia z kluczami: dyscpomiary (idz,idk,idd,rok,kw,idp(autoincrement))
tabela przejscia z kolumnami: dyscwyniki (idp, wynikprobax) ???
Chciałbym, aby później dało się w miarę prosty sposób w MySQL zrobić widok wyświetlający dane:
idz||idk||rok||kw||idd1||wynikproba1||wynikproba2||wynikproba3||idd2||wynikproba1
Pozdrawiam
Kamil
Re: [mysql] Łączenie danych z wielu tabel
Author: geos
Date: Sat, 01 Jul 2017 21:26
Date: Sat, 01 Jul 2017 21:26
156 lines
7838 bytes
7838 bytes
On 28.06.2017 09:56, Kamil Sobczyk wrote:
> W dniu wtorek, 18 października 2016 12:19:21 UTC+2 użytkownik geos napisał:
>> On 18.10.2016 10:50, kamil.sobczyk@gmail.com wrote:
>>> Ogólnie problem jest taki, że tych "konkurencji" jest wiele. Dzieciaki oprócz biegów rywalizują też w rzucie piłką lekarską, skoku w dal itp. A liczba tych konkurencji może się zmieniać (pól/kategorii oceniania w danej konkurencji może być wiele, choć w każdej jest pole SUMA/PUNKTY). I pomiary są robione raz na kwartał.
>>>
>>> Zastanawiam się czy nie będzie lepiej jak stworzę sobie dodatkową tabelę, powiedzmy:
>>>
>>> Wyniki
>>> id_zawodnik (pk)
>>> id_szkolka (pk)
>>> rok (pk)
>>> kwartal (pk)
>>> punkty_b10 {default 0}
>>> punkty_b20 {default 0}
>>> punkty_b30 {default 0}
>>> ...
>>> punkty_skok {default 0}
>>>
>>> i w niej będę sobie na bieżąco aktualizował dane.
>>
>> takie podejście jest podejściem hurtownianym. wydaje mi się, że narobisz
>> sobie w ten sposób więcej pracy, bo każde dodanie dyscypliny będzie
>> wymuszało dodanie kolumny dla odpowiednich punktów, tabela będzie się
>> rozrastać wszerz, wiele kolumn z punktami będzie pustych.
>>
>> na Twoim miejscu kierowałbym się raczej w stronę postaci znormalizowanej
>> i zrobiłbym tak:
>>
>> tabela zawodnicy(idz,...)
>> tabela kluby(idk,...)
>> tabela dyscypliny(idd,...)
>> tabela przejścia z kluczami (idz,idk,idd,idsz,rok,kw) i kolumnami (pkt,...)
>>
>> w takiej konfiguracji dodanie dyscypliny to byłby jeden insert do tabeli
>> dyscypliny. z tabeli przejściowej stosunkowo łatwo też będzie zrobić
>> odpowiedni widok aby prezentował dane tak jak powyżej.
>>
>> pozdrawiam,
>> geos
>
> Witam,
> I po kliku miesiącach okazało się, że miałeś racje - takie podejście było bardzo niewłaściwe. Do tego stopnia, że chce to zrobić od zera. Tylko potrzebowałbym pomocy bo mam braki w wiedzy ;)
>
> Z zaproponowanego przez Ciebie rozwiązania:
> 1) oczywiste
> tabela zawodnicy (idz, nazwiskoimie)
> tabela kluby (idk, nazwaklubu)
> tabela dyscypliny (idd, nazwadyscypliny)
> 2) mniej oczywiste dla mnie - prośba o pomoc z tymi tabelami przejścia czy dobrze kombinuje (założenie /na przykładzie biugu na 5m/ - test wykonywany jest raz na kwartał, przy czym dzieciak ma 3 próby i wyniki tych trzech prób musi być zapamiętany; dla innych konkurencji np. rzut piłką lekarską zapamiętywany jest wynik tylko 1 próby)
>
> tabela przejscia z kluczami: dyscpomiary (idz,idk,idd,rok,kw,idp(autoincrement))
>
> tabela przejscia z kolumnami: dyscwyniki (idp, wynikprobax) ???
podam Ci przykład:
zawodnicy:
1 jórek ogórek
2 kiełbasa sznurek
kluby:
10 znicz warszawa
20 piece koszalin
30 hutnik ząbki
dyscypliny:
100 bieg na orientację 10km
200 bieg na 5km
300 rzut piłką lekarską 5kg
wyniki (idz,idk,idd,data,próba,wynik)
1 10 200 2017-03-04 1 3m45
1 10 200 2017-03-05 2 3m54
2 30 300 2016-06-05 1 20m75
1 10 200 2017-03-07 3 3m34
wszystkie próby są zapamiętywane
każda próba jest numerowana
mając datę łatwo obliczysz rok i kwartał
> Chciałbym, aby później dało się w miarę prosty sposób w MySQL zrobić widok wyświetlający dane:
> idz||idk||rok||kw||idd1||wynikproba1||wynikproba2||wynikproba3||idd2||wynikproba1
być może są bazy, które takie przekształcenie robią automatycznie z
użyciem własnej składni SQL. na pewno umieją to robić programy do
raportowania. na pewno wiele baz posiada, nazwijmy to, półautomatyczne
metody dla takich przekształceń, które potocznie nazywa się "pivotem".
prawie na pewno każda baza RDBMS potrafi zrobić to "na piechotę" z
użyciem funkcji min/max i składni case when..then..end. poniżej masz
przykład dla oracle. myślę, że bez trudu dostosujesz go do mysql. z, k,
d, w to tabele, których używasz. jak już je będziesz miał w bazie to
fragment między liniami "---" Cię nie dotyczy. ostatniego selecta możesz
użyć do zbudowania widoku. gdy będą dochodzić kolejne dyscypliny to
będziesz redefiniował tylko widok przez dodanie do definicji widoku 4
linijek kodu: max dla dyscypliny i 3x max dla prób. przypuszczam, że nie
będzie to konieczne bo tabelę dyscyplin można z dużym
prawdopodobieństwem wypełnić wszelkimi możliwymi dyscyplinami.
zaznaczam, że jest to chyba najprostszy wariant rozwiązania. ma pewne
swoje wady ale nie przypuszczam aby były dokuczliwe. z tego co piszesz
widać, że jest możliwość rozbudowania modelu ale na razie sprawdź czy
taki Ci pasuje.
pozdrawiam
geos
---
with z as (
select 1 idz, 'jórek ogórek' as imie from dual union all
select 2, 'kiełbasa sznurek' from dual )
, k as (
select 10 idk, 'znicz warszawa' klub from dual union all
select 20, 'piece koszalin' from dual union all
select 30, 'hutnik ząbki' from dual )
, d as (
select 100 idd, 'bieg na orientację 10km' nazwa from dual union all
select 200, 'bieg na 5km' from dual union all
select 300, 'rzut piłką lekarską 5kg' from dual )
, w as (
select 1 idz, 10 idk, 200 idd, to_date('2017-03-04','YYYY-MM-DD')
data, 1 proba, '3m45' wynik from dual union all
select 1, 10, 200, to_date('2017-03-05','YYYY-MM-DD'), 2, '3m54' from
dual union all
select 2, 30, 300, to_date('2017-06-04','YYYY-MM-DD'), 1, '20m75' from
dual union all
select 1, 10, 200, to_date('2017-03-07','YYYY-MM-DD'), 3, '3m34' from
dual )
---
select
z.imie
, k.klub
, to_number(to_char(w.data,'YYYY')) rok
, to_number(to_char(w.data,'Q')) kwartal
, max(case when d.idd = 100 then d.nazwa end) dyscyplina100
, max(case when w.idd = 100 and w.proba = 1 then w.wynik end) wynik100_1
, max(case when w.idd = 100 and w.proba = 2 then w.wynik end) wynik100_2
, max(case when w.idd = 100 and w.proba = 3 then w.wynik end) wynik100_3
, max(case when d.idd = 200 then d.nazwa end) dyscyplina200
, max(case when w.idd = 200 and proba = 1 then w.wynik end) wynik200_1
, max(case when w.idd = 200 and proba = 2 then w.wynik end) wynik200_2
, max(case when w.idd = 200 and proba = 3 then w.wynik end) wynik200_3
, max(case when d.idd = 300 then d.nazwa end) dyscyplina300
, max(case when w.idd = 300 and proba = 1 then w.wynik end) wynik300_1
, max(case when w.idd = 300 and proba = 2 then w.wynik end) wynik100_2
, max(case when w.idd = 300 and proba = 3 then w.wynik end) wynik100_3
from w
join z on w.idz = z.idz
join k on w.idk = k.idk
cross join d
group by
z.imie
, k.klub
, to_number(to_char(w.data,'YYYY'))
, to_number(to_char(w.data,'Q'))
;
Re: [mysql] Łączenie danych z wielu tabel
Author: geos
Date: Sat, 01 Jul 2017 21:39
Date: Sat, 01 Jul 2017 21:39
14 lines
1677 bytes
1677 bytes
On 01.07.2017 23:26, geos wrote: > group by > z.imie > , k.klub > , to_number(to_char(w.data,'YYYY')) > , to_number(to_char(w.data,'Q')) > ; aby zawodnicy o takich samych imionach i nazwiskach nie robili zamieszania można dorzucić do tego group by kolumnę z.idz. pozdrawiam, geos
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads