Jakie zapytanie SQL wybierającej dane wedle kryterium

Odpowiedz Nowy wątek
2011-10-18 21:49
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 :-)

edytowany 1x, ostatnio: madmike, 2011-10-18 21:55

Pozostało 580 znaków

2011-10-18 22:03
0

przecież to są podstawy SQLa! Poczytaj o HAVING


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2011-10-18 22:11
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.

Pozostało 580 znaków

2011-10-18 23:47
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

- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2011-10-19 13:38
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?

Pozostało 580 znaków

2011-10-19 13:49
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 :)


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2011-10-19 14:38
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 :-)

Pozostało 580 znaków

2011-10-19 15:05
0

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


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2011-10-19 17:44
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)

Pozostało 580 znaków

2011-10-19 21:15
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

- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2011-10-20 10:14
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!

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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