Commit 10082fd5 by Patryk Czarnik

Poprawki w kodach SQL - głównie wcięcia :)

parent 067dfbfa
CREATE TABLE regions ( CREATE TABLE regions (
region_id INTEGER CONSTRAINT region_id_nn NOT NULL, region_id INTEGER CONSTRAINT region_id_nn NOT NULL,
region_name VARCHAR(25), region_name VARCHAR(25),
CONSTRAINT reg_id_pk PRIMARY KEY (region_id) CONSTRAINT reg_id_pk PRIMARY KEY (region_id)
); );
CREATE TABLE countries ( CREATE TABLE countries (
country_id CHAR(2) CONSTRAINT country_id_nn NOT NULL, country_id CHAR(2) CONSTRAINT country_id_nn NOT NULL,
country_name VARCHAR(40), country_name VARCHAR(40),
region_id INTEGER, region_id INTEGER,
CONSTRAINT country_c_id_pk PRIMARY KEY (country_id), CONSTRAINT country_c_id_pk PRIMARY KEY (country_id),
CONSTRAINT countr_reg_fk FOREIGN KEY (region_id) REFERENCES regions(region_id) CONSTRAINT countr_reg_fk FOREIGN KEY (region_id) REFERENCES regions(region_id)
); );
CREATE TABLE locations ( CREATE TABLE locations (
location_id INTEGER, location_id INTEGER,
street_address VARCHAR(40), street_address VARCHAR(40),
postal_code VARCHAR(12), postal_code VARCHAR(12),
city VARCHAR(30) CONSTRAINT loc_city_nn NOT NULL, city VARCHAR(30) CONSTRAINT loc_city_nn NOT NULL,
state_province VARCHAR(25), state_province VARCHAR(25),
country_id CHAR(2), country_id CHAR(2),
CONSTRAINT loc_id_pk PRIMARY KEY (location_id), CONSTRAINT loc_id_pk PRIMARY KEY (location_id),
CONSTRAINT loc_c_id_fk FOREIGN KEY (country_id) REFERENCES countries(country_id) CONSTRAINT loc_c_id_fk FOREIGN KEY (country_id) REFERENCES countries(country_id)
); );
CREATE TABLE departments ( CREATE TABLE departments (
department_id INTEGER, department_id INTEGER,
department_name VARCHAR(100) CONSTRAINT dept_name_nn NOT NULL, department_name VARCHAR(100) CONSTRAINT dept_name_nn NOT NULL,
manager_id INTEGER, manager_id INTEGER,
location_id INTEGER, location_id INTEGER,
CONSTRAINT dept_id_pk PRIMARY KEY (department_id), CONSTRAINT dept_id_pk PRIMARY KEY (department_id),
CONSTRAINT dept_loc_fk FOREIGN KEY (location_id) REFERENCES locations (location_id) CONSTRAINT dept_loc_fk FOREIGN KEY (location_id) REFERENCES locations (location_id)
) ; ) ;
CREATE TABLE jobs ( CREATE TABLE jobs (
job_id VARCHAR(10), job_id VARCHAR(10),
job_title VARCHAR(35) CONSTRAINT job_title_nn NOT NULL, job_title VARCHAR(35) CONSTRAINT job_title_nn NOT NULL,
min_salary NUMERIC(8, 2), min_salary NUMERIC(8, 2),
max_salary NUMERIC(8, 2), max_salary NUMERIC(8, 2),
CONSTRAINT job_id_pk PRIMARY KEY(job_id) CONSTRAINT job_id_pk PRIMARY KEY(job_id)
); );
CREATE TABLE employees ( CREATE TABLE employees (
employee_id INTEGER, employee_id INTEGER,
first_name VARCHAR(25), first_name VARCHAR(25),
last_name VARCHAR(30) CONSTRAINT emp_last_name_nn NOT NULL, last_name VARCHAR(30) CONSTRAINT emp_last_name_nn NOT NULL,
email VARCHAR(30) CONSTRAINT emp_email_nn NOT NULL, email VARCHAR(30) CONSTRAINT emp_email_nn NOT NULL,
phone_number VARCHAR(20), phone_number VARCHAR(20),
hire_date DATE CONSTRAINT emp_hire_date_nn NOT NULL, hire_date DATE CONSTRAINT emp_hire_date_nn NOT NULL,
job_id VARCHAR(10) CONSTRAINT emp_job_nn NOT NULL, job_id VARCHAR(10) CONSTRAINT emp_job_nn NOT NULL,
salary NUMERIC(8, 2), salary NUMERIC(8, 2),
commission_pct NUMERIC(2, 2), commission_pct NUMERIC(2, 2),
manager_id INTEGER, manager_id INTEGER,
department_id INTEGER, department_id INTEGER,
CONSTRAINT emp_emp_id_pk PRIMARY KEY (employee_id), CONSTRAINT emp_emp_id_pk PRIMARY KEY (employee_id),
CONSTRAINT emp_dept_fk FOREIGN KEY (department_id) REFERENCES departments, CONSTRAINT emp_dept_fk FOREIGN KEY (department_id) REFERENCES departments,
CONSTRAINT emp_job_fk FOREIGN KEY (job_id) REFERENCES jobs (job_id), CONSTRAINT emp_job_fk FOREIGN KEY (job_id) REFERENCES jobs (job_id),
CONSTRAINT emp_manager_fk FOREIGN KEY (manager_id) REFERENCES employees, CONSTRAINT emp_manager_fk FOREIGN KEY (manager_id) REFERENCES employees,
CONSTRAINT emp_salary_min CHECK (salary > 0), CONSTRAINT emp_salary_min CHECK (salary > 0),
CONSTRAINT emp_email_uk UNIQUE (email) CONSTRAINT emp_email_uk UNIQUE (email)
); );
CREATE TABLE job_history ( CREATE TABLE job_history (
employee_id INTEGER CONSTRAINT jhist_employee_nn NOT NULL, employee_id INTEGER CONSTRAINT jhist_employee_nn NOT NULL,
start_date DATE CONSTRAINT jhist_start_date_nn NOT NULL, start_date DATE CONSTRAINT jhist_start_date_nn NOT NULL,
end_date DATE CONSTRAINT jhist_end_date_nn NOT NULL, end_date DATE CONSTRAINT jhist_end_date_nn NOT NULL,
job_id VARCHAR(10) CONSTRAINT jhist_job_nn NOT NULL, job_id VARCHAR(10) CONSTRAINT jhist_job_nn NOT NULL,
department_id INTEGER, department_id INTEGER,
CONSTRAINT jhist_date_interval CHECK (end_date > start_date), CONSTRAINT jhist_date_interval CHECK (end_date > start_date),
CONSTRAINT jhist_emp_id_st_date_pk PRIMARY KEY (employee_id, start_date), CONSTRAINT jhist_emp_id_st_date_pk PRIMARY KEY (employee_id, start_date),
CONSTRAINT jhist_job_fk FOREIGN KEY (job_id) REFERENCES jobs, CONSTRAINT jhist_job_fk FOREIGN KEY (job_id) REFERENCES jobs,
CONSTRAINT jhist_emp_fk FOREIGN KEY (employee_id) REFERENCES employees, CONSTRAINT jhist_emp_fk FOREIGN KEY (employee_id) REFERENCES employees,
CONSTRAINT jhist_dept_fk FOREIGN KEY (department_id) REFERENCES departments CONSTRAINT jhist_dept_fk FOREIGN KEY (department_id) REFERENCES departments
); );
...@@ -160,29 +160,29 @@ CREATE SEQUENCE employees_seq START WITH 207 INCREMENT BY 1 NO CYCLE; ...@@ -160,29 +160,29 @@ CREATE SEQUENCE employees_seq START WITH 207 INCREMENT BY 1 NO CYCLE;
ALTER TABLE employees ALTER COLUMN employee_id SET DEFAULT nextval('employees_seq'); ALTER TABLE employees ALTER COLUMN employee_id SET DEFAULT nextval('employees_seq');
CREATE OR REPLACE VIEW emp_details_view ( CREATE OR REPLACE VIEW emp_details_view (
employee_id, job_id, manager_id, department_id, location_id, country_id, first_name, last_name, salary, commission_pct, department_name, job_title, city, state_province, country_name, region_name employee_id, job_id, manager_id, department_id, location_id, country_id, first_name, last_name, salary, commission_pct, department_name, job_title, city, state_province, country_name, region_name
) AS SELECT e.employee_id, ) AS SELECT e.employee_id,
e.job_id, e.job_id,
e.manager_id, e.manager_id,
e.department_id, e.department_id,
d.location_id, d.location_id,
l.country_id, l.country_id,
e.first_name, e.first_name,
e.last_name, e.last_name,
e.salary, e.salary,
e.commission_pct, e.commission_pct,
d.department_name, d.department_name,
j.job_title, j.job_title,
l.city, l.city,
l.state_province, l.state_province,
c.country_name, c.country_name,
r.region_name r.region_name
FROM employees e, FROM employees e,
departments d, departments d,
jobs j, jobs j,
locations l, locations l,
countries c, countries c,
regions r regions r
WHERE e.department_id = d.department_id WHERE e.department_id = d.department_id
AND d.location_id = l.location_id AND d.location_id = l.location_id
AND l.country_id = c.country_id AND l.country_id = c.country_id
......
...@@ -91,12 +91,12 @@ $$ LANGUAGE plpgsql; ...@@ -91,12 +91,12 @@ $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION zarabiajacy_wiecej_niz(emp_id INTEGER) CREATE OR REPLACE FUNCTION zarabiajacy_wiecej_niz(emp_id INTEGER)
RETURNS SETOF employees AS $$ RETURNS SETOF employees AS $$
DECLARE DECLARE
the_salary NUMERIC; the_salary NUMERIC;
BEGIN BEGIN
SELECT salary INTO the_salary FROM employees WHERE employee_id = emp_id; SELECT salary INTO the_salary FROM employees WHERE employee_id = emp_id;
RETURN QUERY RETURN QUERY
SELECT * FROM employees WHERE salary > the_salary ORDER BY salary ASC; SELECT * FROM employees WHERE salary > the_salary ORDER BY salary ASC;
END END
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
...@@ -439,14 +439,14 @@ SELECT 2 * (3 + NULL) - 15 * 4; ...@@ -439,14 +439,14 @@ SELECT 2 * (3 + NULL) - 15 * 4;
jest NULL u tych pracowników, którzy nie uzyskują prowizji. jest NULL u tych pracowników, którzy nie uzyskują prowizji.
*/ */
SELECT first_name, last_name, salary, commission_pct SELECT first_name, last_name, salary, commission_pct
,commission_pct * salary -- prowizja kwotowo ,commission_pct * salary -- prowizja kwotowo
,salary + commission_pct * salary -- kwota do wypłaty ,salary + commission_pct * salary -- kwota do wypłaty
FROM employees; FROM employees;
-- Aby zastąpić wartość NULL inną "konkretną" wartością, można użyć funkcji COALESCE -- Aby zastąpić wartość NULL inną "konkretną" wartością, można użyć funkcji COALESCE
SELECT first_name, last_name, salary, commission_pct SELECT first_name, last_name, salary, commission_pct
,coalesce(commission_pct * salary, 0) as "kwota prowizji" ,coalesce(commission_pct * salary, 0) as "kwota prowizji"
,salary + coalesce(commission_pct, 0) * salary as "wypłata z prowizją" ,salary + coalesce(commission_pct, 0) * salary as "wypłata z prowizją"
FROM employees; FROM employees;
-- coalesce(wartosc1, wartosc2, ....) -- dowolnie wiele wartości po przecinku -- coalesce(wartosc1, wartosc2, ....) -- dowolnie wiele wartości po przecinku
...@@ -468,8 +468,8 @@ FROM employees; ...@@ -468,8 +468,8 @@ FROM employees;
-- W Oraclu jest też funkcja nvl, która działa tak jak dwuargumentowy coalesce: -- W Oraclu jest też funkcja nvl, która działa tak jak dwuargumentowy coalesce:
-- NVL(x, y): jeśli x nie jest nullem, to zwraca x, a jeśli x jest nullem, to zwraca y -- NVL(x, y): jeśli x nie jest nullem, to zwraca x, a jeśli x jest nullem, to zwraca y
SELECT first_name, last_name, salary, commission_pct SELECT first_name, last_name, salary, commission_pct
,nvl(commission_pct * salary, 0) as "kwota prowizji" ,nvl(commission_pct * salary, 0) as "kwota prowizji"
,salary + nvl(commission_pct, 0) * salary as "wypłata z prowizją" ,salary + nvl(commission_pct, 0) * salary as "wypłata z prowizją"
FROM employees; FROM employees;
-- Inne funkcje Oracla związane z obsługą NULL: -- Inne funkcje Oracla związane z obsługą NULL:
...@@ -479,12 +479,12 @@ FROM employees; ...@@ -479,12 +479,12 @@ FROM employees;
-- jeśli x jest NULLem, to zwraca z -- jeśli x jest NULLem, to zwraca z
SELECT first_name, last_name, commission_pct, SELECT first_name, last_name, commission_pct,
nvl2(commission_pct, 'jest prowizja', 'brak prowizji') nvl2(commission_pct, 'jest prowizja', 'brak prowizji')
FROM employees; FROM employees;
-- Na siłę można to wykorzystać do wyliczenia łącznej wypłaty: -- Na siłę można to wykorzystać do wyliczenia łącznej wypłaty:
SELECT first_name, last_name, salary, commission_pct, SELECT first_name, last_name, salary, commission_pct,
nvl2(commission_pct, salary*(1+commission_pct), salary) AS "wypłata" nvl2(commission_pct, salary*(1+commission_pct), salary) AS "wypłata"
FROM employees; FROM employees;
-- NULLIF(x, y) -- o!, to działa też w PostgreSQL -- NULLIF(x, y) -- o!, to działa też w PostgreSQL
...@@ -668,7 +668,7 @@ WHERE d.department_id = e.department_id ...@@ -668,7 +668,7 @@ WHERE d.department_id = e.department_id
-- natomiast w WHERE mamy tylko inne warunki logiczne -- natomiast w WHERE mamy tylko inne warunki logiczne
SELECT * SELECT *
FROM employees e FROM employees e
JOIN departments d ON d.department_id = e.department_id JOIN departments d ON d.department_id = e.department_id
JOIN locations l ON l.location_id = d.location_id JOIN locations l ON l.location_id = d.location_id
WHERE e.salary >= 10000; WHERE e.salary >= 10000;
...@@ -962,9 +962,9 @@ HAVING count(*) >= 5; ...@@ -962,9 +962,9 @@ HAVING count(*) >= 5;
-- Przy okazji: Zamiast HAVING można też umieści zapytanie z GROUP BY jako podzapytanie -- Przy okazji: Zamiast HAVING można też umieści zapytanie z GROUP BY jako podzapytanie
-- w zewnętrznym zapytaniu, a w tym zewnętrznym użyć WHERE. -- w zewnętrznym zapytaniu, a w tym zewnętrznym użyć WHERE.
SELECT * FROM ( SELECT * FROM (
SELECT job_id, count(*) AS ilu, avg(salary) AS srednia, min(salary) AS min, max(salary) AS max SELECT job_id, count(*) AS ilu, avg(salary) AS srednia, min(salary) AS min, max(salary) AS max
FROM employees FROM employees
GROUP BY job_id) podzapytanie GROUP BY job_id) podzapytanie
WHERE srednia < 6000; WHERE srednia < 6000;
...@@ -1041,11 +1041,11 @@ GROUP BY ROLLUP(job_id) ...@@ -1041,11 +1041,11 @@ GROUP BY ROLLUP(job_id)
ORDER BY 1; ORDER BY 1;
SELECT department_id SELECT department_id
, grouping(department_id) AS grouping_department_id , grouping(department_id) AS grouping_department_id
, job_id , job_id
, grouping(job_id) AS grouping_job_id , grouping(job_id) AS grouping_job_id
, count(*) , count(*)
, avg(salary) , avg(salary)
FROM employees FROM employees
GROUP BY ROLLUP(department_id, job_id) GROUP BY ROLLUP(department_id, job_id)
ORDER BY 1; ORDER BY 1;
...@@ -1110,8 +1110,7 @@ FROM employees ...@@ -1110,8 +1110,7 @@ FROM employees
GROUP BY GROUPING SETS((department_id, job_id), (department_id)); GROUP BY GROUPING SETS((department_id, job_id), (department_id));
--* Analiza przedzialowa i funkcje okna - OVER (PARTITION BY) *--
---- Analiza przedzialowa - PARTITION BY ----
-- przypomnienie podzial pracownikow wg job_id i wyliczenie sredniej pensji: -- przypomnienie podzial pracownikow wg job_id i wyliczenie sredniej pensji:
SELECT job_id, count(*) AS ilu, avg(salary) AS srednia SELECT job_id, count(*) AS ilu, avg(salary) AS srednia
...@@ -1136,14 +1135,14 @@ ORDER BY job_id, employee_id; ...@@ -1136,14 +1135,14 @@ ORDER BY job_id, employee_id;
-- Przykład zastosowania: o ile pracownik zarabia więcej lub mniej od średniej na jego stanowisku -- Przykład zastosowania: o ile pracownik zarabia więcej lub mniej od średniej na jego stanowisku
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
round(salary - avg(salary) OVER (PARTITION BY job_id)) AS roznica round(salary - avg(salary) OVER (PARTITION BY job_id)) AS roznica
FROM employees FROM employees
ORDER BY job_id, salary DESC; ORDER BY job_id, salary DESC;
-- Tutaj zaczniemy uzywac "funkcji okienkowych" -- Tutaj zaczniemy uzywac "funkcji okienkowych"
-- row_number podaje numer wiersza w jego grupie. Numeracja liniowa po kolei. -- row_number podaje numer wiersza w jego grupie. Numeracja liniowa po kolei.
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
row_number() OVER (PARTITION BY job_id ORDER BY salary DESC) row_number() OVER (PARTITION BY job_id ORDER BY salary DESC)
FROM employees FROM employees
ORDER BY job_id; ORDER BY job_id;
...@@ -1156,12 +1155,12 @@ FROM employees; ...@@ -1156,12 +1155,12 @@ FROM employees;
-- To dziala jak okreslanie miejsca sportowca w zawodach. Np. dwie osoby dostaja srebrny medal, bo mialy jednakowy wynik -- To dziala jak okreslanie miejsca sportowca w zawodach. Np. dwie osoby dostaja srebrny medal, bo mialy jednakowy wynik
-- I wtedy brazowego medalu sie nie przyznaje... -- I wtedy brazowego medalu sie nie przyznaje...
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
rank() OVER (PARTITION BY job_id ORDER BY salary DESC) rank() OVER (PARTITION BY job_id ORDER BY salary DESC)
FROM employees; FROM employees;
-- A dla całej tabeli? Musimy podać kolejność, ale nie robimy podziału -- A dla całej tabeli? Musimy podać kolejność, ale nie robimy podziału
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
rank() OVER (ORDER BY salary DESC) rank() OVER (ORDER BY salary DESC)
FROM employees; FROM employees;
...@@ -1169,11 +1168,11 @@ FROM employees; ...@@ -1169,11 +1168,11 @@ FROM employees;
-- ale nastepni w kolejnosci dostana nastepny numer, bez zadnych przerw. -- ale nastepni w kolejnosci dostana nastepny numer, bez zadnych przerw.
-- Tutaj nawet gdyby byly dwa srebrne medale, to bedzie tez przyznany brazowy -- Tutaj nawet gdyby byly dwa srebrne medale, to bedzie tez przyznany brazowy
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
dense_rank() OVER (PARTITION BY job_id ORDER BY salary DESC) dense_rank() OVER (PARTITION BY job_id ORDER BY salary DESC)
FROM employees; FROM employees;
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
dense_rank() OVER (ORDER BY salary DESC) dense_rank() OVER (ORDER BY salary DESC)
FROM employees; FROM employees;
...@@ -1183,12 +1182,12 @@ FROM employees; ...@@ -1183,12 +1182,12 @@ FROM employees;
-- Tutaj dowiemy sie czy pracownik nalezy do bogatszej polowy (1) na swoim stanowiksu, czy do biednejszej polowy (2) -- Tutaj dowiemy sie czy pracownik nalezy do bogatszej polowy (1) na swoim stanowiksu, czy do biednejszej polowy (2)
-- Przy czym to dziala "technicznie" i w przypadku rownych pensji (zob. AD_VP) pracownicy o tej samej pensji moga trafic do roznych grup, bo akurat tu przebiega granica -- Przy czym to dziala "technicznie" i w przypadku rownych pensji (zob. AD_VP) pracownicy o tej samej pensji moga trafic do roznych grup, bo akurat tu przebiega granica
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
ntile(2) OVER (PARTITION BY job_id ORDER BY salary DESC) ntile(2) OVER (PARTITION BY job_id ORDER BY salary DESC)
FROM employees; FROM employees;
-- Tutaj dzielimy pracownikow na 10 czesci wg pensji. -- Tutaj dzielimy pracownikow na 10 czesci wg pensji.
SELECT first_name, last_name, salary, SELECT first_name, last_name, salary,
ntile(10) OVER (ORDER BY salary DESC) ntile(10) OVER (ORDER BY salary DESC)
FROM employees; FROM employees;
SELECT first_name, last_name, salary, SELECT first_name, last_name, salary,
...@@ -1199,11 +1198,11 @@ ORDER BY last_name, first_name; ...@@ -1199,11 +1198,11 @@ ORDER BY last_name, first_name;
-- odwolanie do wartosci, ktora wystapila wczesniej, (do "sasiada") -- odwolanie do wartosci, ktora wystapila wczesniej, (do "sasiada")
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
lag(salary, 1) OVER (PARTITION BY job_id ORDER BY salary DESC) AS poprzedni lag(salary, 1) OVER (PARTITION BY job_id ORDER BY salary DESC) AS poprzedni
FROM employees; FROM employees;
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
lag(salary, 1) OVER (ORDER BY salary DESC) AS poprzedni lag(salary, 1) OVER (ORDER BY salary DESC) AS poprzedni
FROM employees; FROM employees;
-- Przykladowo: o ile pensja pracownika jest mniejsza od poprzedniego na tym samym stanowisku: -- Przykladowo: o ile pensja pracownika jest mniejsza od poprzedniego na tym samym stanowisku:
...@@ -1214,41 +1213,41 @@ FROM employees; ...@@ -1214,41 +1213,41 @@ FROM employees;
-- albo nie do sasiada tylko do rekordu ktory wystapil x pozycji temu -- albo nie do sasiada tylko do rekordu ktory wystapil x pozycji temu
-- Tutaj już bez podziału na stanowiska -- Tutaj już bez podziału na stanowiska
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
lag(salary, 2) OVER (ORDER BY salary DESC) lag(salary, 2) OVER (ORDER BY salary DESC)
FROM employees; FROM employees;
-- zagladanie do rekordow nastepnych -- zagladanie do rekordow nastepnych
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
lead(salary, 1) OVER (PARTITION BY job_id ORDER BY salary DESC) lead(salary, 1) OVER (PARTITION BY job_id ORDER BY salary DESC)
FROM employees; FROM employees;
-- przyklad bez partition by, samo zastosowanie f.okienkowej -- przyklad bez partition by, samo zastosowanie f.okienkowej
-- o ile mniej zarabiam od poprzedniego pracownika na liscie -- o ile mniej zarabiam od poprzedniego pracownika na liscie
SELECT first_name, last_name, salary, SELECT first_name, last_name, salary,
abs(salary - lag(salary, 1) OVER (ORDER BY salary DESC)) AS roznica abs(salary - lag(salary, 1) OVER (ORDER BY salary DESC)) AS roznica
FROM employees; FROM employees;
-- Odwołanie do pierwszego rekordu danej grupy -- Odwołanie do pierwszego rekordu danej grupy
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
first_value(salary) OVER (PARTITION BY job_id ORDER BY salary DESC) first_value(salary) OVER (PARTITION BY job_id ORDER BY salary DESC)
FROM employees; FROM employees;
-- Dla pracownika info kto na jego stanowisku zarabia najwięcej -- Dla pracownika info kto na jego stanowisku zarabia najwięcej
SELECT first_name, last_name, salary, job_id, SELECT first_name, last_name, salary, job_id,
first_value(first_name || ' ' || last_name) first_value(first_name || ' ' || last_name)
OVER (PARTITION BY job_id ORDER BY salary DESC) OVER (PARTITION BY job_id ORDER BY salary DESC)
FROM employees; FROM employees;
SELECT first_name, last_name, salary, job_id, hire_date, SELECT first_name, last_name, salary, job_id, hire_date,
lag(first_name || ' ' || last_name, 1) lag(first_name || ' ' || last_name, 1)
OVER (PARTITION BY job_id ORDER BY salary DESC) OVER (PARTITION BY job_id ORDER BY salary DESC)
FROM employees FROM employees
ORDER BY hire_date; ORDER BY hire_date;
-- Dla każdego pracownika podaj info ile dni minęło od zatrudnienia poprzedniej osoby do zatrudnienia bieżącej osoby. -- Dla każdego pracownika podaj info ile dni minęło od zatrudnienia poprzedniej osoby do zatrudnienia bieżącej osoby.
SELECT first_name, last_name, hire_date, SELECT first_name, last_name, hire_date,
hire_date - lag(hire_date, 1) OVER (ORDER BY hire_date) AS roznica_czasu hire_date - lag(hire_date, 1) OVER (ORDER BY hire_date) AS roznica_czasu
FROM employees; FROM employees;
...@@ -1553,9 +1552,9 @@ FROM employees; ...@@ -1553,9 +1552,9 @@ FROM employees;
-- Obok pracownika wypisz srednia pensje w całej firmie i oblicz różnicę między pensją pracownika a średnią firmy -- Obok pracownika wypisz srednia pensje w całej firmie i oblicz różnicę między pensją pracownika a średnią firmy
SELECT first_name, last_name, salary, SELECT first_name, last_name, salary,
(SELECT 2+2) AS cztery, (SELECT 2+2) AS cztery,
(SELECT avg(salary) FROM employees) AS srednia, (SELECT avg(salary) FROM employees) AS srednia,
round(salary - (SELECT avg(salary) FROM employees)) AS roznica round(salary - (SELECT avg(salary) FROM employees)) AS roznica
FROM employees; FROM employees;
-- Powyższe zapytania są "nieskorelowane", czyli mogą być wyliczone raz, a nie osobno dla każdego wiersza. -- Powyższe zapytania są "nieskorelowane", czyli mogą być wyliczone raz, a nie osobno dla każdego wiersza.
...@@ -1658,45 +1657,45 @@ GROUP BY j.job_id, j.job_title, e1.employee_id, e1.first_name, e1.last_name, e1. ...@@ -1658,45 +1657,45 @@ GROUP BY j.job_id, j.job_title, e1.employee_id, e1.first_name, e1.last_name, e1.
-- Przykład z dwoma podzapytaniami - pacownik, jego stawisko i jego departament -- Przykład z dwoma podzapytaniami - pacownik, jego stawisko i jego departament
-- Wersja zagnieżdżona -- Wersja zagnieżdżona
SELECT e.first_name, e.last_name, e.salary SELECT e.first_name, e.last_name, e.salary
,job_info.job_title ,job_info.job_title
,job_info.ilu AS job_ilosc ,job_info.ilu AS job_ilosc
,round(job_info.srednia, 1) AS job_srednia ,round(job_info.srednia, 1) AS job_srednia
,dep_info.department_name ,dep_info.department_name
,dep_info.ilu AS dep_ilosc ,dep_info.ilu AS dep_ilosc
,round(dep_info.srednia, 1) AS dep_srednia ,round(dep_info.srednia, 1) AS dep_srednia
FROM employees e FROM employees e
LEFT JOIN ( LEFT JOIN (
SELECT job_id, job_title, count(employee_id) AS ilu, avg(salary) AS srednia SELECT job_id, job_title, count(employee_id) AS ilu, avg(salary) AS srednia
FROM jobs JOIN employees USING(job_id) FROM jobs JOIN employees USING(job_id)
GROUP BY job_id GROUP BY job_id
) job_info USING(job_id) ) job_info USING(job_id)
LEFT JOIN ( LEFT JOIN (
SELECT department_id, department_name, count(employee_id) AS ilu, avg(salary) AS srednia, city SELECT department_id, department_name, count(employee_id) AS ilu, avg(salary) AS srednia, city
FROM departments FROM departments
LEFT JOIN employees USING(department_id) LEFT JOIN employees USING(department_id)
LEFT JOIN locations USING(location_id) LEFT JOIN locations USING(location_id)
GROUP BY department_id, city GROUP BY department_id, city
) dep_info USING(department_id) ) dep_info USING(department_id)
ORDER BY e.employee_id; ORDER BY e.employee_id;
-- wersja z WITH -- wersja z WITH
WITH job_info AS WITH job_info AS
(SELECT job_id, job_title, count(employee_id) AS ilu, avg(salary) AS srednia (SELECT job_id, job_title, count(employee_id) AS ilu, avg(salary) AS srednia
FROM jobs JOIN employees USING(job_id) FROM jobs JOIN employees USING(job_id)
GROUP BY job_id), GROUP BY job_id),
dep_info AS dep_info AS
(SELECT department_id, department_name, count(employee_id) AS ilu, avg(salary) AS srednia, city (SELECT department_id, department_name, count(employee_id) AS ilu, avg(salary) AS srednia, city
FROM departments FROM departments
LEFT JOIN employees USING(department_id) LEFT JOIN employees USING(department_id)
LEFT JOIN locations USING(location_id) LEFT JOIN locations USING(location_id)
GROUP BY department_id, city) GROUP BY department_id, city)
SELECT e.first_name, e.last_name, e.salary SELECT e.first_name, e.last_name, e.salary
,job_info.job_title ,job_info.job_title
,job_info.ilu AS job_ilosc ,job_info.ilu AS job_ilosc
,round(job_info.srednia, 1) AS job_srednia ,round(job_info.srednia, 1) AS job_srednia
,dep_info.department_name ,dep_info.department_name
,dep_info.ilu AS dep_ilosc ,dep_info.ilu AS dep_ilosc
,round(dep_info.srednia, 1) AS dep_srednia ,round(dep_info.srednia, 1) AS dep_srednia
FROM employees e FROM employees e
LEFT JOIN job_info USING(job_id) LEFT JOIN job_info USING(job_id)
LEFT JOIN dep_info USING(department_id) LEFT JOIN dep_info USING(department_id)
...@@ -1728,8 +1727,8 @@ ORDER BY employee_id; ...@@ -1728,8 +1727,8 @@ ORDER BY employee_id;
SELECT first_name, last_name, hire_date SELECT first_name, last_name, hire_date
FROM employees FROM employees
WHERE hire_date BETWEEN WHERE hire_date BETWEEN
(SELECT min(start_date) FROM job_history) (SELECT min(start_date) FROM job_history)
AND (SELECT max(start_date) FROM job_history); AND (SELECT max(start_date) FROM job_history);
-- Przykład podzapytania z IN -- Przykład podzapytania z IN
-- To samo da się zrobić inaczej, ale po prostu prezentuję działanie IN -- To samo da się zrobić inaczej, ale po prostu prezentuję działanie IN
......
CREATE TABLE skocznie ( CREATE TABLE skocznie (
id_skoczni integer, id_skoczni integer primary key,
miasto text, miasto text,
kraj_s text, kraj_s text,
nazwa text, nazwa text,
k integer, k integer,
sedz integer sedz integer
); );
CREATE TABLE trenerzy ( CREATE TABLE trenerzy (
kraj text, kraj char(3) primary key,
imie_t text, imie_t text,
nazwisko_t text, nazwisko_t text,
data_ur_t date data_ur_t date
); );
CREATE TABLE zawodnicy ( CREATE TABLE zawodnicy (
id_skoczka integer, id_skoczka integer primary key,
imie text, imie text,
nazwisko text, nazwisko text,
kraj char(3), kraj char(3),
data_ur date, data_ur date,
wzrost integer, wzrost integer,
waga integer waga integer
); );
CREATE TABLE zawody ( CREATE TABLE zawody (
id_zawodow integer, id_zawodow integer primary key,
id_skoczni integer, id_skoczni integer,
data date data date
); );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment