zapytanie SQL przedział wiekowy

0

Witam serdecznie.
Mam problem ze stworzeniem kwerendy wyświetlającej mi potrzebne dane.
Mam 2 tabele:

  • [klienci] gdzie jest kolumna [wiek]
  • [tabela] produkty gdzie jest kolumna [nazwa produktu].
    Potrzebuję wyświetlić przedział wiekowy co 5 lat tj <20, 21<25 itd aż do >65 i ilu klientów w danym przedziale wiekowym posiada dany produkt

Poniżej relacje między tabelami
screenshot-20171019173839.png

0

napisz SQLa, który zwróci klienta, produkt i ilość a potem pokażę Ci jak to pogrupować na przedziały

0

Dziękuję za odpowiedź
Poniżej zapytanie zwracające produkt oraz liczbę klientów na produkt i średnią wieku grupy

SELECT Produkty.[nazwa produktu], Count(Klienci.Nazwisko) AS [Ilość klientów], Round(Avg(Klienci.Wiek)) AS [Średnia Wieku]
FROM Produkty INNER JOIN (Klienci INNER JOIN Umowy ON Klienci.id = Umowy.Id_klienta) ON Produkty.[id produktu] = Umowy.Id_produktu
GROUP BY Produkty.[nazwa produktu];

Dodatkowo poniżej klienci i ilość produktów:

SELECT Klienci.id, Klienci.Nazwisko, Count(Produkty.[nazwa produktu]) AS [Ilość produktów]
FROM Produkty INNER JOIN (Klienci INNER JOIN Umowy ON Klienci.id = Umowy.Id_klienta) ON Produkty.[id produktu] = Umowy.Id_produktu
GROUP BY Klienci.id, Klienci.Nazwisko;

0

Rozwiązanie po chłopsku (popraw se etykiety po then)

SELECT
	um.id_produktu,
	case when kl.wiek < 20 then '<20'
		when kl.wiek > 20 and kl.wiek <= 25 then '21-25'
		when kl.wiek > 25 and kl.wiek <= 30 then '21-25'
		when kl.wiek > 30 and kl.wiek <= 35 then '21-25'
		when kl.wiek > 35 and kl.wiek <= 40 then '21-25'
		when kl.wiek > 40 and kl.wiek <= 45 then '21-25'
		when kl.wiek > 45 and kl.wiek <= 50 then '21-25'
		when kl.wiek > 50 and kl.wiek <= 55 then '21-25'
		when kl.wiek > 55 and kl.wiek <= 60 then '21-25'
		when kl.wiek > 60 and kl.wiek <= 65 then '21-25'
		when kl.wiek > 65 then '65+'
	end as przedzial_wiekowy,
	count(*) ilosc
FROM
	produkty prod left join
	umowy um on um.id_produktu = prod.id_produktu left join
	klienci kl on kl.id = um.id_klienta
GROUP BY
	um.id_produktu,
	case when kl.wiek < 20 then '<20'
		when kl.wiek > 20 and kl.wiek <= 25 then '21-25'
		when kl.wiek > 25 and kl.wiek <= 30 then '21-25'
		when kl.wiek > 30 and kl.wiek <= 35 then '21-25'
		when kl.wiek > 35 and kl.wiek <= 40 then '21-25'
		when kl.wiek > 40 and kl.wiek <= 45 then '21-25'
		when kl.wiek > 45 and kl.wiek <= 50 then '21-25'
		when kl.wiek > 50 and kl.wiek <= 55 then '21-25'
		when kl.wiek > 55 and kl.wiek <= 60 then '21-25'
		when kl.wiek > 60 and kl.wiek <= 65 then '21-25'
		when kl.wiek > 65 then '65+'
	end
0

Super, dzięki za pomoc. Po kilku modyfikacjach kod wygląda jak poniżej

