🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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
#195113
Author: kamil.sobczyk
Date: Mon, 17 Oct 2016 18:02
45 lines
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
#195115
Author: geos
Date: Mon, 17 Oct 2016 20:38
54 lines
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
#195116
Author: geos
Date: Mon, 17 Oct 2016 20:42
17 lines
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
#195117
Author: geos
Date: Mon, 17 Oct 2016 20:45
19 lines
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
#195114
Author: M.M.
Date: Tue, 18 Oct 2016 03:23
43 lines
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
#195118
Author: kamil.sobczyk
Date: Tue, 18 Oct 2016 08:50
75 lines
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
#195119
Author: geos
Date: Tue, 18 Oct 2016 10:18
37 lines
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
#195124
Author: artiun
Date: Tue, 18 Oct 2016 10:40
44 lines
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
#195125
Author: kamil.sobczyk
Date: Tue, 18 Oct 2016 11:00
108 lines
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
#195120
Author: kamil.sobczyk
Date: Tue, 18 Oct 2016 11:04
40 lines
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
#195121
Author: Kamil Sobczyk
Date: Wed, 28 Jun 2017 07:56
58 lines
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
#195122
Author: geos
Date: Sat, 01 Jul 2017 21:26
156 lines
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
#195123
Author: geos
Date: Sat, 01 Jul 2017 21:39
14 lines
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