SELECT MAX HAVING COUNT - POSTGRESQL

0

Jestem początkująca. Szukałam i nie znalazłam nic, co by mi pozwoliło zrozumiieć..

Proszę o wytłumaczenie co robią poniższe kody. Wiem co osobno robi count i having ale razem to już nie za bardzo rozumiem. W jakich sytuacjach taki kod się stosuje.? Proszę o podanie kilka różnych przykładów w tym przykład z biblioteką.
I

SELECT deptno, MAX(salary)
FROM employee
GROUP BY deptno
HAVING COUNT(*)>3;

II

SELECT JOB, MIN(SALARY), 
    FROM EMPLOYEE
    GROUP BY JOB
    HAVING COUNT(*) > 1;

III

SELECT emp_name, 
MIN (emp_salary) 
FROM employee 
GROUP BY emp_name 
HAVING count (emp_salary) > 10000;

IV

SELECT emp_name, 
MIN (emp_salary) 
FROM employee 
GROUP BY emp_name 
HAVING count (emp_id) > 1;

1

Po pierwsze zacznij od zrozumienia czym jest group by. Funkcje agregujące wyliczają wyniki właśnie na grupach rekordów (GROUP BY). HAVING ogranicza wyniki z GROUP BY. NP

SELECT department, SUM(salary) FROM salary GROUP BY department HAVING SUM(salary) > 10000 

Przykladowa tabela ktora zawiera wynagrodzenia, grupujemy po działach, zliczamy sume wynagrodzen i wyswietlamy tylko te które są wieksze niż 10k.

SELECT deptno, MAX(salary)
FROM employee
GROUP BY deptno
HAVING COUNT(*)>3;

Pokaże maksymalną pensje dla kazdego deptno(zakładam ze to numer działu) ale tylko dla takich działów które mają wiecej niż 3 pracowników.

Do przeczytania: https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-having/

0

@skytrack: Dzięki, czyli max z count wykorzystuje się tylko do wynagrodzeń? Czy można to np wykorzystać w bazie danych biblioteka? Jeśli tak to możesz podać przykład?

1

"czyli max z count wykorzystuje się tylko do wynagrodzeń" - nie, możesz to wykorzystać gdzie tylko chcesz i jak chcesz.
" Czy można to np wykorzystać w bazie danych biblioteka" - nie wiem o jaką bazę Ci tu chodzi ale co do zasady można to wykorzystać w każdej relacyjnej bazie danych.

0

@skytrack: POSTGRESQL - BIBLIOTEKA

0

Czym jest postgresql - biblioteka?

0

@Patryk27: Baza danych biblioteka w PostgreSQL.
To co mam jeszcze napisać ? Chce po prostu zrozumieć kod z pierwszego postu i chciałabym jakikolwiek przykład z opisem. Najlepiej przykład zapytania jakiejkolwiek bazy danych biblioteka.

0

Najlepiej przykład zapytania jakiejkolwiek bazy danych biblioteka.

Nie możemy pokazać Ci wykorzystania zapytań grupujących w bazie danych "biblioteka", ponieważ nie wiemy jak ta baza wygląda - gdybyś podesłała jej DDL (tj. zapytania w stylu create table), można by spróbować.

Chce po prostu zrozumieć kod z pierwszego postu i chciałabym jakikolwiek przykład z opisem.

Przykładowo to zapytanie:

SELECT deptno, MAX(salary)
FROM employee
GROUP BY deptno
HAVING COUNT(*)>3;

... zwraca, dla każdego departamentu (FROM employee GROUP BY deptno) mającego powyżej trzech pracowników (HAVING COUNT(*) > 3), maksymalną pensję (MAX(salary)).

Z kolei to zapytanie tutaj:

SELECT emp_name, 
MIN (emp_salary) 
FROM employee 
GROUP BY emp_name 
HAVING count (emp_id) > 1;

... grupuje pracowników po imionach (FROM employee GROUP BY emp_name) i z każdej takiej grupy-po-imieniach mającej powyżej jedną osobę (HAVING count(emp_id) > 1) wybiera minimalną pensję; w praktyce grupuje to pracowników o tych samych imionach i jeśli dane imię ma więcej niż jednego pracownika, zwraca minimalną pensję dla pracowników o tym imieniu.

