sql problem

Problemy związane z tworzeniem i zarządzaniem programami bazo-danowymi.
Regulamin działu


Zadając pytania dotyczące baz danych należy podawać szczegółowe informacje o bazie danych nad którą się pracuje, czyli:

  • Rodzaj serwera bazodanowego: MySql, MSSQL, Oracle itp.
  • Wersja bazy danych
  • Technologia bazodanowa używana w programie: ADO, DbExpress, InterBase
  • Komponenty użyte do zestawienia połączenia: ADOConnection, SqlConnection
  • Sposób zestawienia komponentów bazodanowych np. DataSet - DataSource - DbGrid lub DataSet - DataSetProvider - ClientDataSet - DataSource - DbGrid
  • Jeżeli używane były biblioteki innych firm niż Borland, CodeGeer i Embarcadero proszę podać ich nazwy, numer wersji i adres źródła.

sql problem

Nowy postprzez admszczep » piątek, 16 listopada 2012, 09:51

Witam,
Mam problem zapytanie m SQL. A mianowicie mam 3 tabele
tab1 (urządzenia) tab2 (reklamacje) zgłoszone reklamacje tab3 (czas naprawy)
id_urz nazwa id_urz data ..... id_urz czas naprawy ....
1 aaaa
2 bbbb
3 ccccc
4 dddd

i chciałbym zliczyć ile dla każdego urządzenia było reklamacji i jaki został poświęcony na nie czas join odpada bo zawsze coś pomnoży.

oczekiwany wynik:
id_urz nazwa ilość_rekl czas_napr
1 | aaaa |1 | 1:50
2 | bbbb |2 | 0:30
3 | cccc |0 | 0:00
4 | dddd |5 | 4:58
Avatar użytkownika
admszczep
Homos antropiczny
Homos antropiczny
 
Posty: 66
Dołączył(a): wtorek, 3 listopada 2009, 23:25
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows XP PRO SP3
Kompilator: Embarcadero RAD Studio XE
C++Builder XE
Gadu Gadu: 0
    Windows XPFirefox

Re: sql problem

Nowy postprzez Corvis » piątek, 16 listopada 2012, 09:57

I jaki jest problem ? ;) Nie umiesz zapytani zrobić ? Pokaż mi jak tabele wyglądają. Dokładnie napisz jakie pola są w tabelach, głównie chodzi o relacje. Czyli jakie klucze główne i obce są w jakich tabelach.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows 7Chrome

Re: sql problem

Nowy postprzez admszczep » piątek, 16 listopada 2012, 13:46

zrobiłem takie ale za wolne dla mnie
Kod: Zaznacz cały
select tab1.id_urz, tab1.nazwa, (select count(*) from tab2 where tab2.id_urz=tab1.id_urz) as ilosc, (select sum(koniec-poczatek) from tab3 where tab3.id_urz=tab1.id_urz) as czas from tab1
Avatar użytkownika
admszczep
Homos antropiczny
Homos antropiczny
 
Posty: 66
Dołączył(a): wtorek, 3 listopada 2009, 23:25
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows XP PRO SP3
Kompilator: Embarcadero RAD Studio XE
C++Builder XE
Gadu Gadu: 0
    Windows XPFirefox

Re: sql problem

Nowy postprzez Corvis » piątek, 16 listopada 2012, 14:22

Dobra a czemu by nie tak:

Tabela 1 urządzenia:

idUrzadzenia
NazwaUrzadzenia
...

Tabela 2 Reklamacje

idReklamacji
idUrzadzenia
status <-- otwarte zamkniete
dataRozpoaczenia <-- ustawiana podczas dodawania rekalamcji
dataZakonczenia < -- ustawiania podczas zmiany statusu reklamacji na zamkniete

i jeżeli zmieniasz status na zamknięte do wstawiasz czas do dataZakonczenia

Nie znam dokładnych wymagań systemu, ale już masz jedna tabelę mniej ;)

Nigdy nie używaj count(*) to jest masakra ;)
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows 7Chrome

Re: sql problem

Nowy postprzez admszczep » piątek, 16 listopada 2012, 15:17

Tak ale ta trzecia tabela z czasem wypełniana jest w innym miejscu poprzez import zdarzeń dlatego jest oddzielnie. rozumiem, że zamiast Count(*) lepiej podać tab2.id_urz ale nie ma różnicy w czasie wykonania zapytanie z * i polem taki sam czas
Avatar użytkownika
admszczep
Homos antropiczny
Homos antropiczny
 
Posty: 66
Dołączył(a): wtorek, 3 listopada 2009, 23:25
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows XP PRO SP3
Kompilator: Embarcadero RAD Studio XE
C++Builder XE
Gadu Gadu: 0
    Windows XPFirefox

Re: sql problem

Nowy postprzez Corvis » piątek, 16 listopada 2012, 15:44

Musisz sprawdzić ile kto w jakim czasie naprawił urządzeń dlatego chcesz mieć takie szczegóły ?? można to rozbić jeszcze na poszczególne czynności naprawcze.

Ciężko mi tutaj domyślać się co i jak ma działać. Ale z tego co widzę:

1. Pobierasz id urządzenia
2. Pobierasz nazwę urządzenia
3. Pobierasz ilość wszystkich reklamacji na urządzenie o ID
4. Wyliczasz czas naprawy urządzenia o DANYM ID i robisz SUMĘ tego czasu

Moim zdaniem tak jak jest to napisane nie będzie działać dobrze, ale nie mając bazy i testowych danych ciężko mi napisać lepsze zapytanie. Wpierw wyjdź od poprawnej kolejności w takim zapytaniu:

