Jakie zapytanie SQL wybierającej dane wedle kryterium

0

Witam,
mam problem ze stworzeniem zapytania zliczającego ilość rekordów z tabeli wedle określonego kryterium.
Korzystam z InterBase SQL w wersji 6.0. Interfejs do bazy mam w Borland Builder C++ 2009, ale to mniej istotne. Baza zawiera kilka tabel i jeden widok (VIEW) prezentujący dane z trzech tabel.
Widok SZCZEGOLY wygląda w dużym uproszczeniu tak:

ADRES NR DOMU CENA
Ulica1 23 2000
Ulica1 24 3000
Ulica2 30 2000
Ulica2 70 2500
Ulica2 91 3000
Ulica3 82 1000
Ulica3 23 2000
Potrzebuje napisać zapytanie SQL które wyliczy z widoku SZCZEGOLY ilość rekordów gdzie np.: CENA>2400, pogrupowanych wedle ADRESU. Czyli wynik zapytania powinien wyglądać tak:
ADRES ILOSC
---------------- ----------------
Ulica1 1
Ulica2 2
Ulica3 0
Zapytanie to mogłoby wyglądać np. tak:
select ADRES, count(CENA>2400) as ILOSC from SZCZEGOLY group by ADRES

Jednak oczywiście wyrażenie count(CENA>2400) jest niedopuszczalne.
Próbowałem tego dokonać za pomocą procedur, ale nie jestem aż tak zaznajomiony z językiem SQL i szczerze powiedziawszy procedur nie znam :-(
Czy ma ktoś jakiś pomysł jak to ugryźć? I czy jeśli bez procedur się nie obejdzie, mógłby ktoś mnie ukierunkować co i jak się do tego zabrać?
Bardzo proszę o pomoc :-)

0

przecież to są podstawy SQLa! Poczytaj o HAVING

0

**HAVING ** ani **WHERE ** się tu właśnie nie nadają, bo wykluczają one wszystkie rekordy gdzie ILOSC jest równa 0!
Czyli w przykładzie, w wyniku rekord Ulica3 nie zostanie w ogóle wyświetlony, a nie o to mi chodzi.

1

ech. Dalej twierdzę, że to podstawy SQLa i wystarczyło pomyśleć
jak ci brakuje czegoś to trzeba to dodać

select adres, count(*) ile from dupa where cena > 2400 group by adres
union
select adres, 0 from dupa group by adres having max(cena) <= 2400

albo zapytać o wszystkie od razu i dodać ilość

select
  a.adres,
  COALESCE(b.ile, 0)
from
  (select distinct adres from dupa) a
  left join (select adres, count(*) ile from dupa where cena > 2400 group by adres) b on a.adres = b.adres
0

Dzięki Misiekd za pomoc :-) właśnie o to mi chodziło.
Wybrałem rozwiązanie pierwsze, gdyż InterBase w wersji 6.0 nie zna funckji COALESCE
Być może to są podstawy SQL, których jak się okazuje nie mam jeszcze za bardzo opanowanych, ale chciałem jeszcze pociągnąć dalej ten sam wątek, bo okazuje się, że mój problem jest większy. Otóż, jeśli chciałbym z tabeli SZCZEGÓŁY wyliczyć dwie rzeczy, np.: ilość rekordów gdzie np.:
CENA>2400
oraz ilość rekordów gdzie np.: NR_DOMU>25 pogrupowanych wedle ADRES?
Wynik miałby wyglądać tak:

ADRES ILE_NR ILE_CEN
Ulica1 0 1
Ulica2 2 2
Ulica3 2 0
Jak w takim wypadku sformułować zapytanie, gdzie mam dwa niezależne warunki?
0

jak to niezależne warunki? Jak mają być spełnione oba to AND i w WHERE i w HAVING a jak ma być spełniony co najmniej jeden to OR. Tylko najpierw musisz zrozumieć dlaczego w HAVING jest max(cena) <= 2400 :)

0

W HAVING jest Max(cena)<=2400, gdyż zlepiamy wyniki gdzie warunek cena>2400 jest spełniony (wyliczamy w ilu przypadkach) z wynikami gdzie warunek ten nie jest spełniony (rekordy z zawartością 0). Gdyby HAVING Max(cena)<=2400 nie było, w wyniku zapytania dwukrotnie zwracane byłyby rekordy dla spełnionego warunku cena>240.
Nie wiem czy w poprzednim zapytaniu się jasno wyraziłem. W stwierdzeniu niezależne warunki mam na myśli coś takiego:

SELECT adres, COUNT(nr_domu) WHERE nr_domu > 25,  COUNT(cena) WHERE cena > 2400 FROM szczegoly GROUP BY adres
.....

Nie wiem jak sforumułować tego typu pytanie z dwoma warunkami. Ani łącznik OR ani AND do tych warunków nie pasują, bo ja chcę po prostu wybrać ilość nr_domu>25 pogrupowanych po adres oraz ilość cena>2400 pogrupowanych po adres. Nie wiem czy jasno się wyraziłem :-)

0

to musisz rozbić na dwa oddzielne zapytania raz dla nr_domu a raz dla cena, o ile dobrze rozumiem co chcesz dostać

0

Czyli najprościej po prostu utworzyć dwa widoki takim sposobem j/w, zawierające pola ADRES, ILE_NR oraz ADRES, ILE_CEN. A następnie widoki te połączyć poprzez komendę JOIN? Bo jak inaczej można użyć dwa razy **SELECT **w jednym zapytaniu?
Żeby było jasne o co mi chodzi. W wyniku zapytania, z tabeli SZCZEGOLY (jak w poście pierwszym) chciałbym uzyskać taki rezultat:

ADRES ILE_NR ILE_CEN
Ulica1 count(NR>25) count(CENA>2400)
Ulica2 count(NR>25) count(CENA>2400)
Ulica3 count(NR>25) count(CENA>2400)
1
SELECT
  a.adres,
  case when b.ile is null then 0 else b.ile end ile_cen
  case when c.ile is null then 0 else c.ile end ile_nr
FROM
  (SELECT DISTINCT adres FROM dupa) a
  LEFT JOIN (SELECT adres, COUNT(*) ile FROM dupa WHERE cena > 2400 GROUP BY adres) b ON a.adres = b.adres
  LEFT JOIN (SELECT adres, COUNT(*) ile FROM dupa WHERE nr > 25 GROUP BY adres) c ON a.adres = c.adres
0

Dzięki wielkie za pomoc :)
Niewątpie, że rozwiązanie działa, ale problem jest tej natury, że niestety korzystam ze starego (bo był darmowy) InterBase 6.0, który nie zna CASE ... THEN ... ELSE :(
Ponadto nie przyjmuje on zapytań zawierających dwa SELECTy? Dziwne....
Ale znalazłem inne rozwiązanie mojego problemu. Nieco prostsze choć wymagające więcej pracy.
Ponieważ u mnie wartości liczbowe używane do pównania w warunkach (np. CENA > const, NR > const) są zawsze stałe, toteż do tabeli SZCZEGOŁY dołożę nowe kolumny, które zawierać będą wartości 0 lub 1, świadczące o spełnieniu/niespełnieniu warunku. Następnie będę zliczał sumę tej kolumny pogrypowaną po ADRESie.
Jeszcze raz dzięki wielkie za pomoc!

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