0
CREATE TABLE liczba_wypozyczen
(
	id_l_w SERIAL NOT NULL, /* Tworzenie kolumny id_l_w o typie SERIAL z NOT NULL. */
	liczba_w INTEGER NOT NULL,
	CONSTRAINT liczba_wypozyczen_pkey PRIMARY KEY (id_l_w) 
	/* CONSTRAINT nazwa_tabeli_pkey PRIMARY KEY (nazwa kolumny, która ma być kluczem głównym)  */
	/* Tworzenie klucza głównego w tabeli słownikowej liczba_wypozyczen na kolumnie id_l_w. */
);
CREATE TABLE kategoria
(
	id_ka SERIAL NOT NULL,
	kategoria_k VARCHAR(50) NOT NULL,
	CONSTRAINT kategoria_pkey PRIMARY KEY (id_ka)
);
CREATE TABLE status_ksiazki
(
	id_s_k SERIAL NOT NULL,
	status_k VARCHAR(20) NOT NULL,
	CONSTRAINT status_ksiazki_pkey PRIMARY KEY (id_s_k)
);
CREATE TABLE zwrot
(
	id_z SERIAL NOT NULL,
	status_zwrotu VARCHAR(20) NOT NULL,
	CONSTRAINT zwrot_pkey PRIMARY KEY (id_z)
);
CREATE TABLE czytelnik 
(
	id_cz SERIAL NOT NULL,
	liczba_wypozyczen INTEGER NOT NULL, /* Z tabeli słownikowej liczba_wypozyczen z kolumny liczba_w */
	nazwisko VARCHAR(50) NOT NULL, 
	imie VARCHAR(50) NOT NULL, 
	pesel BIGINT NOT NULL, 
	email VARCHAR(100) NOT NULL, 
	województwo VARCHAR(20) NOT NULL, 
	kod_pocztowy VARCHAR(6) NOT NULL, 
	miasto VARCHAR(50) NOT NULL, 
	adres VARCHAR(50) NOT NULL,
	CONSTRAINT czytelnik_pkey PRIMARY KEY (id_cz),
	CONSTRAINT fk_czytelnik_liczba_wypozyczen FOREIGN KEY (liczba_wypozyczen)
	/* Tworzenie klucza obcego na tabeli czytelnik prowadzącej do tabeli liczba_wypozyczen */
	/* FOREIGN KEY (liczba_wypozyczen) - Tworzenie klucza obcego na tabeli liczba_wypozyczen */
	REFERENCES liczba_wypozyczen (id_l_w)
	/* Klucz obcy odnosi się do tabeli liczba_wypozyczen i kolumny id_l_w */
);
CREATE TABLE logowanie
(
	id_l SERIAL NOT NULL,
	nazwisko_l INTEGER NOT NULL,
	imie_l INTEGER NOT NULL,
	login BIGINT NOT NULL,	
	hasło VARCHAR(8) NOT NULL,
	CONSTRAINT logowanie_pkey PRIMARY KEY (id_l),
	CONSTRAINT fk_logowanie_czytelnik FOREIGN KEY (imie_l)
	/* Tworzenie klucza obcego na tabeli logowowanie prowadzącej do tabeli czytelnik */
	/* FOREIGN KEY (czytelnik_l) - Tworzenie klucza obcego na kolumnie czytelnik_l tabeli logowanie */
	REFERENCES czytelnik (id_cz),
	/* Klucz obcy odnosi się do tabeli czytelnik i kolumny id_cz */
	
	CONSTRAINT fk_logowanie_czytelnik_1 FOREIGN KEY (nazwisko_l) 
	/* 
	Tworzenie klucza obcego na tabeli logowowanie prowadzącej do tabeli czytelnik, ale wpisujemy czytelnik_1 
	Wpisując czytelnik pokaże błąd bo w tej samej tabeli nie może być dwóch takich samych constaint
	*/
	REFERENCES czytelnik (id_cz)
);
CREATE TABLE ksiazka
(
	id_ks SERIAL NOT NULL,
	status_ks INTEGER NOT NULL,
	kategoria_k INTEGER NOT NULL,
	isbn BIGINT NOT NULL,
	tytul VARCHAR(200) NOT NULL,
	autor1 VARCHAR(100) NOT NULL,
	autor2 VARCHAR(100) NULL,
	rok_wydania INTEGER NOT NULL,
	CONSTRAINT ksiazka_pkey PRIMARY KEY (id_ks),
	CONSTRAINT fk_ksiazka_status_ksiazki FOREIGN KEY (status_ks)
	REFERENCES status_ksiazki (id_s_k),
	CONSTRAINT fk_ksiazka_kategoria FOREIGN KEY (kategoria_k)
	REFERENCES kategoria (id_ka)
);
CREATE TABLE wypozyczenia 
(
	id_w SERIAL NOT NULL,
	pesel_w INTEGER NOT NULL, 
	ksiazka_w INTEGER NOT NULL, 
	data_zarezerwowania DATE NOT NULL, 
	data_odebrania TIMESTAMP(2) WITHOUT TIME ZONE NOT NULL, 
	data_zwrotu TIMESTAMP(2) WITHOUT TIME ZONE NOT NULL, 
	termin_zwrotu TIMESTAMP(2) WITHOUT TIME ZONE NOT NULL, 
	status_zwrotu_w INTEGER NOT NULL,
	CONSTRAINT wypozyczenia_pkey PRIMARY KEY (id_w),
	CONSTRAINT fk_wypozyczenia_czytelnik FOREIGN KEY (pesel_w)
	REFERENCES czytelnik (id_cz),
	CONSTRAINT fk_wypozyczenia_ksiazka FOREIGN KEY (ksiazka_w)
	REFERENCES ksiazka (id_ks),
	CONSTRAINT fk_wypozyczenia_zwrot FOREIGN KEY (status_zwrotu_w)
	REFERENCES zwrot (id_z)
);
0

