Commit a8b620f5 by Patryk Czarnik

wykład SQL - część 1

parent 33de0edc
-- To jest komentarz
/* To też */
select * from employees;
-- Zazwyczaj wielkość liter nie ma znaczenia w SQL (wyjaśnienie w innym pliku)
SELECT * FROM departments;
SELECT * FROM locations;
/* Ogólna postać:
SELECT kolumny
FROM tabele
WHERE warunek
GROUP BY kryteria grupowania
HAVING warunek
ORDER BY kryteria sortowania
...
*/
SELECT first_name, last_name, salary FROM employees;
-- Można też wpisać wyrażenie, które coś oblicza
SELECT 'Pracownik ' || first_name || ' ' || last_name,
salary * 12
FROM employees;
-- Szczególnie wtedy przydaje się nadawanie kolumnom wynikowym własnych nazw - tzw. aliasy
-- 'apostrofy' oznaczają w SQL wartości String, a "cudzysłowy" to nazwy cytowane
SELECT 'Pracownik ' || first_name || ' ' || last_name AS Pracownik,
salary * 12 AS "Roczne zarobki"
FROM employees;
SELECT * FROM jobs;
-- Wypisz nazwę stanowiska, a obok różnicę między maksymalną a minimalną pensją
SELECT job_title, max_salary - min_salary AS roznica
FROM jobs;
-- WHERE
-- Wypisz osoby zarabiające co najmniej 10 tys
SELECT * FROM employees WHERE salary >= 10000;
-- Wypisz osoby o nazwisku King
SELECT * FROM employees WHERE last_name = 'King';
SELECT * FROM employees WHERE salary < 5000 AND job_id = 'IT_PROG';
-- Aby sprawdzić, czy pole jest nullem, trzeba użyć IS NULL (nie działa porównanie)
SELECT * FROM locations WHERE state_province IS NULL;
SELECT * FROM locations WHERE state_province IS NOT NULL;
-- Natomiast zastąpienie NULLa inną wartością podczas odczytu, używajmy funkcji coalesce
SELECT city, state_province, country_id FROM locations;
SELECT city, coalesce(state_province, 'BRAK DANYCH'), country_id FROM locations;
-- Operator LIKE sprawdza, czy tekst pasuje do wzorca
-- Osoby z nazwiskami na A:
SELECT first_name, last_name, job_id, salary FROM employees
WHERE last_name LIKE 'A%';
-- nazwiska kończące się na a
SELECT first_name, last_name, job_id, salary FROM employees
WHERE last_name LIKE '%a';
-- Druga litera nazwiska to 'a'
SELECT first_name, last_name, job_id, salary FROM employees
WHERE last_name LIKE '_a%';
-- Generalnie % oznacza dowolny fragment tekstu, a _ oznacza pojedynczy dowolny znak
SELECT city FROM locations;
-- Z tabeli locations odczytaj te miasta, których przedostatnią literą jest 'm'
SELECT city FROM locations WHERE city LIKE '%m_';
-- Odczytaj te miasta, w których nazwie występują (co najmniej) dwie litery 'o'
SELECT city FROM locations WHERE city LIKE '%o%o%';
-- Gdybyśmy chcieli odczytać też 'Oxford'
SELECT city FROM locations WHERE city LIKE '%o%o%' OR city LIKE 'O%o%';
SELECT city FROM locations WHERE lower(city) LIKE '%o%o%';
-- W PostgreSQL (w innych nie) mamy też specjalną wersję ILIKE, która ignoruje wielkość liter
SELECT city FROM locations WHERE city ILIKE '%o%o%';
-- sortowanie - ORDER BY
SELECT * FROM employees
ORDER BY salary;
-- malejąco:
SELECT * FROM employees
ORDER BY salary DESC;
-- kilka kryteriów:
SELECT * FROM employees
ORDER BY last_name, first_name;
-- rosnąco wg jobów, malejąco wg pensji, rosnąco wg nazwisko i imion:
SELECT * FROM employees
ORDER BY job_id, salary DESC, last_name, first_name;
SELECT * FROM employees
ORDER BY length(first_name || last_name);
-- zamiast nazwy kolumny, w ORDER BY można wpisać numer kolumny (spośród tych, które wybieramy SELECTem)
SELECT first_name, last_name, salary, hire_date
FROM employees
ORDER BY 3 DESC, 2, 1;
-- Zapytania dot. wielu tabel
SELECT * FROM employees;
SELECT * FROM departments;
-- Dwie tabele po przecinku -> wychodzi "iloczyn kartezjański", czyli kombinacja każdego z każdym
SELECT * FROM employees, departments;
SELECT count(*) FROM employees, departments;
SELECT (SELECT count(*) FROM employees) * (SELECT count(*) FROM departments);
-- Jak dopasować rekordy?
-- Sposób 1
-- Za pomocą WHERE wybieramy tylko te kombinacje rekordów, w których id się zgadza
SELECT *
FROM employees, departments
WHERE employees.department_id = departments.department_id;
-- Sposób 2 - JOIN
SELECT *
FROM employees JOIN departments
ON employees.department_id = departments.department_id;
-- Różnicę zauważymy łącząc więcej niż 2 tabale.
-- Przy okazji wprowadzam aliasy tabel, czyli krótsze nazwy dla tabel w obrębie zapytania
-- Sposób z WHERE: zarówno warunki złączenia, jak i warunki filtrowania, są pisane razem w jednym WHERE
SELECT *
FROM employees e, departments d, locations l
WHERE e.department_id = d.department_id
AND d.location_id = l.location_id
AND salary < 10000;
-- W podejściu z JOIN warunek łączenia każdej kolejnej tabeli jest pisany w oddzielnym ON, a WHERE zajmuje się dalszym filtrowaniem
SELECT *
FROM employees e
JOIN departments d ON e.department_id = d.department_id
JOIN locations l ON d.location_id = l.location_id
WHERE salary < 10000;
--* JOIN jest częścią klauzuli FROM *--
-- sposoby podawania warunku złączenia w JOIN:
-- JOIN ON warunek logiczny
SELECT * FROM employees e JOIN jobs j ON j.job_id = e.job_id;
-- JOIN USING(kolumna)
-- W obu tabelach kolumna, po której łączymy, musi mieć taką samą nazwę
SELECT * FROM employees JOIN jobs USING(job_id);
-- NATURAL JOIN - sam znajduje kolumny o jednakowych nazwach i po nich łączy
-- raczej nie używajcie - łatwo się pomylić
SELECT * FROM employees NATURAL JOIN jobs;
-- Kierunki złączeń: INNER, LEFT, RIGHT, FULL
SELECT * FROM employees JOIN departments USING(department_id);
-- Domyślnym rodzajem jest INNER. W wynikach pojawiają tylko te rekordy, dla których udało się znaleźć dopasowanie
-- W wynikach nie Kimberely Grant, bo ona nie ma podanego departamentu (department_id IS NULL)
SELECT * FROM employees INNER JOIN departments USING(department_id);
-- LEFT JOIN - będą wszystkie rekordy z lewej tabeli, i te z prawej, które udało się dopasować
-- Jest K.Grant
SELECT * FROM employees LEFT JOIN departments USING(department_id);
-- RIGHT JOIN - będą wszystkie rekordy z prawej tabeli, i te z lewej, które udało się dopasować
-- Nie ma K.Grant, ale są departamenty, w których nikt nie pracuje
SELECT * FROM employees RIGHT JOIN departments USING(department_id);
-- FULL JOIN (można też pisać FULL OUTER JOIN)
-- są wszystkie rekordy z obu tabel, połączone jeśli pasują
SELECT * FROM employees FULL JOIN departments USING(department_id);
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