Jak zrobic z tego jedno zapytanie SQL?


(Spinacz1qaz) #1

W sumie zrobilem projekt. Baza danych hotelu. baza w db2 interfejs w php/html.

Zadaniem tego jest aby z podanych nizej tabel uzuskac dane na temat tego ile hotel zarobil na gosciu 'Kowalski' ale w jednym zapytaniu sql! (gora w dwoch). Ja to zrobie ale w prostacki sposob i przy pomocy php a nie w sql.

create table historia (

  • lp int PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),

(K Chrapa) #2

Witam!

Jesli:

  1. w tabeli historia sa daty wynajecia pokoju

  2. tabela pokoje potrzebna jest nam tylko do cen

to mysle ze moze pojsc cos takiego:

select sum( (JULIAN_DAY(historia.do) - JULIAN_DAY(historia.od) ) *pokoj.cena ) FROM

historia join pokoje using(pokoj)

where historia.nazwisko='Kowalski'

nie pracowalem w db2 , ale wg dokumentacji JULIAN_DAY podaje ilosc dni od poczatku kal. julianskiego .

Jak odejmiesz jedno od drugiego, dostaniesz ilosc dni jakie gosc spedzil.

czyli,

etap 1:

select od,do,(JULIAN_DAY(do) - JULIAN_DAY(od) ) from historia;

Sprawdz,czy dobrze policzyl czas pobytu - nie mam db2 wiec nie przetestuje na szybko.

jesli jest ok,to

etap 2 - wyciagamy tylko dane kowalskiego:

select od,do,(JULIAN_DAY(do) - JULIAN_DAY(od) ) from historia WHERE nazwisko='Kowalski';

etap 3 - podpinamy ceny pokoi:

select historia.od,historia.do,(JULIAN_DAY(historia.do) - JULIAN_DAY(historia.od) ) ,pokoje.cena

from historia join pokoje using(pokoj)

WHERE nazwisko='Kowalski';

etap 4. obliczamy kwoty za kazdy pobyt

select historia.od,historia.do,(JULIAN_DAY(historia.do) - JULIAN_DAY(historia.od) ) * pokoje.cena ,pokoje.cena

from historia join pokoje using(pokoj)

WHERE nazwisko='Kowalski';

etap 5: ladnie sumujemy (trzeba wykopac dwie pierwsze kolumny+ostatnia):

select sum(JULIAN_DAY(historia.do) - JULIAN_DAY(historia.od) ) * pokoje.cena )

from historia join pokoje using(pokoj)

WHERE nazwisko='Kowalski';

Jesli nie zrobilem literowki i sql w db2 ma taka sama skladnie jak w postgresql czy mysql (a pewnie tak), to

powinno pojsc.

pozdrawiam serdecznie,

Kacper Chrapa


(Spinacz1qaz) #3