SELECT
    produkty.[nazwa produktu],
 SWITCH(  
        (klienci.wiek < 20), '<20',
        (klienci.wiek >= 20 AND klienci.wiek <= 25), '20-25',
        (klienci.wiek > 25 AND klienci.wiek <= 30) , '26-30',
        (klienci.wiek > 30 AND klienci.wiek <= 35) , '31-35',
        (klienci.wiek > 35 AND klienci.wiek <= 40) , '36-40',
        (klienci.wiek > 40 AND klienci.wiek <= 45) , '41-45',
        (klienci.wiek > 45 AND klienci.wiek <= 50) , '46-50',
        (klienci.wiek > 50 AND klienci.wiek <= 55) , '51-55',
        (klienci.wiek > 55 AND klienci.wiek <= 60) , '56-60',
        (klienci.wiek > 60 AND klienci.wiek <= 65) , '61-65',
        (klienci.wiek > 65),  '65+'
              ) AS [Przedzial wiekowy],
    
COUNT(klienci.id) as [ilość klientów]
FROM Klienci
    Left JOIN (Umowy Left JOIN Produkty ON Produkty.[id produktu] = Umowy.Id_produktu) ON Klienci.id = Umowy.Id_klienta
GROUP BY
    produkty.[nazwa produktu],
 SWITCH(  (klienci.wiek < 20), '<20',
       (klienci.wiek >= 20 AND klienci.wiek <= 25), '20-25',
        (klienci.wiek > 25 AND klienci.wiek <= 30) , '26-30',
        (klienci.wiek > 30 AND klienci.wiek <= 35) , '31-35',
        (klienci.wiek > 35 AND klienci.wiek <= 40) , '36-40',
        (klienci.wiek > 40 AND klienci.wiek <= 45) , '41-45',
        (klienci.wiek > 45 AND klienci.wiek <= 50) , '46-50',
        (klienci.wiek > 50 AND klienci.wiek <= 55) , '51-55',
        (klienci.wiek > 55 AND klienci.wiek <= 60) , '56-60',
        (klienci.wiek > 60 AND klienci.wiek <= 65) , '61-65',
        (klienci.wiek > 65),  '65+' );

Idąc dalej...Czy użycie Switch/Case to jedyna droga? Co w przypadku gdy przedziałów jest więcej

2

Gdy przedziałów jest więcej... użyj matematyki.
Case when wiek<20 then 20 when wiek>80 then 80 else 5*(wiek/5) end

1

@Marcin.Miga: dawno nie używałeś Accessa ;) To co napisałeś sprawdzi się w t-sql, ale MsAccess to inna liga: dzielenie intów potraktuje nie jak inty i zwróci double...
To w MSAccess realizujemy operatorem: \

Czyli zapytanie trzeba tak:

SELECT
	produkty.[nazwa produktu],
	SWITCH(  
			klienci.wiek<=20," do 20"
			,klienci.wiek>65,"65+"
			,1,((klienci.wiek-1)\5)*5+1 & "-" & ((klienci.wiek-1)\5+1)*5 
	) AS [Przedzial wiekowy],
	COUNT(klienci.id) as [ilość klientów]
FROM 
	Klienci
	Left JOIN (Umowy Left JOIN Produkty ON Produkty.[id produktu] = Umowy.Id_produktu) ON Klienci.id = Umowy.Id_klienta
GROUP BY
	produkty.[nazwa produktu],
	SWITCH(  
			klienci.wiek<=20," do 20"
			,klienci.wiek>65,"65+"
			,1,((klienci.wiek-1)\5)*5+1 & "-" & ((klienci.wiek-1)\5+1)*5 
	)
0
Marcin.Miga napisał(a):

Gdy przedziałów jest więcej... użyj matematyki.
Case when wiek<20 then 20 when wiek>80 then 80 else 5*(wiek/5) end

Próbuje rozwinąć powyższy przykład do postaci nagłówków w kolumnach jako przedziały od do np. 0 - 5 6 - 10 itd.
Niestety nie potrafię rozwiązać problemu .
Można prosić o pomoc.

0

Prawie tam samo, tylko PIVOT. A po Accesowemu to kwerenda krzyżowa.

0

Bardzo dziękuje.

Marcin.Miga napisał(a):

Prawie tam samo, tylko PIVOT. A po Accesowemu to kwerenda krzyżowa.

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