[SQL] Pomoc w zapytaniu
Mariusz Bukowski - 09-01-2007 00:01
[SQL] Pomoc w zapytaniu
Witam ,
Jest to moje pierwsze podejscie do tematu mySql + php. Prosze grupowiczow o pomoc ( mam nadzieje ze dobrze opisze oproblem)
Stworzyłem dwie table :
tabela1 : id_urzadzenia, nazwa
tabela2 : id_urzadzenia, data, czas, dana1, dana2
Chciałbym wyświetlić dla kazdego id_urzadzenia z tabeli1 najbardziej aktualny wpis danych do tabeli2 ( po dacie i godzinie)
Stworzyłem zapytanie :
SELECT tabela1.id_urzadzenia, tabela1.nazwa, tabela2.data, tabela2.czas, tabela2.dana1, tabela2.dana2 FROM tabela1 LEFT JOIN tabela2 ON tabela1.id_urzadzenia=tabela2.id_urzadzenia ORDER BY tabela1.id_urzadzenia
Ktorego wynik obrabiam w php.
Aktualnie w tabeli1 znajduje 200 urządzen, a w tabeli2 kazde urzadzenie ma juz srednio 30 wpisów.
I tutaj moje zmartwienie polega na tym , iz codziennie przyrasta duzo wpisow do tabeli2 i niedlugo moj pomysł zacznie działac bardzo wolno. Czy jest mozliwe stworzenie jednego zapytania ktore zwroci najbadziej aktualne dane ( data, godzina) z tabeli2 dla kazdego urzadzenia z tabeli1 ?
Pozdrawiam ,
Mariusz
p.s Probuje to zrobic od dwoch dni - stosowałem GROUP BY i MAX ale nie poradziłem sobie. Dodam ze beze mam 4.0 wiec nie działają podzapytania. Nie moge dokonac zmiany bazy.
mwgomez - 09-01-2007 00:01
Nie wiem czy dobrze zrozumiałem problem, ale moja propozycja jest nastepująca:
1) Ważniejsza dla nas jest tabela2: SELECT a.id_urzadzenia, b.nazwa, a.data, a.czas, a.dana1, a.dana2 FROM tabela2 a, tabela1 b where a.id_urzadzenia = b.id_urzadzenia ORDER BY a.id_urzadzenia
2) Skoro ma być najbardziej aktualne po (data, czas) to chyba najpierw można dodać order by a.id_urzadzenia, a.data, a.czas
3) Skoro zapisy dodawane są codziennie to nie można po prostu zrobić select na dzień dzisiejszy, albo założyć osobne tabele na każdy dzień?
4) Można wykonywać select na każde urządzenie osobno where tabela2.id_rzadzenia = nr_urzadzenia order by data, czas wówczas w pierwszym wierszu mamy najbardziej aktualny wpis
5) do tabela2 dodałbym własne idtabela2 co umożliwi wyłowienie pojedyńczego rekordu, a dalej mozna by utworzyć trzecią tabelkę w której można zapamiętywać ostatnie idtabela2.
Wydaje mi się, że zwolnienie powinno być chyba dopiero zauważalne, gdy każde urządzenie miałoby po kilkdziesiąt tysięcy wpisów (to sa na prawdę małe tabelki po kilka pól), ale to jest subiektywne i zależy od wielu aspektów.
Pozdrawiam
-- Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
Mariusz Bukowski - 09-01-2007 00:01
> > 2) > Skoro ma być najbardziej aktualne po (data, czas) to chyba najpierw można > dodać > order by a.id_urzadzenia, a.data, a.czas >
Tak, ale nadal otrzymam po kilkadzisiat wpisow dla danego urzadzenia, a nie jeden najbardziej aktualny. I znowu bedzie trzeba zaprząc php do obrobki.
Moze pytam o konstrukcje mysql nie mozliwe do zrealizowania za jednym zapytaniem ?
> 3) > Skoro zapisy dodawane są codziennie to nie można po prostu zrobić select > na > dzień dzisiejszy, albo założyć osobne tabele na każdy dzień? >
Niektore urzadzenia mogą ulec awarii i nie bedzie wpisu z dzisiejszego dnia, ale najbardziej aktualnym bedzie np wpis z poprzedniego dnia - i taki wpis musze wyciągnąc. Zakladanie osobnej tabeli dla kazdego dnia nie bedzie optymalne ze wzgledu na rysowanie wykresow z otrzymanych danych. Lepiej wyciagac dane z jednej tabeli, niz z 360 jezeli bede chcial narysowac wykres danych z okresu roku.
> 4) > Można wykonywać select na każde urządzenie osobno > where tabela2.id_rzadzenia = nr_urzadzenia > order by data, czas > wówczas w pierwszym wierszu mamy najbardziej aktualny wpis
To powoduje ze bede miał tyle selectow ile urządzen. Docelowo w bazie bedzie 600 urządzeń, codziennie beda dochodzic 3 wpisy dla kazdego urządzenia. Czy takie rozwiazanie jest optymalne ? Moze martwie sie niepotrzebnie....
> > 5) > do tabela2 dodałbym własne idtabela2 co umożliwi wyłowienie pojedyńczego > rekordu, a dalej mozna by utworzyć trzecią tabelkę w której można > zapamiętywać > ostatnie idtabela2. >
Własnie to uczyniłem, dodałem do tabela2 id_wpisu, mozesz powiedziec cos wiecej na ten temat ?
> > Pozdrawiam >
Pozdrawiam i dziekuje ze odpowiedz.
Mariusz Bukowski
krycek6@wp.pl - 09-01-2007 00:01
On 8 Sty, 03:04, "Mariusz Bukowski" <mari...@telemetria.eu> wrote:
> Stworzyłem dwie table : > > tabela1 : id_urzadzenia, nazwa > > tabela2 : id_urzadzenia, data, czas, dana1, dana2 > > Chciałbym wyświetlić dla kazdego id_urzadzenia z tabeli1 najbardziej > aktualny wpis danych do tabeli2 ( po dacie i godzinie) > > Stworzyłem zapytanie : > > SELECT tabela1.id_urzadzenia, tabela1.nazwa, tabela2.data, tabela2.czas, > tabela2.dana1, tabela2.dana2 > FROM tabela1 > LEFT JOIN tabela2 ON tabela1.id_urzadzenia=tabela2.id_urzadzenia > ORDER BY tabela1.id_urzadzenia >
Spróbuj wybierac maksymalna wartosc korzystajac ze samozłączenia wewnętrznego z warunkiem tabela2.czas_modyfikacji <= ta_sama_tabela.czas_modyfikacji. Powinno to zastąpić podzapytanie z MAX()
Pisane z głowy bez sprawdzenia:
SELECT tabela1.id_urzadzenia, tabela1.nazwa, tabela2.data, tabela2.czas, tabela2.dana1, tabela2.dana2 FROM tabela1 LEFT JOIN (tabela2 join tabela2 do_maks on tabela2.id_urzadzenia = do_maks.id_urzadzenia and tabela2.data >= do_maks.data and tabela2.czas >= do_m aks.czas) ON tabela1.id_urzadzenia=tabela2.id_urzadzenia ORDER BY tabela1.id_urzadzenia
mwgomez - 09-01-2007 00:01
Myślałem o czymś takim: Jeżeli teraz tabela2 ma "id_wpisu" to tworzymy trzecią tabelę np tabela3 z polami: id, id_urzadzenia, id_wpisu Teraz po każdym INSERT do tabela2 dla danego urządzenia wykonujemy również aktualizację wiersza w trzeciej tabeli dzięki czemu w tabeli3 mamy dla każdego urządzenia tylko dane jego ostatniego wpisu. Taka operacja to jest tylko jeden dodatkowy insert na każdy insert do tabela2, to nie jest żądne obciążenie dla bazy danych.
Jeżeli chodzi o to czy coś jest optymalne czy nie - chyba najprościej będzie utworzyć na boku bazę testową - wpisac do niej fikcyjne dane i stoper do ręki :)
Pozdrawiam
-- Wysłano z serwisu OnetNiusy: http://niusy.onet.pl
Mariusz Bukowski - 09-01-2007 00:01
> Jeżeli teraz tabela2 ma "id_wpisu" to tworzymy trzecią tabelę np tabela3 z > polami: > id, id_urzadzenia, id_wpisu > Teraz po każdym INSERT do tabela2 dla danego urządzenia wykonujemy również > aktualizację wiersza w trzeciej tabeli dzięki czemu w tabeli3 mamy dla > każdego > urządzenia tylko dane jego ostatniego wpisu. Taka operacja to jest tylko > jeden > dodatkowy insert na każdy insert do tabela2, to nie jest żądne obciążenie > dla > bazy danych. >
Wielkie dzieki, to chyba najlpesze rozwiazanie.
Pozdrawiam,
Mariusz
Rafal - 09-01-2007 00:01
>SELECT tabela1.id_urzadzenia, tabela1.nazwa, tabela2.data, tabela2.czas, >tabela2.dana1, tabela2.dana2 >FROM tabela1 >LEFT JOIN tabela2 ON tabela1.id_urzadzenia=tabela2.id_urzadzenia
ORDER BY data DESC, czas DESC , tabela1.id_urzadzenia ASC LIMIT 100
pozdrawiam Rafal sxat -- Archiwum grupy: http://niusy.onet.pl/pl.comp.bazy-danych
mattoid - 09-01-2007 00:01
Dnia Mon, 8 Jan 2007 03:04:07 +0100, Mariusz Bukowski napisał(a):
> Stworzyłem dwie table : > tabela1 : id_urzadzenia, nazwa > tabela2 : id_urzadzenia, data, czas, dana1, dana2 > Chciałbym wyświetlić dla kazdego id_urzadzenia z tabeli1 najbardziej > aktualny wpis danych do tabeli2 ( po dacie i godzinie)
Witam! Nie używałem co prawda mySql-a ale sądzę, że nie powinno być problemów. W MS SQL Server można zrobić to np. w ten sposób, bez podzapytań, itp. działań.
SELECT TOP(1) T1.id_urzadzenia ,T1.nazwa ,T2.data ,T2.czas ,T2.dana1 ,T2.dana2 FROM tabela1 AS T1 JOIN tabela2 AS T2 ON T1.id_urzadzenia = T2.id_urzadzenia ORDER BY T2.data ,T2.czas
Oczywiście można stworzyć również widok prezentujący dane w dowolnym układdzie i z niego wybierać jedną wartość z posortowanej wcześniej w odpowiedni sposób listy.
-- Pozdrawiam mattoid
Mariusz Bukowski - 09-01-2007 00:01
> > Witam! > Nie używałem co prawda mySql-a ale sądzę, że nie powinno być problemów. > W MS SQL Server można zrobić to np. w ten sposób, bez podzapytań, itp. > działań. > > SELECT TOP(1) T1.id_urzadzenia > ,T1.nazwa > ,T2.data > ,T2.czas > ,T2.dana1 > ,T2.dana2 > FROM tabela1 AS T1 > JOIN tabela2 AS T2 > ON T1.id_urzadzenia = T2.id_urzadzenia > ORDER BY T2.data > ,T2.czas >
Niestety wprowadzenie TOP(1) powoduje błąd.
Pozdrawiam
Mariusz
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
jak to =?ISO-8859-2?Q?zrobi=E6=2E=2E=2E=3F_TSQL_sql_server?==?ISO-8859-2?Q?_?=
Jak =?windows-1250?Q?pobra=E6_szacowan=B9_wielko=9C=E6_zbiory_wy nikowego_w_MS?==?windows-1250?Q?_SQL_2005=3F?=
=?iso-8859-2?Q?=5BMS_SQL=5D_Czy_mo=BFna_wywo=B3a=E6_funkcje_t ylko_raz_dla?==?iso-8859-2?Q?_ca=B3ego_zbioru_=BCr=F3d=B3owego=3F?=
[MSSQL] =?ISO-8859-2?Q?zgodno=B6ci_z_licencjami_Microsoft_?==?ISO-8859-2?Q?SQL_Server?=
=?ISO-8859-2?Q?k=B3opot_z_uruchomieniem_MY_SQL_dla_C?==?ISO-8859-2?Q?MS_i_CRM_na_Fedora_Core_3?=
Oracle PL/SQL Wstawianie =?ISO-8859-2?Q?wynik=F3w_kolekcji_d?==?ISO-8859-2?Q?o_tabeli?=
[MSSQL] ACCESS - SQL =?ISO-8859-2?Q?B=B3ad_w_konwersji_lic?==?ISO-8859-2?Q?zb?=
[Oracle PL/SQL] Cursor i zapis =?ISO-8859-2?Q?rekord=F3w_do_?==?ISO-8859-2?Q?kolejnych_plik=F3w?=
=?iso-8859-2?Q?=5BMySQL=5D_Co_minimalnie_potrzebne_zeby_mie=E 6_klienta_My?==?iso-8859-2?Q?SQL_na_Linuxie=3F?=
[newbie] MS SQL - praca =?ISO-8859-2?Q?jednocze=B6nie_na_2_?==?ISO-8859-2?Q?bazach_=28linkowanie_=3F=29?=
zanotowane.pldoc.pisz.plpdf.pisz.plmelooonka.opx.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|