Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

SQL Firebird - sortowanie po okresach

08 Sie 2012 11:36 2764 11
  • Poziom 12  
    Witam Wszystkich.
    Mam pewien problem ze zbudowanie zapytań do bazy tak by w wyniku otrzymać dane zagregowane wg okresów np. 5dni. Lub mówiąc inaczej po 5dni. Przykładowo mam tabelę i pola: id, data, ilość, zdarzenie teraz dane przykładowe:
    id data ilosc zdarzenie
    1 2012-08-01 2 1
    2 2012-08-02 2 1
    3 2012-08-03 2 1
    4 2012-08-05 2 1
    5 2012-08-06 2 1
    ................. itd. a w wyniku chcę uzyskać coś takiego np co 3 dni i suma ilości i zdarzeń:
    ID suma_ilosc suma_zdarzen
    1 6 3
    2 4 2
    .................. itd. Moje rozwiązanie nie do końca działa

    Kod: sql
    Zaloguj się, aby zobaczyć kod


    Z góry dziękuję za jakiekolwiek sugestie
  • Poziom 16  
    a czemu akurat co 3 dni?
    Nie wiem jak to jest w firebird ale może spróbuj wyjąc z danej daty dzień tygodnia i po nim na przykład pogrupuj

    Moderowany przez arnoldziq:

    Bo tego wymaga projekt.
    Kolejna taka bezsensowna uwaga zostanie nagrodzona Ostrzeżeniem.

  • Poziom 40  
    To ma być grupowanie po 3 dni "kalendarzowe" (1, 2, 3 - I grupa, 4, 5, 6 - II grupa etc.), czy po 3 dni dostępne w bazie (jak w Twoim przykładzie - gdzie brakuje 4-go)?

    Te daty mogą występować po kilka razy te same, czy są niepowtarzalne?

    Ja co prawda w samym Firebirdzie za dużo nie pisałem, ale generalnie zasada w przypadku podziału na dni "kalendarzowe" w obrębie roku mogła by być taka:
    zdefiniuj sobie dodatkową kolumnę z dniem roku (YEARDAY), ewentualnie ilość dni od jakiejś daty. Numer dnia (z zakresu 1 - 365) podziel przez 3 i weź część całkowitą (to albo będzie w standardzie, albo znajdziesz sobie odpowiednią funkcję zaokrąglającą) - to będzie numer Twojej "grupy", po którym potem możesz próbować grupować w klauzuli GROUP BY.
  • Poziom 16  
    Drogi Moderatorze,
    Cytat:

    Bo tego wymaga projekt.
    Kolejna taka bezsensowna uwaga zostanie nagrodzona Ostrzeżeniem.

    To pytanie nie jest bez sensowne tylko uściślające ponieważ pojawiają się trzy przykładowe liczby:3 dni, 5 dni, w zapytaniu 12 dni.Dlatego pytam:).
    Najprościej będzie dany zakres pojedynczych dat zgrupować po wyniku funkcji konwertującej.Może właśnie po numerze tygodnia z daty..
  • Moderator Programowanie
    Drogi Użytkowniku,
    skoro autor pytania sformułował je właśnie w ten sposób, że podał 3 różne okresy, to należy przypuszczać, że w końcowym projekcie okresy te mogą się dowolnie zmieniać.
    Wywołanie zapytania może nastąpić w dowolnym okresie czasu i podejrzewam, że wywołanie okresu 3, 5 czy 35 dni jest równie prawdopodobne.
    Dlatego pytanie :
    Cytat:
    a czemu akurat co 3 dni?

    Uważam za bezsensowne i kompletnie nie związane z tokiem dyskusji.

    A wracając do tematu;
    Zakładając, że mamy taką tablicę :
    Kod: sql
    Zaloguj się, aby zobaczyć kod

    Wypełnioną takimi, przykładowymi danymi:
    SQL Firebird - sortowanie po okresach
    Wystarczy wywołać takie zapytanie :
    Kod: sql
    Zaloguj się, aby zobaczyć kod

    I otrzymujemy taki wynik :
    SQL Firebird - sortowanie po okresach
    Czyli, wydaje mi się, to co autor chciał uzyskać; to znaczy ID zdarzenia, ilość wystąpień w (dowolnym) okresie czasu oraz sumę ilości wystąpień danego zdarzenia w podanym okresie.
  • Poziom 16  
    Hmm to może niech Autor uściśli co tak na prawdę chce :)
    ... i chyba inaczej to rozumiemy:
    Cytat:

    1 2012-08-01 2 1
    2 2012-08-02 2 1
    3 2012-08-03 2 1
    4 2012-08-05 2 1
    5 2012-08-06 2 1
    ................. itd. a w wyniku chcę uzyskać coś takiego np co 3 dni i suma ilości i zdarzeń:
    ID suma_ilosc suma_zdarzen
    1 6 3
    2 4 2


    Jak dla mnie w tym przykładzie dokładnie Autor zaznaczył. Potrzebuje daty z okresu 3 dni pogrupować i zsumować ilość i zdarzenia w tym okresie
  • Poziom 42  
    Proponuję napisać funkcję, która będzie tworzyć grupę na podstawie daty, np przeliczając datę na liczbę dni od początku roku (niestety FB jest tak ubogi w funkcje, że szkoda słów) - trochę matematyki będzie trzeba. NAstępnie otrzymany wynik podzieli przez 3 i taki zwróci. teraz wystarczy zgrupować to tej funkcji.

    / Możliwe, że umieszczenie jej wprost w GROUP BY potraktowane zostanie jako błąd - ach ten FB. Wtedy zrobić SELECT ... FROM (SELECT ... ) i w tym wewnętrznym funkcję umieścić jako rezultat (jeden z rezultatów), a zgrupować w zewnętrznym) /

    Wada tej metody taka, że nie wiesz, jaką grupę data obejmuje.

    PS. JEst możliwe, że do obliczeń o jakich wspomniałem wystarczy tylko zwykłe podzielenie daty przez 3 (in_data / 3), względnie jeszcze scastować to na INT.
  • Poziom 12  
    Wow spore zainteresowanie dziękuję Wszystkim!!
    Do Kolegi marcinj12:
    To ma być dowolny okres, 3 dni to przykład może być 5 czy 12 nie ma znaczenia. Daty oczywiście się powtarzają bo zdarzenia dotyczą różnych indeksów(towarów), których tu nie podałem ale może to mój błąd. Inaczej: tabela przechowuje dane o historii sprzedaży ale w uproszczonym stanie index, datę, ilość transakcji w dniu(zdarzeń), ilość sprzedanych sztuk. Może to coś Wam rozjaśni.

    Do Kolegi Dżyszla
    Tak właśnie w FB nie wszystko się da ale właśnie o to mniej więcej chodzi.
    Doszedłem do wniosku być może błędnego, że utworzę drugą tabelę z wynikam. Zapytanie do pierwszej z zakresem dat np.: od 2010-01-01 do 2010-01-03 da wynik X i Y co przeniosę do tabeli wyników później zapytanie 2 z zakresem o kolejny okres (3 dni to przykład może wystąpić np 11 dni) od 2010-01-04 do 2010-01-07 itd. Po prostu po stronie aplikacji :( Jak sądzicie??

    A do Kolegi arnoldziq:

    Chodzi mi o coś takiego tyle że okres może być dowolny ale równy czyli tak jak
    rok ma 52 tygodnie to tak samo ale na np 3, czy 6 czy 9 dniowe okresy. Dzień i tydzień, miesiąc to są raczej proste :)


    P.S.
    Bardzo dziękuję za odpowiedzi Wszystkim!!!!!!
  • Pomocny post
    Poziom 42  
    Nie ma potrzeby tworzenia ekstra drugiej tabeli, chyba, że chcesz w niej dane po prostu przechowywać w postaci zagregowanej.

    Spróbuj coś na ten wzór (nie mam FB pod ręką):
    Kod: sql
    Zaloguj się, aby zobaczyć kod

    BTW - na pewno potrzebujesz kolumny zdarzenie? Ja w powyższym uwzględniłem, że tam zawsze jest 1 więc nie ma sensu.

    Gdyby powyższe nie dało oczekiwanych rezultatów, to zrób tak w procedurze:
    Kod: sql
    Zaloguj się, aby zobaczyć kod
    To ma tą zaletę, że możesz przy wynikach wyświetlać okresy. Wada: bardzo powolne. Oczywiście nagłówek dorób sam ;) (za dużo się narzędziami w pracy posługuję, więc nie pamiętam, a nie chcę bzdur totalnych popisać ;p) Oczywiście do wyników wystarczy zrobić SELECT * FROM procedura...
  • Poziom 12  
    Dzięki za naprowadzenie na pewno Plus dla Ciebie. Choć oczywiście Wszystkim jestem wdzięczny za zainteresowanie.
    Kod: sql
    Zaloguj się, aby zobaczyć kod


    Małe zmiany które poczyniłem związane są z notacją FB proble jest tylko taki, że indeks podaję z zewnątrz i tylko dla niego uzyskuję obliczenia. Może inaczej dla tych samych dat występują różne wartości sztuk i zdarzeń więc albo tak jak teraz podaję indeks albo trzeba by zrobić jointa :) do tej samej tabeli i wykluczyć te różne indeksy. Ogólnie czas wykonywania nie jest tragiczny ale indeksów ma być docelowo kilkaset tysięcy więc może być kiszka :) Jeżeli zaszczycicie mnie jakimś jeszcze pomysłem będę wdzięczny. Pozdrawiam.
  • Poziom 42  
    JAk mówisz - albo tabela gdzie wpiszesz indeksy i zrobisz skręta, albo - jeśli nie będzie ich nader dużo, to przekaż je jako string (liczby oddzielone przecinkami) a następnie zbuduj zapytanie jako string dołączając swoje indeksy w postaci IN i następnie wykonaj je za pomocą EXECUTE STATEMENT.
  • Poziom 12  
    Witam. Więc rozwiązałem to tak, może komuś się przyda :)
    Kod: sql
    Zaloguj się, aby zobaczyć kod