Kod: Zaznacz cały
select
tab2.id_rz,
tab1.nazwa
from tab2
join tab1 on (tab2.id_urz = tab1.id_urz);


Tutaj wpierw pobierasz informacje o dostępnych reklamacjach potem dobierasz do nich dodatkowe info takie jak nazwa urządzenia. Ta kolejność ma bardzo duże znaczenie bo urządzeń możesz mieć 50 000 a reklamacji tylko 100 :)
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows 7Chrome

Re: sql problem

Nowy postprzez admszczep » piątek, 16 listopada 2012, 15:50

Twoje zapytanie działa prawidłowo przy 2 tabela i od niego zacząłem moje boje ale po dodaniu 3 tabeli robi się meksyk więc albo długie liczenie albo algorytm do importu, który wpisuje wartości do pól reklamacji i wtedy będzie ok.
Avatar użytkownika
admszczep
Homos antropiczny
Homos antropiczny
 
Posty: 66
Dołączył(a): wtorek, 3 listopada 2009, 23:25
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows XP PRO SP3
Kompilator: Embarcadero RAD Studio XE
C++Builder XE
Gadu Gadu: 0
    Windows XPFirefox

Re: sql problem

Nowy postprzez Corvis » piątek, 16 listopada 2012, 15:52

Kod: Zaznacz cały
select
tab2.id_rz,
tab1.nazwa
from tab2
left join tab3 on (tab2.id_urz = tab3.id_urz)
join tab1 on (tab2.id_urz = tab1.id_urz)


Zobacz tak, ale tak jak mówię strzelam trochę w ciemno bo nie mam jak testować :)

EDIT:

Powaliłem kolejność teraz powinno być OK

EDIT 2:

Teraz tam gdzie przy reklamacjach nie masz czasu naprawy będziesz miał NULL możesz null zamienić na 0 przy użyciu ifnull i wszystko powinno śmigać.
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows 7Chrome

Re: sql problem

Nowy postprzez Corvis » piątek, 16 listopada 2012, 15:59

Nie podałeś też sposobu grupowania danych. Czy czas naprawy ma być dla urządzeń o danym ID w danej reklamacji czy ogólnie ?
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows 7Chrome

Re: sql problem

Nowy postprzez admszczep » piątek, 16 listopada 2012, 16:00

tak zrobi z left'em ale jak dodasz obliczenia na polach z count lub sum to już nie jest to co potrzebuje bo muszę mieć ogólny czas i ogólną ilość reklamacji w podanym okresie więć tak nie wyjdzie. Bo dla joinów on liczy wartość dla każdego rekordu. robiłem już nawet operację sumowania z warunkami ale wtedy zgadza mi się tylko czas a ilość operacji jest powiększona o ilość zarejestrowanych czasów dla danej reklamacji, niestety czasów może być więcej niż reklamacji . myślałem jeszcze o union ale nie wiem do końca jak to działa tam jest opcja bez powtórzeń
Avatar użytkownika
admszczep
Homos antropiczny
Homos antropiczny
 
Posty: 66
Dołączył(a): wtorek, 3 listopada 2009, 23:25
Podziękował : 2
Otrzymał podziękowań: 0
System operacyjny: Windows XP PRO SP3
Kompilator: Embarcadero RAD Studio XE
C++Builder XE
Gadu Gadu: 0
    Windows XPFirefox

Re: sql problem

Nowy postprzez Corvis » piątek, 16 listopada 2012, 16:06

Jak chcesz to zrób kopię bazy danych z przykładowymi danymi w pliku SQL z prześlij mi na PW to sprawdzę. Wydaje mi się, że nie używasz group by i dlatego ci źle wychodzi. Używając instrukcji sum, count bez group by - to proszenie się o kłopoty. Ale mogę się mylić bo jak mówię nie mam danych i możliwość sprawdzenia tego. Czyli składamy to do kupy. Potrzebujesz mieć informację:

Ilość wszystkich reklamacji
Czas przeznaczony na naprawę tych reklamacji

w podanym przez użytkownika okresie czasu ??

I jeszcze jedno w czym jest ten czas data, godzina, dataGodzina oraz gdzie ta informacja jest trzymana ?? Naprawdę jak byś wrzucił pełną strukturę tabel 2 i 3 inna gadka by była.

Dodane

Kod: Zaznacz cały
select  tab2.id_urz, tab1.nazwa,  (select count(tab3.id_urz) from tab3 were tab3.id_urz = tab2.id_urz group by tab3.id_urz) as Ilosc
from tab2 join tab1 on ( tab2.id_urz = tab1.id_urz)


Zobacz czy to ci zadziała i porównaj czasy wykonania ze swoim zapytaniem ale bez wyliczania czasu naprawy.
Ostatnio edytowano piątek, 16 listopada 2012, 18:06 przez Corvis, łącznie edytowano 1 raz
"Sukcesy trwają, dopóki ich ktoś nie spieprzy. Porażki są wieczne"

Dr Gregory House
Avatar użytkownika
Corvis
Programista I
Programista I
 
Posty: 880
Dołączył(a): sobota, 26 lipca 2008, 00:31
Podziękował : 80
Otrzymał podziękowań: 30
System operacyjny: WINDOWS 7 64-bity
Kompilator: Praca - C++ Builder XE2 ENTERPRISE - Update 4, Dom - C++ Builder XE4 - Uddate 1
Gadu Gadu: 0
    Windows 7Chrome


Powrót do Bazy danych

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 2 gości

cron