Nareszcie jakas propozycja [-o<

Nie zupelnie tylko widze gdzie tu jest odniesienie do pokoje ale to dlatego ze nie do konca rozumiem skladnie tego fragmentu: pokoje.cena

from historia join pokoje using(pokoj). Przetestowale i zwraca taki blad :

  • select sum( (JULIAN_DAY(historia.do) - JULIAN_DAY(historia.od) ) *pokoj.cena ) FROM historia join pokoje using(pokoj) where historia.nazwisko='Kowalski'

Jak wpisze ON w miejscu o ktore prosi wymaga nie przyjmujac WHERE, jak dodam jeszcze historia(majac : "join pokoje using(pokoj) ON

historia") wyskakuje:

select sum( (JULIAN_DAY(historia.do) - JULIAN_DAY(historia.od) ) *pokoj.cena ) FROM historia join pokoje using(pokoj) ON pokoje where historia.nazwisko='Kowalski'

  • SQL0104N An unexpected token "where" was found following "ing(pokoj) ON

Co to jest za blad? Rozumiem ze wymaga specyfikacji czegos ale w skladni join nie ma polecenia ON wiec nie specjalnie wiem co robic?

Co do dat to juz dziala normalnie i mozna zkykle odejmowanie do-od zrobic i zwraca integera.

Wilkie dzieki tak czy inaczej za pomoc!! =D

Znalazlem jeszcze cos takiego :

select pokoj, extract(day from do-od)*cena from historia,pokoje where nazwisko='Kowalski' and pokoje.pokoj=historia.pokoj;

ale tutaj mi wyrzuca blad "odniesienie do pokoju dwuznaczne":

SQL0203N A reference to column "POKOJ" is ambiguous. SQLSTATE=42702

Jak ktos ma jeszcze jakies propozycje to prosze piszcie!!


(K Chrapa) #4

WItam!

sproboj tak:

select sum( (JULIAN_DAY(historia.do) - JULIAN_DAY(historia.od) ) *pokoje.cena ) FROM

historia,pokoje where historia.pokoj=pokoje.pokoj and historia.nazwisko='Kowalski'

jest to bardziej tradycyjna skladnia zlaczenia - mam nadzieje,ze pod db2 pojdzie:-)

testowalem oba zapytania pod mysl (tylko pod inna funkcja zamiast julian_day) - i na pewno pojdzie i da

ci wynik, jakiego oczekujesz.Pytanie, jak pod db2 to bedzie wygladalo.

jesli chodzi o "pokoje.cena" - kiedy robisz zlaczenie dwoch tabel, to nazwy kolumn moga sie zdublowac.

dlatego dobrze jest jednoznacznie okreslic "namiary" ,czyli: tabela.kolumna .

Twoje zapytanie sql moze byc troche problematyczne - poniewaz podajesz recznie numery pokoi - mimo

ze sume da sie tam wcisnac:-)

Jesli juz chcesz podzapytaniami:

select sum( (julian_day(do) - julian_date(do))*(select cena from pokoje where pokoje.pokoj=historia.pokoj)) from historia where nazwisko='Kowalski';

powinno pojsc - w kazdym razie, przetestowalem wlasnie pod postgresem - tylko bez julian_date.

gdybys szukal dobrej ksiazki do sql - polecam "SQL dla kazdego" Rafe Coburn. Tytul sugeruje wersje dla

opornych , ale w rzeczywistosci jest to swietna ksiazka, wyjasniajaca kompleksowo sql na poziomie zaawansowanym(aczkolwiek do podstaw). Warto poznac sql'a , jesli chcesz zajmowac sie aplikacjami webowymi-

mozna wiele z niego wycisnac, i bedzie to tez bardziej wydajne niz gdybys mial dane mielic w php.

pozdrawiam,

Kacper


(K Chrapa) #5

Dopiero zauwazylem:

>Znalazlem jeszcze cos takiego :

>select pokoj, extract(day from do-od)*cena from historia,pokoje where nazwisko='Kowalski' and >pokoje.pokoj=historia.pokoj;

>ale tutaj mi wyrzuca blad "odniesienie do pokoju dwuznaczne":

>SQL0203N A reference to column "POKOJ" is ambiguous. SQLSTATE=42702

nie wiem , czy extract zadziala (ale jesli oblicza ilosc dni do-od ) , to jest ok.

Problem w tym,ze kolumna pokoj wystepuje w obu tabelach - musisz wiec wpisac np.: pokoje.pokoj.

(swoja droga, proponuje nazwe w tabeli zrobic nr_pokoju- bedzie bardziej czytelne).

a najlepiej to odpusc to sobie i zrob od razu:

select sum( extract(day from do-od)*cena) from historia,pokoje where nazwisko='Kowalski' and pokoje.pokoj=historia.pokoj;

pozdrawiam,

kacper


(Spinacz1qaz) #6

Wielkie dzieki za pomoc!! [-o<

Ostatecznie:

  • select sum((historia.do-historia.od)*cena) from historia,pokoje where nazwisko='Kowalski' and pokoje.pokoj=historia.pokoj ;

To dziala poprawnie(nawet bez extracta). Tylko bylo trzeba daty doprecyzowac z ktorej tabeli ma brac(historia.do-historia.od).

Jeszcze raz bardzo dziekuje za pomoc. Teraz sie porzadnie zabiore za sql zamiast go omijac php-em.

Problem rozwiazany. Koniec tematu. Uprzejmie prosze adminow o zamkniecie tematu.