Łączenie danych z wielu tabel

0

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.

0

Zacznijmy od tego, że masz złą strukturę danych.

  1. Czy zawodnik może występować w wielu szkółkach? (czyli że raz id_zawodnik=5 i id_szkolka=5, a innym razem jest inne id_szkolka?) Jeśli nie, to proponuję id_szkolka przeniesc do tabeli zawodnik.
  2. Nazwę pola w tabeli klub(id_klub) zamienic na id_szkolka, bo chyba ma takie znaczenie. Chodzi by to ujemdnolicić.
  3. Te trzy tabele biegowe połączyć w jedną dodająąc kolumnę z wyróżnikiem biegu. Czyli byłaby (id_zawodnik, rok, kwartal, typ_biegu, punkty).

Wtedy zapytanie z grupowaniem po PK (oznaczony powyzej jako podkreslenie)

1

Tak naprawdę to musisz zagregować dane z 3 tabel łącząc je ze sobą, rozwiązań jest kilka, oto jedno z nich, pisane z palca więc moga być błędy, ale idea powinna być zrozumiana:

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

samo pobranie wszystkich kombinacji kwartal rok

SELECT DISTINCT
    ROK
    ,KWARTAL
FROM
    (
    SELECT
        ROK
        ,KWARTAL
    FROM
        BIEG5
    UNION
    SELECT
        ROK
        ,KWARTAL
    FROM
        BIEG10
    UNION
    SELECT
        ROK
        ,KWARTAL
    FROM
        BIEG30
   ) AS DT
0

Podsumowując:

Fakt: zawodnik w danym momencie może być tylko w jednym klubie/szkółce, ale dość istotne są też dane historyczne. Czyli łącząc razem informacje następujące podejście myślę będzie OK:
zawodnik

id_zawodnik (pk)
id_szkolka (pk)
imie_nazwisko

historia zmian klubu/szkółki:
klub_zmiana

id_zawodnik (pk)
id_szkolka (pk)
from
to

a historia zmian osiągniętych wyników jest już do wydobycia z tabel BIEG5..30

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). Dlatego dla przejrzystości (i ewentualnych modyfikacji potem) chciałem, aby każda konkurencja była w osobnej tabeli. Mając jednak na względzie jakie jest rozwiązanie mojego problemu (przedstawione przez Panczo) to chyba 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.

0

Nie mam wiedzy, aby oceniać poprawność dziedzinowa, ale rzuca mi się kilka niespójności (może błędnie):

  1. Co w sytuacji jeśli szkółka ma zawodników w kilku grupach wiekowych?
  2. Nie ładowałbym wszystkiego do jednej tabeli wyniki, albo inaczej dla każdego rodzaju konkurencji założyłbym osobną tabelę i dla biegów pola np. takie: id_zawodnik, id_szkolka, grupa_wiekowa/kategoria, wynik, dystans, czas, miejsce, punkty
  3. Podobnie tabela dla skoku w dal, rzucie piłka lekarską itd.

Zestawienie tego w jednej tabeli moze mieć sens, ale mozna też spokojnie robić do tego widok

0

W sumie sam się zakręciłem ;) - systematyzując jest tak: KLUB --> SZKÓŁKI (dana grupa wiekowa to nowa szkółka w danym klubie).
Fakt dużo by się uprościło grupując to po konkurencjach. Spróbuję może i stworzę sobie widok bazując na przedstawionym przez Ciebie powyżej przykładzie i zobaczę jak to będzie hulało.

0

Po pierwszych szybkich testach działa to rewelacyjnie - dokładnie tak jak chciałem. Nie tworzę nowej tabeli. Widok na podstawie podanego zapytania (aż tyle tych kategorii testów nie będzie, żeby tego nie ogarnąć) jest jak najbardziej OK.
Myślę, że uda mi się to ogarnąć w 6 kategoriach - czyli 6 tabel byłoby łączonych razem. Nie mam doświadczenia - przy takim podejściu będzie to w miarę szybko hulało?

0

Przy bazach danych nikt Ci nie powie, ze to będzie hulało, za duzo czynników które na to wpływają:spżet, indeksy, ilosc danych, zakresy itd.

1 użytkowników online, w tym zalogowanych: 0, gości: 1