O, no proszę - z czymś takim można pracować :-)

Przykładowym zapytaniem wykorzystującym funkcje agregujące mogłoby być:

  SELECT pesel_w, MAX(data_zwrotu)
    FROM wypozyczenia
GROUP BY pesel_w
  HAVING COUNT(*) > 1

... rozumiane jako: dla każdego PESELu (FROM wypozyczenia GROUP BY pesel_w), który miał więcej niż jedno wypożyczenie (HAVING COUNT(*) > 1) znajdź maksymalną (symbolicznie, "ostatnią") datę zwrotu książki.

0

@Patryk27:

Patryk27 napisał(a):

Najlepiej przykład zapytania jakiejkolwiek bazy danych biblioteka.

Nie możemy pokazać Ci wykorzystania zapytań grupujących w bazie danych "biblioteka", ponieważ nie wiemy jak ta baza wygląda - gdybyś podesłała jej DDL (tj. zapytania w stylu create table), można by spróbować.

Chce po prostu zrozumieć kod z pierwszego postu i chciałabym jakikolwiek przykład z opisem.

Przykładowo to zapytanie:

SELECT deptno, MAX(salary)
FROM employee
GROUP BY deptno
HAVING COUNT(*)>3;

... zwraca, dla każdego departamentu (FROM employee GROUP BY deptno) mającego powyżej trzech pracowników (HAVING COUNT(*) > 3), maksymalną pensję (MAX(salary)).

Z kolei to zapytanie tutaj:

SELECT emp_name, 
MIN (emp_salary) 
FROM employee 
GROUP BY emp_name 
HAVING count (emp_id) > 1;

... grupuje pracowników po imionach (FROM employee GROUP BY emp_name) i z każdej takiej grupy-po-imieniach mającej powyżej jedną osobę (HAVING count(emp_id) > 1) wybiera minimalną pensję; w praktyce grupuje to pracowników o tych samych imionach i jeśli dane imię ma więcej niż jednego pracownika, zwraca minimalną pensję dla pracowników o tym imieniu.

Niby rozumiem już ale nie ze wszystkimi zadaniami tego typu bym sobie poradziła.

0
Patryk27 napisał(a):

O, no proszę - z czymś takim można pracować :-)

Przykładowym zapytaniem wykorzystującym funkcje agregujące mogłoby być:

  SELECT pesel_w, MAX(data_zwrotu)
    FROM wypozyczenia
GROUP BY pesel_w
  HAVING COUNT(*) > 1

... rozumiane jako: dla każdego PESELu (FROM wypozyczenia GROUP BY pesel_w), który miał więcej niż jedno wypożyczenie (HAVING COUNT(*) > 1) znajdź maksymalną (symbolicznie, "ostatnią") datę zwrotu książki.

To już wiem, o co chodzi. Wielkie dzięki.

0

@Patryk27: Mam jeszcze jedno pytanie. Zauważyłam, że w swojej bazie mam błąd - Wszystkich czytelników mam, że wypożyczyli 1 książke zamiast 1 lub 2 lub 3 książki (Umkneło mi to).
Jak to prawidło zrobić?
Z tabeli czytelnik usunąć liczbe_wypozyczen a w tabeli wypozyczenia dodać wiersze wypożyczonych książek z pozostałymi kolumnami jak poniżej?
Przykład
screenshot-20220529145300.png

0

Hmm, tak na moje należy usunąć tabelę liczba_wypozyczen, usunąć kolumnę czytelnik.liczba_wypoczyczen, a następnie do tabeli wypozyczenia dorzucić klucz obcy id_cz (do tabeli czytelnik).

Wtedy liczbę wypożyczeń uzyskasz za pomocą prostego zapytania:

    SELECT c.id_cz, COUNT(w.id_w)
      FROM czytelnik c
INNER JOIN wypozyczenia w ON w.id_cz = c.id_cz
  GROUP BY c.id_cz

Coś takiego ma dodatkową zaletę, że pozwala na dorzucenie do zapytania warunków w stylu WHERE w.status_zwrotu = cośtam, które pozwala rozróżnić aktywne wypożyczenia od tych zakończonych itd.

0

Ok dzięki nie miałam jeszcze INNER JOIN.
Wstawianie danych insert into - Czy jak czytelnik wypożyczył więcej niż jedną książkę to dane do wierszy wstawiam jak niżej?

screenshot-20220529152232.png

0

Czy jak czytelnik wypożyczył więcej niż jedną książkę to dane do wierszy wstawiam jak niżej?

Tak, dokładnie :-)
(choć prawdopodobnie id_w drugiego wiersza powinno być różne, np. równe 2 - zakładając, że były to dwa osobne wypożyczenia.)

Btw, numery PESEL oraz podobne rzeczy zwykle zapisuje się jako TEXT, a nie liczby (głównie dlatego, że raczej nikt nie szuka danych na zasadzie pesel > 1000 AND pesel < 1500 + kolumna typu tekst rozwiązuje problem "a co jeśli pesel kiedyś będzie dłuższy").

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.