<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://wiki.cs.hse.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Luc1ph3r</id>
	<title>Wiki - Факультет компьютерных наук - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.cs.hse.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Luc1ph3r"/>
	<link rel="alternate" type="text/html" href="https://wiki.cs.hse.ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Luc1ph3r"/>
	<updated>2026-09-22T13:21:58Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.9</generator>
	<entry>
		<id>https://wiki.cs.hse.ru/index.php?title=%D0%9E_%D1%84%D0%B0%D0%BA%D1%83%D0%BB%D1%8C%D1%82%D0%B5%D1%82%D0%B5&amp;diff=23137</id>
		<title>О факультете</title>
		<link rel="alternate" type="text/html" href="https://wiki.cs.hse.ru/index.php?title=%D0%9E_%D1%84%D0%B0%D0%BA%D1%83%D0%BB%D1%8C%D1%82%D0%B5%D1%82%D0%B5&amp;diff=23137"/>
		<updated>2017-04-23T17:23:19Z</updated>

		<summary type="html">&lt;p&gt;Luc1ph3r: Переименовал «Компьютерные сети и базы данных 2» в «Базы данных 2», т.к. для сетей есть отдельная страница&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
&lt;br /&gt;
== Учебные курсы факультета компьютерных наук==&lt;br /&gt;
&lt;br /&gt;
=== Курсы за 2016/17 учебный год ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 1 курс !! 2 курс !! 3-4 курс !! майноры&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
[[Математический анализ на ПМИ_2016/2017 | Математический анализ на ПМИ (пилотный поток)]]&lt;br /&gt;
&lt;br /&gt;
[[Линейная алгебра и геометрия_2016/2017 | Линейная алгебра и геометрия на ПМИ]]&lt;br /&gt;
&lt;br /&gt;
[[Дискретная_математика_1_2016/2017 | Дискретная математика-1 на ПМИ]]&lt;br /&gt;
&lt;br /&gt;
[[Основы и методология программирования_2016/2017_пилотный_поток | Основы и методология программирования на ПМИ (пилотный поток)]]&lt;br /&gt;
&lt;br /&gt;
[[Основы и методология программирования_2016/2017 | Основы и методология программирования на ПМИ (основной поток)]]&lt;br /&gt;
&lt;br /&gt;
[[Алгоритмы_и_структуры_данных_на_ПМИ_(пилотный_поток) | Алгоритмы и структуры данных на ПМИ (пилотный поток)]]&lt;br /&gt;
&lt;br /&gt;
[[Алгоритмы_и_структуры_данных_на_ПМИ_(основной_поток) | Алгоритмы и структуры данных на ПМИ (основной поток)]]&lt;br /&gt;
&lt;br /&gt;
[[Алгебра_на_ПМИ_2016/2017 | Алгебра на ПМИ]]&lt;br /&gt;
&lt;br /&gt;
[http://hsealgebra17.wikidot.com/ Алгебра на ПИ]&lt;br /&gt;
&lt;br /&gt;
|| &lt;br /&gt;
&lt;br /&gt;
[[Математический анализ_2016/2017 | Математический анализ-3 на ПМИ (основной поток)]]&lt;br /&gt;
&lt;br /&gt;
[[Математически_анализ_3_на_ПМИ_(пилотный_поток) | Математический анализ-3 на ПМИ (пилотный поток)]]&lt;br /&gt;
&lt;br /&gt;
[[DM_2_2016_2017 | Дискретная математика-2 на ПМИ (основной поток)]]&lt;br /&gt;
&lt;br /&gt;
[[Дискретная математика_2_2016/2017 | Дискретная математика-2 на ПМИ (пилотный поток)]]&lt;br /&gt;
&lt;br /&gt;
[[Алгоритмы и структуры данных_2_2016/2017 | Алгоритмы и структуры данных – 2 на ПМИ (основной поток)]]&lt;br /&gt;
&lt;br /&gt;
[[Теория вероятностей_2016/2017 | Теория вероятностей на ПМИ (основной поток)]]&lt;br /&gt;
&lt;br /&gt;
[[Теория_вероятностей_2016/2017_(пилотный_поток) | Теория вероятностей на ПМИ (пилотный поток)]]&lt;br /&gt;
&lt;br /&gt;
[[Архитектура_компьютеров_и_операционные_системы_2016/2017 | Архитектура компьютеров и операционные системы]]&lt;br /&gt;
&lt;br /&gt;
[[Факультатив_теория_вычислений_2016/2017 | Факультатив теория вычислений на ПМИ]]&lt;br /&gt;
&lt;br /&gt;
[[Дополнительные_главы_теории_вероятностей_(факультатив,_2017) | Дополнительные главы теории вероятностей (факультатив)]]&lt;br /&gt;
&lt;br /&gt;
[[Дифференциальные_уравнения_(2_курс,_2016/2017) | Дифференциальные уравнения]]&lt;br /&gt;
&lt;br /&gt;
[[Математическая_статистика_2016/2017_(пилотный_поток) | Математическая статистика на ПМИ (пилотный поток)]]&lt;br /&gt;
&lt;br /&gt;
|| &lt;br /&gt;
&lt;br /&gt;
[[НИС_Машинное_обучение_и_приложения_2016/2017 | НИС Машинное обучение и приложения на ПМИ]]&lt;br /&gt;
&lt;br /&gt;
[[Машинное_обучение_1 | Машинное обучение 1 на ПМИ]]&lt;br /&gt;
&lt;br /&gt;
[[Машинное_обучение_2 | Машинное обучение 2 на ПМИ]]&lt;br /&gt;
&lt;br /&gt;
[[Прикладной_статистический_анализ_данных | Прикладной статистический анализ данных на ПМИ]]&lt;br /&gt;
&lt;br /&gt;
[[Численные_методы_в_анализе_данных | Численные методы в анализе данных на ПМИ]]&lt;br /&gt;
&lt;br /&gt;
[http://www.machinelearning.ru/wiki/index.php?title=Статистика_случайных_процессов_(курс_лекций,_ФКН_ВШЭ) Вероятностные модели и статистика случайных процессов на ПМИ]&lt;br /&gt;
&lt;br /&gt;
[http://www.machinelearning.ru/wiki/index.php?title=Opt Методы оптимизации на ПМИ (специализации МОП и РС)]&lt;br /&gt;
&lt;br /&gt;
[[НИС_Распределенные_системы_(осень_2016) | НИС Распределенные системы]]&lt;br /&gt;
&lt;br /&gt;
[[Анализ и верификация алгоритмов биржевой торговли | Анализ и верификация алгоритмов для систем биржевой торговли ]]&lt;br /&gt;
&lt;br /&gt;
[[Программирование_на_графических_процессорах | Программирование на графических процессорах]]&lt;br /&gt;
&lt;br /&gt;
[[ЯРПО | Языки разработки ПО (курс по выбору) на ПМИ]]&lt;br /&gt;
&lt;br /&gt;
[[Data analysis (Software Engineering) 2017 | Data analysis  на ПИ]]&lt;br /&gt;
&lt;br /&gt;
[[Базы данных 2 | Базы данных 2 ]]&lt;br /&gt;
&lt;br /&gt;
[[Компьютерные сети 2 | Компьютерные сети 2]]&lt;br /&gt;
&lt;br /&gt;
[[Машинное_обучение_на_больших_данных | Машинное обучение на больших данных на ПМИ]]&lt;br /&gt;
&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
[[Современные_методы_машинного_обучения_(курс_майнора) | Современные методы машинного обучения (курс майнора)]]&lt;br /&gt;
&lt;br /&gt;
[[Майнор_Интеллектуальный_анализ_данных/Введение_в_программирование_2016/2017 | Введение в программирование (курс майнора)]]&lt;br /&gt;
&lt;br /&gt;
[[Майнор Интеллектуальный анализ данных/Введение в анализ данных | Введение в анализ данных (курс майнора)]]&lt;br /&gt;
&lt;br /&gt;
[[Майнор Интеллектуальный анализ данных/Прикладные задачи анализа данных| Прикладные задачи анализа данных (курс майнора)]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|width=100%&lt;br /&gt;
|style=&amp;quot;vertical-align:top;&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Первая колонка --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Курсы за 2015/16 учебный год ===&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| [[Технологии программирования|Технологии программирования на ПМИ]]&lt;br /&gt;
|-&lt;br /&gt;
|[[ОиМП-2015|Основы и методология программирования на ПМИ]]&lt;br /&gt;
|-&lt;br /&gt;
|[[Алгоритмы и структуры данных]]&lt;br /&gt;
|-&lt;br /&gt;
|[[Линейная алгебра и геометрия_2015/2016 | Линейная алгебра и геометрия на ПМИ]]&lt;br /&gt;
|-&lt;br /&gt;
|[[Алгебра_2015/2016 | Алгебра на ПМИ]]&lt;br /&gt;
|-&lt;br /&gt;
|[http://hsealgebra.wikidot.com/ Алгебра на ПИ]&lt;br /&gt;
|-&lt;br /&gt;
|[[Компьютерные системы]]&lt;br /&gt;
|-&lt;br /&gt;
|[[Математический анализ на ПМИ_2015/2016 | Математический анализ на ПМИ]]&lt;br /&gt;
|-&lt;br /&gt;
|[[Факультатив_Матпрактикум | Матпрактикум (факультатив) на ПМИ]]&lt;br /&gt;
|-&lt;br /&gt;
|[[Data analysis (Software Engineering)]]&amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|[[Майнор Интеллектуальный анализ данных/Введение в программирование|Введение в программирование (курс майнора) на ПМИ]]&lt;br /&gt;
|-&lt;br /&gt;
|[[Майнор Интеллектуальный анализ данных/Введение в анализ данных/2015-2016|Введение в анализ данных (курс майнора) на ПМИ]]&lt;br /&gt;
|-&lt;br /&gt;
|[[НИС Машинное обучение и приложения|НИС Машинное обучение и приложения на ПМИ]]&lt;br /&gt;
|-&lt;br /&gt;
|[[Архитектура компьютеров и системное программирование (ПМИ_4, 2015/2016)|Архитектура компьютеров и системное программирование (4 курс)]]&lt;br /&gt;
|-&lt;br /&gt;
|[[Дифференциальные уравнения (2 курс, 2015/2016)| Дифференциальные уравнения]]&lt;br /&gt;
|-&lt;br /&gt;
|[[Введение в VBA|Введение в VBA]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|style=&amp;quot;vertical-align:top;&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Вторая колонка --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Курсы за 2014/15 учебный год ===&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Основы и методологии программирования]]&amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|[[Алгоритмы и структуры данных 2015 | Алгоритмы и структуры данных]]&amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|[[Анализ данных (Программная инженерия)]]&amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|[[Алгебра_2014/2015 | Алгебра]]&amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|[[Magolego_sna_2015| MAGoLEGO Social Network Analysis]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Проектная работа ====&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Проектная работа]] &amp;lt;br /&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|[[Учебная практика 1 курс (2016)]]&lt;br /&gt;
|-&lt;br /&gt;
|[[Проектная работа 2 курс (2016)]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Завершение двухколоночной таблицы --&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Мероприятия факультета компьютерных наук ==&lt;br /&gt;
=== Summer School 2015 ===&lt;br /&gt;
[[Introduction to Natural Language Processing|Introduction to Natural Language Processing]]&lt;br /&gt;
#[[Lecture 1. Introduction|Introduction]]&lt;br /&gt;
#[[Lecture 2. Tokenization and word counts|Tokenization and word counts]]&lt;br /&gt;
#[[Lecture 3. POS tagging. Key word and phrase extraction|POS tagging. Key word and phrase extraction]]&lt;br /&gt;
#[[Lecture 4. Parsing|Parsing]]&lt;br /&gt;
#[[Lecture 5. Language sources|Language sources]]&lt;br /&gt;
#[[Lecture 6. Synonyms and near-synonyms detection|Synonyms and near-synonyms detection]]&lt;br /&gt;
#[[Lecture 8. Suffix trees for NLP|Suffix trees for NLP]]&lt;br /&gt;
#[[NLP References|References]]&lt;br /&gt;
&lt;br /&gt;
== Архив ==&lt;br /&gt;
* [[Учебная практика 1 курс (2015)]]&lt;/div&gt;</summary>
		<author><name>Luc1ph3r</name></author>
	</entry>
	<entry>
		<id>https://wiki.cs.hse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_1&amp;diff=19617</id>
		<title>Базы данных/Лабораторная работа 1</title>
		<link rel="alternate" type="text/html" href="https://wiki.cs.hse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_1&amp;diff=19617"/>
		<updated>2016-06-04T11:08:05Z</updated>

		<summary type="html">&lt;p&gt;Luc1ph3r: Добавлена информация о том, где находятся логи.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Задачи: освоить самые необходимые навыки настройки СУБД, получения данных и манипуляции с ними, а также составления простых отчетов.&lt;br /&gt;
&lt;br /&gt;
=== Введение ===&lt;br /&gt;
&lt;br /&gt;
Так как у некоторых групп лабораторные работы начинаются раньше первой лекции, то предлагается [http://wiki.cs.hse.ru/%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D1%82%D0%B5%D1%80%D0%BC%D0%B8%D0%BD%D1%8B краткий список терминов], используемых в лабораторной работе.&lt;br /&gt;
&lt;br /&gt;
PostgreSQL - популярная реляционная система управления базами данных. Эта СУБД используется многими крупными компаниями, являясь единственной хорошо развитой свободной альтернативой наряду с MySQL. Но по сравнению с MySQL, PostgreSQL предоставляет больше возможностей для работы с большими объемами данных (не &amp;quot;big data&amp;quot;, но до терабайта).&lt;br /&gt;
&lt;br /&gt;
В качестве базы данных в лабораторных работах будет использоваться база фильмов IMDB (сам сайт также использует эту СУБД). Дамп базы достаточно большой, поэтому, если у вас есть возможность, скачайте и импортируйте его заранее.&lt;br /&gt;
&lt;br /&gt;
Рекомендуется использовать Ubuntu 14.04 и PostgreSQL 8.1+. Также нужно примерно 10 Гб места на диске.&lt;br /&gt;
&lt;br /&gt;
Для выполнения запросов подойдет и терминал, но можно использовать IDE (например, DataGrip или любую другую от JetBrains с аналогичным плагином).&lt;br /&gt;
&lt;br /&gt;
База данных, которая используется в лабораторных работах: https://yadi.sk/d/EVhJUiroqgzWj&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 1: Установка PostgreSQL ===&lt;br /&gt;
&lt;br /&gt;
Первая задача состоит в том, чтобы установить СУБД и проверить ее работоспособность.&lt;br /&gt;
&lt;br /&gt;
Выполните в терминале:&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install postgresql postgresql-contrib&lt;br /&gt;
&lt;br /&gt;
Сервер PostgreSQL создает отдельно пользователя в системе для доступа к базе. Чтобы переключиться на этого пользователя, выполните:&lt;br /&gt;
&lt;br /&gt;
 sudo -i -u postgres &lt;br /&gt;
&lt;br /&gt;
Теперь вы можете войти в интерактивный режим работы с СУБД:&lt;br /&gt;
&lt;br /&gt;
 psql&lt;br /&gt;
&lt;br /&gt;
Приглашение в интерактивном режиме выглядит так:&lt;br /&gt;
&lt;br /&gt;
 postgres=# &lt;br /&gt;
&lt;br /&gt;
Чтобы посмотреть, какие базы уже есть в системе, наберите:&lt;br /&gt;
&lt;br /&gt;
 \l&lt;br /&gt;
&lt;br /&gt;
Примерный результат:&lt;br /&gt;
&lt;br /&gt;
 postgres=# \l&lt;br /&gt;
                                  List of databases&lt;br /&gt;
    Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   &lt;br /&gt;
 -----------+----------+----------+-------------+-------------+-----------------------&lt;br /&gt;
  postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | &lt;br /&gt;
  template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +&lt;br /&gt;
            |          |          |             |             | postgres=CTc/postgres&lt;br /&gt;
  template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +&lt;br /&gt;
            |          |          |             |             | postgres=CTc/postgres&lt;br /&gt;
 (3 rows)&lt;br /&gt;
&lt;br /&gt;
Альтернативно, можно выполнить запрос:&lt;br /&gt;
&lt;br /&gt;
 SELECT datname FROM pg_database;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Чтобы работать с конкретной базой, ее нужно выбрать. Выполните \c database_name:&lt;br /&gt;
&lt;br /&gt;
 postgres=# \c imdb&lt;br /&gt;
 You are now connected to database &amp;quot;imdb&amp;quot; as user &amp;quot;postgres&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чтобы узнать, какие таблицы есть базе, выполните:&lt;br /&gt;
&lt;br /&gt;
 \d&lt;br /&gt;
&lt;br /&gt;
Альтернативный запрос:&lt;br /&gt;
&lt;br /&gt;
 SELECT table_name FROM information_schema.tables WHERE table_schema = &#039;public&#039;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Чтобы узнать, какие есть колонки в таблице:&lt;br /&gt;
&lt;br /&gt;
 \d+ table&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
 \d table&lt;br /&gt;
&lt;br /&gt;
Альтернативный запрос:...&lt;br /&gt;
&lt;br /&gt;
 SELECT column_name FROM information_schema.columns WHERE table_name =&#039;table&#039;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 2: Основы администрирования PostgreSQL ===&lt;br /&gt;
&lt;br /&gt;
Следующая задача состоит в том, чтобы настроить два важный параметра:&lt;br /&gt;
&lt;br /&gt;
* логирование запросов - чтобы подтвердить, что вы честно выполняли лабу&lt;br /&gt;
* ручное подтверждение вносимых изменений - чтобы в случае некорректных запросов вы могли откатить свои изменения простым способом.&lt;br /&gt;
&lt;br /&gt;
Про второй механизм подробнее. Когда вы вносите изменения в данные, они не сразу вступают в силу. СУБД создает diff аналогичный тому, который можно видеть в git. После этого вы начинаете работать с измененной версией, но в других сессиях данные по-прежнему старые. Если вы что-то сделали неправильно, вы можете откатить изменения в своей сессии с помощью команды rollback. Если же все изменения корректны, подтвердите их, выполнив commit. Закоммиченные изменения откатить намного сложнее, поэтому как правило в СУБД отключают опцию autocommit, которая подтверждает изменения автоматически.&lt;br /&gt;
&lt;br /&gt;
Когда вы завершаете сессию, выполняется rollback. Если вы убиваете процесс, то он может еще некоторое время &amp;quot;держать&amp;quot; данные, не давая их изменить.&lt;br /&gt;
&lt;br /&gt;
Приступим к конфигурированию.&lt;br /&gt;
&lt;br /&gt;
PostgreSQL представлен в системе в виде сервиса, управлять которым можно как и обычно через команду service. Как правило, для внесения каких-либо изменений нужно перезапустить сервис.&lt;br /&gt;
&lt;br /&gt;
Конфигурационный файл:&lt;br /&gt;
&lt;br /&gt;
 sudo vim /etc/postgresql/9.*/main/postgresql.conf&lt;br /&gt;
&lt;br /&gt;
Допишите или раскомментируйте:&lt;br /&gt;
&lt;br /&gt;
 log_line_prefix = &#039;%t %c %u &#039; # time sessionid user&lt;br /&gt;
 log_statement = &#039;all&#039;&lt;br /&gt;
&lt;br /&gt;
Управлять некоторыми параметрами можно прямо из сессии с СУБД. Например включение подробного логирования:&lt;br /&gt;
&lt;br /&gt;
 SELECT set_config(&#039;log_statement&#039;, &#039;all&#039;, true);&lt;br /&gt;
&lt;br /&gt;
Если вы используете Ubuntu, то по умолчанию лог-файлы могут быть найдены по пути &amp;lt;code&amp;gt;/var/log/postgresql/*&amp;lt;/code&amp;gt;. Если же у вас другой дистрибутив, то конфигурация может отличаться. (Например, для &amp;lt;code&amp;gt;ArchLinux&amp;lt;/code&amp;gt; нужно в конфигурационном файле &amp;lt;code&amp;gt;/var/lib/postgres/data/postgresql.conf&amp;lt;/code&amp;gt; указать режим логированния с помощью &amp;lt;code&amp;gt;log_destination=&#039;stderr&#039;&amp;lt;/code&amp;gt; и включить запись в файл &amp;lt;code&amp;gt;logging_collector=on&amp;lt;/code&amp;gt;. На самом деле, лучше найти эти строчки в конфигурационном файле и почитать, что они значат. Внутри конфига всё хорошо объяснено).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Чтобы отключить автокоммит, от пользователя postgres допишите в файл или создайте новый, если его нет ~/.psqlrc:&lt;br /&gt;
&lt;br /&gt;
 \set AUTOCOMMIT off &lt;br /&gt;
&lt;br /&gt;
Также можно инициировать процедуру, которая внесет изменения глобально только в случае выполнения commit:&lt;br /&gt;
&lt;br /&gt;
 BEGIN;&lt;br /&gt;
 -- манипуляции с данными&lt;br /&gt;
 COMMIT;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 3: импорт и экспорт базы данных IMDB ===&lt;br /&gt;
&lt;br /&gt;
Две наиболее важные операции. Выполняйте в сессии пользователя postgres.&lt;br /&gt;
&lt;br /&gt;
Экспортировать базу данных:&lt;br /&gt;
&lt;br /&gt;
 pg_dump dbname | gzip &amp;gt; filename.gz&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Импортировать базу:&lt;br /&gt;
&lt;br /&gt;
 gunzip -c filename.gz | psql dbname&lt;br /&gt;
&lt;br /&gt;
Попробуйте импортировать базу IMDB:&lt;br /&gt;
&lt;br /&gt;
https://yadi.sk/d/EVhJUiroqgzWj&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Важно:&#039;&#039;&#039; прежде чем импортировать дамп, нужно создать базу данных:&lt;br /&gt;
&lt;br /&gt;
В psql выполните:&lt;br /&gt;
&lt;br /&gt;
 create database imdb;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Важно: прежде чем импортировать дамп, нужно включить автокоммит.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Это займет некоторое время (20 минут - норм). &lt;br /&gt;
&lt;br /&gt;
Также можно отдельно импортировать схему и данные частями:&lt;br /&gt;
&lt;br /&gt;
https://yadi.sk/d/759CTPxpqoCs2&lt;br /&gt;
&lt;br /&gt;
Используйте, например: ls imdb3*.gz | xargs gunzip | psql dbname&lt;br /&gt;
&lt;br /&gt;
Также можно импортировать только конкретные таблицы, указав их через ключ  --table.&lt;br /&gt;
&lt;br /&gt;
Можно импортировать только схему: --schema-only или только данные: --data-only&lt;br /&gt;
&lt;br /&gt;
==== Структура базы IMDB ====&lt;br /&gt;
&lt;br /&gt;
У каждой таблицы есть идентификатор, указанный как первичный ключ (id). По нему выбирать быстрее всего.&lt;br /&gt;
&lt;br /&gt;
Основные таблицы и их описание:&lt;br /&gt;
* title - названия фильмов (поле title) и год выпуска (поле production_year); если это сериал, то также здесь можно найти номер эпизода&lt;br /&gt;
* movie_info - характеристики и факты о фильме: movie_id - идентификатор из таблицы title (далее для краткой записи: title.id), info_type_id - идентификатор из таблицы info_type (info_type.id), info - текстовое поле со значением характеристики.&lt;br /&gt;
* name - актеры (имя и пол)&lt;br /&gt;
* person_info - характеристики и факты об актерах также с названиями характеристик из (info_type.id)&lt;br /&gt;
* char_name - роли (имена персонажей)&lt;br /&gt;
* cast_info - таблица со связью ролей (person_role_id), актеров (person_id) и фильмов (movie_id)&lt;br /&gt;
&lt;br /&gt;
=== Часть 4: Простые операции CRUD ===&lt;br /&gt;
&lt;br /&gt;
К простым операциям манипуляции данными (Create, Read, Update, Delete) относятся:&lt;br /&gt;
&lt;br /&gt;
* Добавление: INSERT&lt;br /&gt;
* Выборка: SELECT &lt;br /&gt;
* Обновление: UPDATE&lt;br /&gt;
* Удаление: DELETE&lt;br /&gt;
&lt;br /&gt;
==== Добавление данных INSERT ====&lt;br /&gt;
&lt;br /&gt;
Чтобы добавить новую запись в таблицу, нужно вычислить ее идентификатор. Для этого в PostgreSQL используются последовательности - числа, которые меняются по заданным правилам (обычно просто инкрементируются на единицу). &lt;br /&gt;
&lt;br /&gt;
Чтобы посмотреть список всех последовательностей выполните:&lt;br /&gt;
&lt;br /&gt;
 SELECT c.relname FROM pg_class c WHERE c.relkind = &#039;S&#039;;&lt;br /&gt;
&lt;br /&gt;
Именование последовательностей обычно выбирают предсказуемым, чтобы легко было понять, к какой таблице они относятся. &lt;br /&gt;
&lt;br /&gt;
Синтаксис INSERT выглядит так: сначала в скобках перечисляются атрибуты, которые будут вставлены, а затем после VALUES в скобках указываются значения. Можно также не перечислять атрибуты, тогда в VALUES нужно по порядку указать значения для всех. &lt;br /&gt;
&lt;br /&gt;
Попробуйте добавить себя в список актеров:&lt;br /&gt;
&lt;br /&gt;
 insert into name (id, name, gender) values(nextval(&#039;name_id_seq&#039;), &#039;Ivan Savin&#039;, &#039;m&#039;);&lt;br /&gt;
&lt;br /&gt;
Здесь nextval(&#039;name_id_seq&#039;) генерирует следующее значение для последовательности name_id_seq.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Важно:&#039;&#039;&#039; В предлагаемом дампе базы последовательности обнулены и не могут сгенерировать уникальный идентификатор сразу. Чтобы это исправить, укажите текущее значение последовательности максимальным идентификатором в таблице, к которой она относится. Пример:&lt;br /&gt;
&lt;br /&gt;
 select max(id) from name;&lt;br /&gt;
 select setval(&#039;name_id_seq&#039;, 5555233);&lt;br /&gt;
&lt;br /&gt;
Если вы отключили автокоммит, то, так как вы вносите изменения в данные, завершите операцию, выполнив:&lt;br /&gt;
&lt;br /&gt;
 commit;&lt;br /&gt;
&lt;br /&gt;
Если вы не уверены в своих изменениях, выполните:&lt;br /&gt;
&lt;br /&gt;
 rollback;&lt;br /&gt;
&lt;br /&gt;
За одну операцию INSERT можно вставлять несколько строк данных. Для этого после VALUES нужно перечислить кортежи данных через запятую:&lt;br /&gt;
&lt;br /&gt;
 insert into name (id, name, gender) &lt;br /&gt;
 values(nextval(&#039;name_id_seq&#039;), &#039;Dmitry Burmistrov&#039;, &#039;m&#039;), &lt;br /&gt;
 (nextval(&#039;name_id_seq&#039;), &#039;Victor Yakovlev&#039;, &#039;m&#039;);&lt;br /&gt;
&lt;br /&gt;
==== Выборка данных SELECT ====&lt;br /&gt;
&lt;br /&gt;
Для чтения данных из базы используется ключевое слово SELECT, после которого указывается список атрибутов, которые нужно получить в выборке. Если указать вместо списка атрибутов &amp;quot;*&amp;quot;, то выберутся все. Самый простой запрос выборки из базы данных выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 select * from info_type;&lt;br /&gt;
&lt;br /&gt;
Не пробуйте выбрать все данные из больших таблиц (title, name) - это займет много времени. Если вы хотите выбрать несколько кортежей данных для примера, то ограничьте результаты с помощью LIMIT:&lt;br /&gt;
&lt;br /&gt;
 select * from title limit 10;&lt;br /&gt;
&lt;br /&gt;
Условия выборки указываются после ключевого слова WHERE. Условия можно комбинировать с помощью скобок и слов OR и AND. Примеры условий:&lt;br /&gt;
&lt;br /&gt;
* WHERE title=&#039;Databases&#039; - простое условие равенства&lt;br /&gt;
* WHERE title like &#039;%base%&#039; - поиск по подстроке, &amp;quot;%&amp;quot; - любое количество любых символов&lt;br /&gt;
* WHERE created_date &amp;gt; now() - сравнение даты с текущим моментом; см. также http://www.postgresql.org/docs/8.3/static/functions-datetime.html&lt;br /&gt;
* WHERE title not in (&#039;Databases&#039;, &#039;Networks&#039;) - значение не входит в список&lt;br /&gt;
* WHERE not exists (SELECT * FROM ...) - выполняется, если подзапрос вернул хотя бы одну запись&lt;br /&gt;
* WHERE artist_id in (SELECT id FROM artist...) - подзапрос определяет множество значений.&lt;br /&gt;
&lt;br /&gt;
Пример запроса с условиями:&lt;br /&gt;
&lt;br /&gt;
 select * from title where title like &#039;%Matrix&#039; and production_year=1999;&lt;br /&gt;
&lt;br /&gt;
Также в блоке с перечислением атрибутов можно указывать подзапросы. Подзапрос будет выполняться в последнюю очередь для каждого кортежа, удовлетворяющего остальным условиям. Также, чтобы использовать условия из основного запроса в этом подзапросе, лучше указывать название атрибута вместе с таблицей, в которой он принадлежит:&lt;br /&gt;
&lt;br /&gt;
 select (select info from info_type where info_type.id=person_info.info_type_id), person_info.info from person_info where person_id=1732058;&lt;br /&gt;
&lt;br /&gt;
Если нужно вывести только уникальные кортежи, используйте distinct:&lt;br /&gt;
&lt;br /&gt;
  select distinct production_year from title;&lt;br /&gt;
&lt;br /&gt;
Попробуйте найти ваши любимые фильмы, указывая часть названия и комбинируя условия, указывая год выхода. Попробуйте найти ваших любимых актеров и факты о них.&lt;br /&gt;
&lt;br /&gt;
==== Обновление данных UPDATE ====&lt;br /&gt;
&lt;br /&gt;
Чтобы обновить данные, нужно указать, какие параметры вы хотите обновить и условия выборки обновляемых данных:&lt;br /&gt;
&lt;br /&gt;
 update cast_info set person_id=1732058 where movie_id=3514559;&lt;br /&gt;
&lt;br /&gt;
Если вы не укажите условия, то обновятся значения во всей таблице, обычно это не нужно.&lt;br /&gt;
&lt;br /&gt;
В запросе на обновление также можно использовать подзапросы. Единственное ограничение: нельзя в подзапросе использовать обновляемую таблицу, так как СУБД в этом случае можно ввести в бесконечный цикл обновления. Пример более понятного запроса на обновление:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Предостережение&#039;&#039;&#039;: не выполняйте следующий запрос, пока не разберетесь, что именно он делает.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 update cast_info set person_id=(select id from name where name=&#039;Savin Ivan&#039;) &lt;br /&gt;
 where movie_id=(select id from title where title like &#039;The Matrix&#039; and production_year=1999);&lt;br /&gt;
&lt;br /&gt;
Если вы не закоммитите изменения, то обновляемые записи останутся залоченными, то есть их невозможно будет обновить в других сессиях. Попробуйте не выполняя коммит, открыть новую сессию и попытаться обновить те же данные. В результате новая сессия зависнет, ожидая завершения транзакции в первой сессии. Закоммитьте изменения в первой сессии.&lt;br /&gt;
&lt;br /&gt;
Попробуйте назначить себя и своих друзей на подходящие роли в ваших любимых фильмах. Составьте запрос, который будет демонстрировать, кто где и какую роль играет (используя подзапросы).&lt;br /&gt;
&lt;br /&gt;
==== Удаление данных DELETE ====&lt;br /&gt;
&lt;br /&gt;
Синтаксис удаления данных аналогичен синтаксису выборки за исключением того, что вместо &amp;quot;SELECT * FROM&amp;quot; достаточно написать &amp;quot;DELETE FROM&amp;quot;. Будьте внимательны, удаляя данные и проверяйте условия перед отправкой коммита.&lt;br /&gt;
&lt;br /&gt;
Удалите актеров, которые вам не нравятся (или актера, выбранного случайно). Это сделать не так просто, как может показаться, потому что их идентификаторы используются в других таблицах, а нарушать целостность данных нельзя. Для корректного удаления, нужно найти все связи актера с фильмами и удалить сначала их, после этого удалить информацию о них из таблицы фактов, после этого станет доступно удаление.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 5: Агрегация данных ===&lt;br /&gt;
&lt;br /&gt;
Часто с помощью СУБД генерируют различные полезные отчеты. В любой популярной СУБД есть агрегирующие функции, с помощью которых, можно собрать статистику о данных. Самая простая статистика: количество записей, удовлетворяющих заданным условиям. Пример выбора количества фильмов в базе:&lt;br /&gt;
&lt;br /&gt;
 select count(1) from title where kind_id=(select id from kind_type where kind=&#039;movie&#039;);&lt;br /&gt;
&lt;br /&gt;
Для числовых атрибутов также помимо COUNT можно использовать SUM, AVG и другие востребованные функции.&lt;br /&gt;
&lt;br /&gt;
Попробуйте вывести, в скольких фильмах снимались ваши любимые актеры.&lt;br /&gt;
&lt;br /&gt;
==== Преобразование атрибутов по некоторым правилам ====&lt;br /&gt;
&lt;br /&gt;
Если нужно преобразовать какой-либо атрибут по правилам (условиям), то можно использоваться конструкцию CASE ... WHEN ... THEN ... END.&lt;br /&gt;
В этом случае данная конструкция будет обозначать новый атрибут у записи. Рассмотрим её детальнее.&lt;br /&gt;
&lt;br /&gt;
 case &lt;br /&gt;
     when &#039;&#039;&#039;&#039;&#039;condition1&#039;&#039;&#039;&#039;&#039; then &#039;&#039;&#039;&#039;&#039;result1&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     when &#039;&#039;&#039;&#039;&#039;condition2&#039;&#039;&#039;&#039;&#039; then &#039;&#039;&#039;&#039;&#039;result2&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     else &#039;&#039;&#039;&#039;&#039;result3&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Если условие &#039;&#039;&#039;&#039;&#039;condition1&#039;&#039;&#039;&#039;&#039; верно (т.е. &#039;&#039;&#039;true&#039;&#039;&#039;), то атрибуту будет&lt;br /&gt;
присвоено значение &#039;&#039;&#039;&#039;&#039;result1&#039;&#039;&#039;&#039;&#039;. Если &#039;&#039;&#039;&#039;&#039;condition1&#039;&#039;&#039;&#039;&#039; неверно, то &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt; перейдёт&lt;br /&gt;
к следующему &amp;lt;code&amp;gt;when&amp;lt;/code&amp;gt;. Если ни один из &#039;&#039;&#039;&#039;&#039;condition&#039;&#039;&#039;&#039;&#039; не выполняется, то атрибуту будет &lt;br /&gt;
присвоено значение, указанное в &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; (если в этом случае отсутствует &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt;, то&lt;br /&gt;
атрибут будет равен &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Представим таблицу &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! a&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Добавим теперь к каждой записи новый атрибут, который будет обозначать значение атрибута &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; словами:&lt;br /&gt;
 select&lt;br /&gt;
    a,&lt;br /&gt;
    case&lt;br /&gt;
        when a = 1 then &#039;one&#039;&lt;br /&gt;
        when a = 2 then &#039;two&#039;&lt;br /&gt;
        when a = 3 then &#039;three&#039;&lt;br /&gt;
        else &#039;other&#039;&lt;br /&gt;
    end&lt;br /&gt;
 from t;&lt;br /&gt;
&lt;br /&gt;
Результат:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! a&lt;br /&gt;
! case&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| one&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| two&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| three&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| other&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Как видно из результата, новый атрибут получил название &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt;. Если мы хотим переименовать его в &lt;br /&gt;
желаемый вариант, то это можно сделать с помощью &amp;lt;code&amp;gt;as&amp;lt;/code&amp;gt;:&lt;br /&gt;
 select&lt;br /&gt;
    a,&lt;br /&gt;
    case&lt;br /&gt;
        when a = 1 then &#039;one&#039;&lt;br /&gt;
        when a = 2 then &#039;two&#039;&lt;br /&gt;
        when a = 3 then &#039;three&#039;&lt;br /&gt;
        else &#039;other&#039;&lt;br /&gt;
    end as new_attribute&lt;br /&gt;
 from t;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! a&lt;br /&gt;
! new_attribute&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| one&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| two&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| three&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| other&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Также, чтобы каждый раз не писать &amp;lt;code&amp;gt;when a = &amp;lt;/code&amp;gt;, можно сразу указать, по какому атрибуту мы бежим:&lt;br /&gt;
 select&lt;br /&gt;
    a,&lt;br /&gt;
    case a&lt;br /&gt;
        when 1 then &#039;one&#039;&lt;br /&gt;
        when 2 then &#039;two&#039;&lt;br /&gt;
        when 3 then &#039;three&#039;&lt;br /&gt;
        else &#039;other&#039;&lt;br /&gt;
    end as new_attribute&lt;br /&gt;
 from t;&lt;br /&gt;
&lt;br /&gt;
Таким образом, используя &amp;lt;code&amp;gt;case..when..&amp;lt;/code&amp;gt; можно помечать нужные нам записи для дальнейшей обработки данных. &lt;br /&gt;
Например, добавить к фильму атрибут, обозначающий, относится фильм к 20 или 21 веку.&lt;br /&gt;
&lt;br /&gt;
 select&lt;br /&gt;
   *, &lt;br /&gt;
   case&lt;br /&gt;
     when production_year &amp;gt;= 1900 and production_year &amp;lt; 2000 then &#039;XX&#039;&lt;br /&gt;
     when production_year &amp;gt;= 2000 and production_year &amp;lt; 2100 then &#039;XXI&#039;&lt;br /&gt;
   end as century&lt;br /&gt;
 from title&lt;br /&gt;
&lt;br /&gt;
Сокращённый результат:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| 2395294&lt;br /&gt;
|-&lt;br /&gt;
| title&lt;br /&gt;
| (1979-03-11)&lt;br /&gt;
|-&lt;br /&gt;
| production_year&lt;br /&gt;
| 1979&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| XX&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Группировка агрегированных данных GROUP BY ====&lt;br /&gt;
&lt;br /&gt;
Статистику можно также сгруппировать по некоторому атрибуту, который возвращается запросом. Например, чтобы вывести количества фильмов, выпущенных в каждый год, выполните запрос:&lt;br /&gt;
&lt;br /&gt;
 select production_year, count(1) from title&lt;br /&gt;
 where kind_id=(select id from kind_type where kind=&#039;movie&#039;)&lt;br /&gt;
 group by production_year&lt;br /&gt;
 order by production_year;&lt;br /&gt;
&lt;br /&gt;
В запросе также результаты отсортированы по году выпуска с помощью ORDER BY.&lt;br /&gt;
&lt;br /&gt;
Попробуйте собрать следующие статистики: количество актеров и актрис; среднее количество фильмов в год, выпущенных в XX веке, и, выпущенных в XXI веке (с учетом текущего года). &lt;br /&gt;
&lt;br /&gt;
Попробуйте также узнать среднее количество ролей в фильмах в различные годы. Этот запрос может выполняться долго, поэтому рекомендуется сначала отлаживать его на небольшом количестве данных, используя LIMIT или какие-либо условия.&lt;br /&gt;
&lt;br /&gt;
=== Защита лабораторной работы ===&lt;br /&gt;
# Показать логи выполнения запросов. &lt;br /&gt;
# Прокомментировать для агрегаций, что и как происходит. &lt;br /&gt;
# Написать запрос по просьбе преподавателя.&lt;br /&gt;
&lt;br /&gt;
=== Полезные материалы ===&lt;br /&gt;
&lt;br /&gt;
Интерактивный урок по основам SQL запросов (видео лекции + задания): https://www.codeschool.com/courses/try-sql&lt;/div&gt;</summary>
		<author><name>Luc1ph3r</name></author>
	</entry>
	<entry>
		<id>https://wiki.cs.hse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_1&amp;diff=19608</id>
		<title>Базы данных/Лабораторная работа 1</title>
		<link rel="alternate" type="text/html" href="https://wiki.cs.hse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_1&amp;diff=19608"/>
		<updated>2016-06-03T20:45:57Z</updated>

		<summary type="html">&lt;p&gt;Luc1ph3r: Добавлена информация про использование case..when&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Задачи: освоить самые необходимые навыки настройки СУБД, получения данных и манипуляции с ними, а также составления простых отчетов.&lt;br /&gt;
&lt;br /&gt;
=== Введение ===&lt;br /&gt;
&lt;br /&gt;
Так как у некоторых групп лабораторные работы начинаются раньше первой лекции, то предлагается [http://wiki.cs.hse.ru/%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D1%82%D0%B5%D1%80%D0%BC%D0%B8%D0%BD%D1%8B краткий список терминов], используемых в лабораторной работе.&lt;br /&gt;
&lt;br /&gt;
PostgreSQL - популярная реляционная система управления базами данных. Эта СУБД используется многими крупными компаниями, являясь единственной хорошо развитой свободной альтернативой наряду с MySQL. Но по сравнению с MySQL, PostgreSQL предоставляет больше возможностей для работы с большими объемами данных (не &amp;quot;big data&amp;quot;, но до терабайта).&lt;br /&gt;
&lt;br /&gt;
В качестве базы данных в лабораторных работах будет использоваться база фильмов IMDB (сам сайт также использует эту СУБД). Дамп базы достаточно большой, поэтому, если у вас есть возможность, скачайте и импортируйте его заранее.&lt;br /&gt;
&lt;br /&gt;
Рекомендуется использовать Ubuntu 14.04 и PostgreSQL 8.1+. Также нужно примерно 10 Гб места на диске.&lt;br /&gt;
&lt;br /&gt;
Для выполнения запросов подойдет и терминал, но можно использовать IDE (например, DataGrip или любую другую от JetBrains с аналогичным плагином).&lt;br /&gt;
&lt;br /&gt;
База данных, которая используется в лабораторных работах: https://yadi.sk/d/EVhJUiroqgzWj&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 1: Установка PostgreSQL ===&lt;br /&gt;
&lt;br /&gt;
Первая задача состоит в том, чтобы установить СУБД и проверить ее работоспособность.&lt;br /&gt;
&lt;br /&gt;
Выполните в терминале:&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install postgresql postgresql-contrib&lt;br /&gt;
&lt;br /&gt;
Сервер PostgreSQL создает отдельно пользователя в системе для доступа к базе. Чтобы переключиться на этого пользователя, выполните:&lt;br /&gt;
&lt;br /&gt;
 sudo -i -u postgres &lt;br /&gt;
&lt;br /&gt;
Теперь вы можете войти в интерактивный режим работы с СУБД:&lt;br /&gt;
&lt;br /&gt;
 psql&lt;br /&gt;
&lt;br /&gt;
Приглашение в интерактивном режиме выглядит так:&lt;br /&gt;
&lt;br /&gt;
 postgres=# &lt;br /&gt;
&lt;br /&gt;
Чтобы посмотреть, какие базы уже есть в системе, наберите:&lt;br /&gt;
&lt;br /&gt;
 \l&lt;br /&gt;
&lt;br /&gt;
Примерный результат:&lt;br /&gt;
&lt;br /&gt;
 postgres=# \l&lt;br /&gt;
                                  List of databases&lt;br /&gt;
    Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   &lt;br /&gt;
 -----------+----------+----------+-------------+-------------+-----------------------&lt;br /&gt;
  postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | &lt;br /&gt;
  template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +&lt;br /&gt;
            |          |          |             |             | postgres=CTc/postgres&lt;br /&gt;
  template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +&lt;br /&gt;
            |          |          |             |             | postgres=CTc/postgres&lt;br /&gt;
 (3 rows)&lt;br /&gt;
&lt;br /&gt;
Альтернативно, можно выполнить запрос:&lt;br /&gt;
&lt;br /&gt;
 SELECT datname FROM pg_database;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Чтобы работать с конкретной базой, ее нужно выбрать. Выполните \c database_name:&lt;br /&gt;
&lt;br /&gt;
 postgres=# \c imdb&lt;br /&gt;
 You are now connected to database &amp;quot;imdb&amp;quot; as user &amp;quot;postgres&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чтобы узнать, какие таблицы есть базе, выполните:&lt;br /&gt;
&lt;br /&gt;
 \d&lt;br /&gt;
&lt;br /&gt;
Альтернативный запрос:&lt;br /&gt;
&lt;br /&gt;
 SELECT table_name FROM information_schema.tables WHERE table_schema = &#039;public&#039;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Чтобы узнать, какие есть колонки в таблице:&lt;br /&gt;
&lt;br /&gt;
 \d+ table&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
 \d table&lt;br /&gt;
&lt;br /&gt;
Альтернативный запрос:...&lt;br /&gt;
&lt;br /&gt;
 SELECT column_name FROM information_schema.columns WHERE table_name =&#039;table&#039;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 2: Основы администрирования PostgreSQL ===&lt;br /&gt;
&lt;br /&gt;
Следующая задача состоит в том, чтобы настроить два важный параметра:&lt;br /&gt;
&lt;br /&gt;
* логирование запросов - чтобы подтвердить, что вы честно выполняли лабу&lt;br /&gt;
* ручное подтверждение вносимых изменений - чтобы в случае некорректных запросов вы могли откатить свои изменения простым способом.&lt;br /&gt;
&lt;br /&gt;
Про второй механизм подробнее. Когда вы вносите изменения в данные, они не сразу вступают в силу. СУБД создает diff аналогичный тому, который можно видеть в git. После этого вы начинаете работать с измененной версией, но в других сессиях данные по-прежнему старые. Если вы что-то сделали неправильно, вы можете откатить изменения в своей сессии с помощью команды rollback. Если же все изменения корректны, подтвердите их, выполнив commit. Закоммиченные изменения откатить намного сложнее, поэтому как правило в СУБД отключают опцию autocommit, которая подтверждает изменения автоматически.&lt;br /&gt;
&lt;br /&gt;
Когда вы завершаете сессию, выполняется rollback. Если вы убиваете процесс, то он может еще некоторое время &amp;quot;держать&amp;quot; данные, не давая их изменить.&lt;br /&gt;
&lt;br /&gt;
Приступим к конфигурированию.&lt;br /&gt;
&lt;br /&gt;
PostgreSQL представлен в системе в виде сервиса, управлять которым можно как и обычно через команду service. Как правило, для внесения каких-либо изменений нужно перезапустить сервис.&lt;br /&gt;
&lt;br /&gt;
Конфигурационный файл:&lt;br /&gt;
&lt;br /&gt;
 sudo vim /etc/postgresql/9.*/main/postgresql.conf&lt;br /&gt;
&lt;br /&gt;
Допишите или раскомментируйте:&lt;br /&gt;
&lt;br /&gt;
 log_line_prefix = &#039;%t %c %u &#039; # time sessionid user&lt;br /&gt;
 log_statement = &#039;all&#039;&lt;br /&gt;
&lt;br /&gt;
Управлять некоторыми параметрами можно прямо из сессии с СУБД. Например включение подробного логирования:&lt;br /&gt;
&lt;br /&gt;
 SELECT set_config(&#039;log_statement&#039;, &#039;all&#039;, true);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Чтобы отключить автокоммит, от пользователя postgres допишите в файл или создайте новый, если его нет ~/.psqlrc:&lt;br /&gt;
&lt;br /&gt;
 \set AUTOCOMMIT off &lt;br /&gt;
&lt;br /&gt;
Также можно инициировать процедуру, которая внесет изменения глобально только в случае выполнения commit:&lt;br /&gt;
&lt;br /&gt;
 BEGIN;&lt;br /&gt;
 -- манипуляции с данными&lt;br /&gt;
 COMMIT;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 3: импорт и экспорт базы данных IMDB ===&lt;br /&gt;
&lt;br /&gt;
Две наиболее важные операции. Выполняйте в сессии пользователя postgres.&lt;br /&gt;
&lt;br /&gt;
Экспортировать базу данных:&lt;br /&gt;
&lt;br /&gt;
 pg_dump dbname | gzip &amp;gt; filename.gz&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Импортировать базу:&lt;br /&gt;
&lt;br /&gt;
 gunzip -c filename.gz | psql dbname&lt;br /&gt;
&lt;br /&gt;
Попробуйте импортировать базу IMDB:&lt;br /&gt;
&lt;br /&gt;
https://yadi.sk/d/EVhJUiroqgzWj&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Важно:&#039;&#039;&#039; прежде чем импортировать дамп, нужно создать базу данных:&lt;br /&gt;
&lt;br /&gt;
В psql выполните:&lt;br /&gt;
&lt;br /&gt;
 create database imdb;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Важно: прежде чем импортировать дамп, нужно включить автокоммит.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Это займет некоторое время (20 минут - норм). &lt;br /&gt;
&lt;br /&gt;
Также можно отдельно импортировать схему и данные частями:&lt;br /&gt;
&lt;br /&gt;
https://yadi.sk/d/759CTPxpqoCs2&lt;br /&gt;
&lt;br /&gt;
Используйте, например: ls imdb3*.gz | xargs gunzip | psql dbname&lt;br /&gt;
&lt;br /&gt;
Также можно импортировать только конкретные таблицы, указав их через ключ  --table.&lt;br /&gt;
&lt;br /&gt;
Можно импортировать только схему: --schema-only или только данные: --data-only&lt;br /&gt;
&lt;br /&gt;
==== Структура базы IMDB ====&lt;br /&gt;
&lt;br /&gt;
У каждой таблицы есть идентификатор, указанный как первичный ключ (id). По нему выбирать быстрее всего.&lt;br /&gt;
&lt;br /&gt;
Основные таблицы и их описание:&lt;br /&gt;
* title - названия фильмов (поле title) и год выпуска (поле production_year); если это сериал, то также здесь можно найти номер эпизода&lt;br /&gt;
* movie_info - характеристики и факты о фильме: movie_id - идентификатор из таблицы title (далее для краткой записи: title.id), info_type_id - идентификатор из таблицы info_type (info_type.id), info - текстовое поле со значением характеристики.&lt;br /&gt;
* name - актеры (имя и пол)&lt;br /&gt;
* person_info - характеристики и факты об актерах также с названиями характеристик из (info_type.id)&lt;br /&gt;
* char_name - роли (имена персонажей)&lt;br /&gt;
* cast_info - таблица со связью ролей (person_role_id), актеров (person_id) и фильмов (movie_id)&lt;br /&gt;
&lt;br /&gt;
=== Часть 4: Простые операции CRUD ===&lt;br /&gt;
&lt;br /&gt;
К простым операциям манипуляции данными (Create, Read, Update, Delete) относятся:&lt;br /&gt;
&lt;br /&gt;
* Добавление: INSERT&lt;br /&gt;
* Выборка: SELECT &lt;br /&gt;
* Обновление: UPDATE&lt;br /&gt;
* Удаление: DELETE&lt;br /&gt;
&lt;br /&gt;
==== Добавление данных INSERT ====&lt;br /&gt;
&lt;br /&gt;
Чтобы добавить новую запись в таблицу, нужно вычислить ее идентификатор. Для этого в PostgreSQL используются последовательности - числа, которые меняются по заданным правилам (обычно просто инкрементируются на единицу). &lt;br /&gt;
&lt;br /&gt;
Чтобы посмотреть список всех последовательностей выполните:&lt;br /&gt;
&lt;br /&gt;
 SELECT c.relname FROM pg_class c WHERE c.relkind = &#039;S&#039;;&lt;br /&gt;
&lt;br /&gt;
Именование последовательностей обычно выбирают предсказуемым, чтобы легко было понять, к какой таблице они относятся. &lt;br /&gt;
&lt;br /&gt;
Синтаксис INSERT выглядит так: сначала в скобках перечисляются атрибуты, которые будут вставлены, а затем после VALUES в скобках указываются значения. Можно также не перечислять атрибуты, тогда в VALUES нужно по порядку указать значения для всех. &lt;br /&gt;
&lt;br /&gt;
Попробуйте добавить себя в список актеров:&lt;br /&gt;
&lt;br /&gt;
 insert into name (id, name, gender) values(nextval(&#039;name_id_seq&#039;), &#039;Ivan Savin&#039;, &#039;m&#039;);&lt;br /&gt;
&lt;br /&gt;
Здесь nextval(&#039;name_id_seq&#039;) генерирует следующее значение для последовательности name_id_seq.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Важно:&#039;&#039;&#039; В предлагаемом дампе базы последовательности обнулены и не могут сгенерировать уникальный идентификатор сразу. Чтобы это исправить, укажите текущее значение последовательности максимальным идентификатором в таблице, к которой она относится. Пример:&lt;br /&gt;
&lt;br /&gt;
 select max(id) from name;&lt;br /&gt;
 select setval(&#039;name_id_seq&#039;, 5555233);&lt;br /&gt;
&lt;br /&gt;
Если вы отключили автокоммит, то, так как вы вносите изменения в данные, завершите операцию, выполнив:&lt;br /&gt;
&lt;br /&gt;
 commit;&lt;br /&gt;
&lt;br /&gt;
Если вы не уверены в своих изменениях, выполните:&lt;br /&gt;
&lt;br /&gt;
 rollback;&lt;br /&gt;
&lt;br /&gt;
За одну операцию INSERT можно вставлять несколько строк данных. Для этого после VALUES нужно перечислить кортежи данных через запятую:&lt;br /&gt;
&lt;br /&gt;
 insert into name (id, name, gender) &lt;br /&gt;
 values(nextval(&#039;name_id_seq&#039;), &#039;Dmitry Burmistrov&#039;, &#039;m&#039;), &lt;br /&gt;
 (nextval(&#039;name_id_seq&#039;), &#039;Victor Yakovlev&#039;, &#039;m&#039;);&lt;br /&gt;
&lt;br /&gt;
==== Выборка данных SELECT ====&lt;br /&gt;
&lt;br /&gt;
Для чтения данных из базы используется ключевое слово SELECT, после которого указывается список атрибутов, которые нужно получить в выборке. Если указать вместо списка атрибутов &amp;quot;*&amp;quot;, то выберутся все. Самый простой запрос выборки из базы данных выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 select * from info_type;&lt;br /&gt;
&lt;br /&gt;
Не пробуйте выбрать все данные из больших таблиц (title, name) - это займет много времени. Если вы хотите выбрать несколько кортежей данных для примера, то ограничьте результаты с помощью LIMIT:&lt;br /&gt;
&lt;br /&gt;
 select * from title limit 10;&lt;br /&gt;
&lt;br /&gt;
Условия выборки указываются после ключевого слова WHERE. Условия можно комбинировать с помощью скобок и слов OR и AND. Примеры условий:&lt;br /&gt;
&lt;br /&gt;
* WHERE title=&#039;Databases&#039; - простое условие равенства&lt;br /&gt;
* WHERE title like &#039;%base%&#039; - поиск по подстроке, &amp;quot;%&amp;quot; - любое количество любых символов&lt;br /&gt;
* WHERE created_date &amp;gt; now() - сравнение даты с текущим моментом; см. также http://www.postgresql.org/docs/8.3/static/functions-datetime.html&lt;br /&gt;
* WHERE title not in (&#039;Databases&#039;, &#039;Networks&#039;) - значение не входит в список&lt;br /&gt;
* WHERE not exists (SELECT * FROM ...) - выполняется, если подзапрос вернул хотя бы одну запись&lt;br /&gt;
* WHERE artist_id in (SELECT id FROM artist...) - подзапрос определяет множество значений.&lt;br /&gt;
&lt;br /&gt;
Пример запроса с условиями:&lt;br /&gt;
&lt;br /&gt;
 select * from title where title like &#039;%Matrix&#039; and production_year=1999;&lt;br /&gt;
&lt;br /&gt;
Также в блоке с перечислением атрибутов можно указывать подзапросы. Подзапрос будет выполняться в последнюю очередь для каждого кортежа, удовлетворяющего остальным условиям. Также, чтобы использовать условия из основного запроса в этом подзапросе, лучше указывать название атрибута вместе с таблицей, в которой он принадлежит:&lt;br /&gt;
&lt;br /&gt;
 select (select info from info_type where info_type.id=person_info.info_type_id), person_info.info from person_info where person_id=1732058;&lt;br /&gt;
&lt;br /&gt;
Если нужно вывести только уникальные кортежи, используйте distinct:&lt;br /&gt;
&lt;br /&gt;
  select distinct production_year from title;&lt;br /&gt;
&lt;br /&gt;
Попробуйте найти ваши любимые фильмы, указывая часть названия и комбинируя условия, указывая год выхода. Попробуйте найти ваших любимых актеров и факты о них.&lt;br /&gt;
&lt;br /&gt;
==== Обновление данных UPDATE ====&lt;br /&gt;
&lt;br /&gt;
Чтобы обновить данные, нужно указать, какие параметры вы хотите обновить и условия выборки обновляемых данных:&lt;br /&gt;
&lt;br /&gt;
 update cast_info set person_id=1732058 where movie_id=3514559;&lt;br /&gt;
&lt;br /&gt;
Если вы не укажите условия, то обновятся значения во всей таблице, обычно это не нужно.&lt;br /&gt;
&lt;br /&gt;
В запросе на обновление также можно использовать подзапросы. Единственное ограничение: нельзя в подзапросе использовать обновляемую таблицу, так как СУБД в этом случае можно ввести в бесконечный цикл обновления. Пример более понятного запроса на обновление:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Предостережение&#039;&#039;&#039;: не выполняйте следующий запрос, пока не разберетесь, что именно он делает.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
 update cast_info set person_id=(select id from name where name=&#039;Savin Ivan&#039;) &lt;br /&gt;
 where movie_id=(select id from title where title like &#039;The Matrix&#039; and production_year=1999);&lt;br /&gt;
&lt;br /&gt;
Если вы не закоммитите изменения, то обновляемые записи останутся залоченными, то есть их невозможно будет обновить в других сессиях. Попробуйте не выполняя коммит, открыть новую сессию и попытаться обновить те же данные. В результате новая сессия зависнет, ожидая завершения транзакции в первой сессии. Закоммитьте изменения в первой сессии.&lt;br /&gt;
&lt;br /&gt;
Попробуйте назначить себя и своих друзей на подходящие роли в ваших любимых фильмах. Составьте запрос, который будет демонстрировать, кто где и какую роль играет (используя подзапросы).&lt;br /&gt;
&lt;br /&gt;
==== Удаление данных DELETE ====&lt;br /&gt;
&lt;br /&gt;
Синтаксис удаления данных аналогичен синтаксису выборки за исключением того, что вместо &amp;quot;SELECT * FROM&amp;quot; достаточно написать &amp;quot;DELETE FROM&amp;quot;. Будьте внимательны, удаляя данные и проверяйте условия перед отправкой коммита.&lt;br /&gt;
&lt;br /&gt;
Удалите актеров, которые вам не нравятся (или актера, выбранного случайно). Это сделать не так просто, как может показаться, потому что их идентификаторы используются в других таблицах, а нарушать целостность данных нельзя. Для корректного удаления, нужно найти все связи актера с фильмами и удалить сначала их, после этого удалить информацию о них из таблицы фактов, после этого станет доступно удаление.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 5: Агрегация данных ===&lt;br /&gt;
&lt;br /&gt;
Часто с помощью СУБД генерируют различные полезные отчеты. В любой популярной СУБД есть агрегирующие функции, с помощью которых, можно собрать статистику о данных. Самая простая статистика: количество записей, удовлетворяющих заданным условиям. Пример выбора количества фильмов в базе:&lt;br /&gt;
&lt;br /&gt;
 select count(1) from title where kind_id=(select id from kind_type where kind=&#039;movie&#039;);&lt;br /&gt;
&lt;br /&gt;
Для числовых атрибутов также помимо COUNT можно использовать SUM, AVG и другие востребованные функции.&lt;br /&gt;
&lt;br /&gt;
Попробуйте вывести, в скольких фильмах снимались ваши любимые актеры.&lt;br /&gt;
&lt;br /&gt;
==== Преобразование атрибутов по некоторым правилам ====&lt;br /&gt;
&lt;br /&gt;
Если нужно преобразовать какой-либо атрибут по правилам (условиям), то можно использоваться конструкцию CASE ... WHEN ... THEN ... END.&lt;br /&gt;
В этом случае данная конструкция будет обозначать новый атрибут у записи. Рассмотрим её детальнее.&lt;br /&gt;
&lt;br /&gt;
 case &lt;br /&gt;
     when &#039;&#039;&#039;&#039;&#039;condition1&#039;&#039;&#039;&#039;&#039; then &#039;&#039;&#039;&#039;&#039;result1&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     when &#039;&#039;&#039;&#039;&#039;condition2&#039;&#039;&#039;&#039;&#039; then &#039;&#039;&#039;&#039;&#039;result2&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
     else &#039;&#039;&#039;&#039;&#039;result3&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
 end&lt;br /&gt;
&lt;br /&gt;
Если условие &#039;&#039;&#039;&#039;&#039;condition1&#039;&#039;&#039;&#039;&#039; верно (т.е. &#039;&#039;&#039;true&#039;&#039;&#039;), то атрибуту будет&lt;br /&gt;
присвоено значение &#039;&#039;&#039;&#039;&#039;result1&#039;&#039;&#039;&#039;&#039;. Если &#039;&#039;&#039;&#039;&#039;condition1&#039;&#039;&#039;&#039;&#039; неверно, то &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt; перейдёт&lt;br /&gt;
к следующему &amp;lt;code&amp;gt;when&amp;lt;/code&amp;gt;. Если ни один из &#039;&#039;&#039;&#039;&#039;condition&#039;&#039;&#039;&#039;&#039; не выполняется, то атрибуту будет &lt;br /&gt;
присвоено значение, указанное в &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt; (если в этом случае отсутствует &amp;lt;code&amp;gt;else&amp;lt;/code&amp;gt;, то&lt;br /&gt;
атрибут будет равен &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Представим таблицу &amp;lt;code&amp;gt;T&amp;lt;/code&amp;gt;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! a&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Добавим теперь к каждой записи новый атрибут, который будет обозначать значение атрибута &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; словами:&lt;br /&gt;
 select&lt;br /&gt;
    a,&lt;br /&gt;
    case&lt;br /&gt;
        when a = 1 then &#039;one&#039;&lt;br /&gt;
        when a = 2 then &#039;two&#039;&lt;br /&gt;
        when a = 3 then &#039;three&#039;&lt;br /&gt;
        else &#039;other&#039;&lt;br /&gt;
    end&lt;br /&gt;
 from t;&lt;br /&gt;
&lt;br /&gt;
Результат:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! a&lt;br /&gt;
! case&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| one&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| two&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| three&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| other&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Как видно из результата, новый атрибут получил название &amp;lt;code&amp;gt;case&amp;lt;/code&amp;gt;. Если мы хотим переименовать его в &lt;br /&gt;
желаемый вариант, то это можно сделать с помощью &amp;lt;code&amp;gt;as&amp;lt;/code&amp;gt;:&lt;br /&gt;
 select&lt;br /&gt;
    a,&lt;br /&gt;
    case&lt;br /&gt;
        when a = 1 then &#039;one&#039;&lt;br /&gt;
        when a = 2 then &#039;two&#039;&lt;br /&gt;
        when a = 3 then &#039;three&#039;&lt;br /&gt;
        else &#039;other&#039;&lt;br /&gt;
    end as new_attribute&lt;br /&gt;
 from t;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! a&lt;br /&gt;
! new_attribute&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| one&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| two&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| three&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| other&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Также, чтобы каждый раз не писать &amp;lt;code&amp;gt;when a = &amp;lt;/code&amp;gt;, можно сразу указать, по какому атрибуту мы бежим:&lt;br /&gt;
 select&lt;br /&gt;
    a,&lt;br /&gt;
    case a&lt;br /&gt;
        when 1 then &#039;one&#039;&lt;br /&gt;
        when 2 then &#039;two&#039;&lt;br /&gt;
        when 3 then &#039;three&#039;&lt;br /&gt;
        else &#039;other&#039;&lt;br /&gt;
    end as new_attribute&lt;br /&gt;
 from t;&lt;br /&gt;
&lt;br /&gt;
Таким образом, используя &amp;lt;code&amp;gt;case..when..&amp;lt;/code&amp;gt; можно помечать нужные нам записи для дальнейшей обработки данных. &lt;br /&gt;
Например, добавить к фильму атрибут, обозначающий, относится фильм к 20 или 21 веку.&lt;br /&gt;
&lt;br /&gt;
 select&lt;br /&gt;
   *, &lt;br /&gt;
   case&lt;br /&gt;
     when production_year &amp;gt;= 1900 and production_year &amp;lt; 2000 then &#039;XX&#039;&lt;br /&gt;
     when production_year &amp;gt;= 2000 and production_year &amp;lt; 2100 then &#039;XXI&#039;&lt;br /&gt;
   end as century&lt;br /&gt;
 from title&lt;br /&gt;
&lt;br /&gt;
Сокращённый результат:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| id&lt;br /&gt;
| 2395294&lt;br /&gt;
|-&lt;br /&gt;
| title&lt;br /&gt;
| (1979-03-11)&lt;br /&gt;
|-&lt;br /&gt;
| production_year&lt;br /&gt;
| 1979&lt;br /&gt;
|-&lt;br /&gt;
| century&lt;br /&gt;
| XX&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Группировка агрегированных данных GROUP BY ====&lt;br /&gt;
&lt;br /&gt;
Статистику можно также сгруппировать по некоторому атрибуту, который возвращается запросом. Например, чтобы вывести количества фильмов, выпущенных в каждый год, выполните запрос:&lt;br /&gt;
&lt;br /&gt;
 select production_year, count(1) from title&lt;br /&gt;
 where kind_id=(select id from kind_type where kind=&#039;movie&#039;)&lt;br /&gt;
 group by production_year&lt;br /&gt;
 order by production_year;&lt;br /&gt;
&lt;br /&gt;
В запросе также результаты отсортированы по году выпуска с помощью ORDER BY.&lt;br /&gt;
&lt;br /&gt;
Попробуйте собрать следующие статистики: количество актеров и актрис; среднее количество фильмов в год, выпущенных в XX веке, и, выпущенных в XXI веке (с учетом текущего года). &lt;br /&gt;
&lt;br /&gt;
Попробуйте также узнать среднее количество ролей в фильмах в различные годы. Этот запрос может выполняться долго, поэтому рекомендуется сначала отлаживать его на небольшом количестве данных, используя LIMIT или какие-либо условия.&lt;br /&gt;
&lt;br /&gt;
=== Защита лабораторной работы ===&lt;br /&gt;
# Показать логи выполнения запросов. &lt;br /&gt;
# Прокомментировать для агрегаций, что и как происходит. &lt;br /&gt;
# Написать запрос по просьбе преподавателя.&lt;br /&gt;
&lt;br /&gt;
=== Полезные материалы ===&lt;br /&gt;
&lt;br /&gt;
Интерактивный урок по основам SQL запросов (видео лекции + задания): https://www.codeschool.com/courses/try-sql&lt;/div&gt;</summary>
		<author><name>Luc1ph3r</name></author>
	</entry>
	<entry>
		<id>https://wiki.cs.hse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_2&amp;diff=19298</id>
		<title>Базы данных/Лабораторная работа 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.cs.hse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_2&amp;diff=19298"/>
		<updated>2016-04-22T18:39:59Z</updated>

		<summary type="html">&lt;p&gt;Luc1ph3r: /* Декартово произведение */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Задачи: освоить операции реляционной алгебры, оконные функции. Сохранение запросов в виде представлений. Фактически после этой работы вы сможете составить запрос любой сложности и создать удобное представление результатов.&lt;br /&gt;
&lt;br /&gt;
== Алиасы таблиц и выбираемых полей ==&lt;br /&gt;
&lt;br /&gt;
Для удобства составления запросов можно присваивать таблицам или выборкам алиасы. Это удобно в случае, если в запросе участвует несколько таблиц и вы хотите обратиться к конкретной.&lt;br /&gt;
&lt;br /&gt;
 select (select title from title t where t.id=ci.movie_id) from cast_info ci;&lt;br /&gt;
&lt;br /&gt;
Также можно присваивать алиасы значениям выбираемых полей. Это, например, удобно для последующей работы с этими полями:&lt;br /&gt;
&lt;br /&gt;
 select * from &lt;br /&gt;
 (select production_year, count(1) as cnt from title group by production_year) t&lt;br /&gt;
 where t.cnt &amp;gt; 50000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Работа с реляционной алгеброй ==&lt;br /&gt;
&lt;br /&gt;
В предыдущей лабораторной работе вы работали как правило с одной таблицей, выполняя операции селекции (добавляя условия в WHERE) и проекцией (перечисляя, что именно вы хотите выбрать между SELECT и FROM, в том числе, выполняя подзапросы к другим базам). Основные механизмы, которые дают большое преимущество реляционным СУБД относятся к взаимодействию нескольких отношений или результатов выборок. Эта лабораторная работа завершает введение и исчерпывает тему DML.&lt;br /&gt;
&lt;br /&gt;
=== Объединения ===&lt;br /&gt;
&lt;br /&gt;
Объединять множества в реляционных базах данных можно двумя способами: вертикально и горизонтально. Горизонтальные объединения используются намного чаще, так как реляционные базы нормализованы и нужные вам атрибуты могут быть раскиданы по разным сущностям. Посмотрите, как это выглядит в базе IMDb:&lt;br /&gt;
&lt;br /&gt;
http://i.imgur.com/pDq0n.png&lt;br /&gt;
&lt;br /&gt;
Используя связи между сущностями, вы можете горизонтально объединять таблицы и таким образом расширять результаты вышей выборки. Операции горизонтального соединения таблиц представлены в языках стандарта SQL ключевым словом JOIN. Рассмотрим варианты использования горизонтальных объединений.&lt;br /&gt;
&lt;br /&gt;
Исчерпывающее руководство для визуалов:&lt;br /&gt;
&lt;br /&gt;
https://lh3.googleusercontent.com/-7yCwOQ8wjL0/VBPfTmSuq0I/AAAAAAAAF0Q/1LS_wD5cJPY/w1024-h724/LEFT%2Bvs%2BRight%2BOuter%2BJoin%2Bin%2BSQL.png&lt;br /&gt;
&lt;br /&gt;
Но если вы любите копировать команды из методички и смотреть, что получается, читайте дальше:)&lt;br /&gt;
&lt;br /&gt;
=== Введение в JOIN ===&lt;br /&gt;
&lt;br /&gt;
Присоединение обычно происходит по некоторым атрибутам, которые называются первичными и внешними ключами. Первичный ключ обычно называется id, он содержится во всех таблицах, которые претендуют на участие в верно построенной реляционной базе. Также таблицы могут содержать внешние ключи - это атрибуты, как правило типа unsigned integer, которые содержат те же значения, что и первичные ключи соответствующих сущностей. &lt;br /&gt;
&lt;br /&gt;
Например, теперь, если вы хотите получить отчет, в котором будут следующие поля: имя актера, имя персонажа, фильм, год выпуска фильма, то вам нужно присоединить к таблице cast_info таблицы, где содержатся названия фильмов, имена актеров и имена персонажей, а именно: char_name, title и name, которые нужно присоединить по их первичным ключам.&lt;br /&gt;
&lt;br /&gt;
Синтаксис команды join:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM t1&lt;br /&gt;
 JOIN t2 ON t1.id=t2.t1_id&lt;br /&gt;
&lt;br /&gt;
В условии соединения ON можно указывать множество условий используя скобки и AND/OR.&lt;br /&gt;
&lt;br /&gt;
Альтернативный способ выборки из нескольких таблиц:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM t1, t2 &lt;br /&gt;
 WHERE t1.id=t2.t1_id&lt;br /&gt;
&lt;br /&gt;
В результате запросов вы получите все сопоставленные записи и атрибуты из обеих таблиц.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Внутреннее объединение INNER JOIN ====&lt;br /&gt;
&lt;br /&gt;
Обычный JOIN сопоставляет кортежи соединяемых сущностей по указаному в ON правилу. Если какое-либо из значений по которому соединяется сущность не задано (NULL), то кортеж не попадет в результирующую выборку.&lt;br /&gt;
&lt;br /&gt;
Пример человекопонятной выборки, кто где снимался:&lt;br /&gt;
&lt;br /&gt;
 select t.title, n.name, c.name from cast_info ca&lt;br /&gt;
 join title t on t.id=ca.movie_id&lt;br /&gt;
 join name n on n.id=ca.person_id&lt;br /&gt;
 join char_name c on c.id=ca.person_role_id&lt;br /&gt;
 where t.kind_id=1&lt;br /&gt;
 limit 10;&lt;br /&gt;
&lt;br /&gt;
Лимит указан для быстрой демонтсрации запроса.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задания:&#039;&#039;&#039;&lt;br /&gt;
* Сделайте следующий отчет: название компании, выпускающей кинофильмы; название фильма; факты о фильме - для какой-либо выбранной вами кинокомпании (выберите более менее активную) за период в 5 последних лет. Диапазон дат укажите не конкретными датами, а относительно сегодняшнего дня, поищите соответствующие функции работы с временем.&lt;br /&gt;
* Соберите статистику по количеству фильмов выпускаемых разными странами (ищите страну в movie_info) и количество фильмов, для которых не указана страна.&lt;br /&gt;
&lt;br /&gt;
==== Объединения слева и справа LEFT JOIN, RIGHT JOIN ====&lt;br /&gt;
&lt;br /&gt;
В случае, если вы хотите обязательно выбрать все кортежи из первой таблицы, даже если нет соответствующих картежей во второй, используйте LEFT JOIN. Если соответствующих записей не будет, то атрибуты второй таблицы будут указаны как NULL.&lt;br /&gt;
&lt;br /&gt;
Выбрать ключевые слова с названиями фильмов, но так чтобы все фильмы попали в выборку.&lt;br /&gt;
&lt;br /&gt;
 select t.title, k.keyword from title t &lt;br /&gt;
 left join movie_keyword mk on mk.movie_id=t.id &lt;br /&gt;
 left join keyword k on k.id=mk.keyword_id &lt;br /&gt;
 where mk.id is null &lt;br /&gt;
 limit 100;&lt;br /&gt;
&lt;br /&gt;
Лимит указан для быстрой демонтсрации запроса.&lt;br /&gt;
&lt;br /&gt;
RIGHT JOIN соответственно оставляет все значения в присоединяемой таблице, а для кортежей, для которых не удалось сопоставить кортежи из первой таблицы, прописывает NULL.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задания:&#039;&#039;&#039;&lt;br /&gt;
# Найдите фильмы, в которых нет персонажей.&lt;br /&gt;
# Найдите актеров, которые никогда не снимались в фильмах. (двумя способами: с помощью JOIN и с помощью WHERE NOT EXIST)&lt;br /&gt;
&lt;br /&gt;
==== Полное объединение FULL JOIN ====&lt;br /&gt;
&lt;br /&gt;
Работает аналогично LEFT и RIGHT JOIN: в случае, если какому-то кортежу из первой или второй таблице не удалось найти пару, то вместо соответствующих значений прописывается NULL.&lt;br /&gt;
&lt;br /&gt;
Пока никаких идей для полезного запроса, full join нужен обычно для того, чтобы обнаруживать нарушения целостности. Попробуйте узнать, есть ли в cast_info записи с невалидными идентификаторами актеров, фильмов или ролей и фильмы и роли, для которых нет записей в cast_info. Или проверьте, что в таблице фактов об актерах нет невалидных идентификаторов (ссылки на несуществующих актеров). Если вы корректно удалили актера в первой лабораторной работе или просто ничего не делали, то таких записей не должно быть.&lt;br /&gt;
&lt;br /&gt;
==== Декартово произведение ====&lt;br /&gt;
&lt;br /&gt;
Как было ранее показано, существует альтернативный способ выборки из нескольких таблиц:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM t1, t2 WHERE t1.id=t2.t1_id&lt;br /&gt;
&lt;br /&gt;
Если не указывать условий, то таблицы перемножатся: то есть в результате вы получите выборку, в которой каждая запись из одной таблицы сопоставляется с каждой записью из другой таблицы.&lt;br /&gt;
&lt;br /&gt;
Посчитайте, сколько всего различных комбинаций актеров и персонажей может быть исходя из базы. В этой выборке следует также учесть, что персонаж может появляться в разных фильмах, но называться одинаково, при этом просто умножив cast_info на что-то не получится. Выбирайте сразу количество, не выводя результаты выборки.&lt;br /&gt;
&lt;br /&gt;
=== Операции над множествами ===&lt;br /&gt;
&lt;br /&gt;
Вертикальные объединения обычно используют для манипуляции с готовыми запросами. Для того, чтобы объединить две выборки, нужно, чтобы у них совпадали имена атрибутов.&lt;br /&gt;
&lt;br /&gt;
Синтаксис:&lt;br /&gt;
&lt;br /&gt;
 select * from t1&lt;br /&gt;
 union&lt;br /&gt;
 select * from t2&lt;br /&gt;
&lt;br /&gt;
==== Объединение UNION ====&lt;br /&gt;
&lt;br /&gt;
Объединяет кортежи выборок, при этом убирает дубли.&lt;br /&gt;
&lt;br /&gt;
==== Полное объединение UNION ALL ====&lt;br /&gt;
&lt;br /&gt;
Объединяет кортежи выборок, при этом не убирает дубли.&lt;br /&gt;
&lt;br /&gt;
==== Пересечение INTERSECT ====&lt;br /&gt;
&lt;br /&gt;
Возвращает кортежи, которые есть в обоих отношениях.&lt;br /&gt;
&lt;br /&gt;
==== Вычитание EXCEPT ====&lt;br /&gt;
&lt;br /&gt;
Возвращает кортежи, которые есть в первом, но нет во втором отношениях.&lt;br /&gt;
&lt;br /&gt;
== Оконные функции ==&lt;br /&gt;
&lt;br /&gt;
Оконные функции - это наиболее мощный инструмент, заложенный в стандарте SQL. Применение оконных функций к месту обычно помогает существенно упростить запросы.&lt;br /&gt;
&lt;br /&gt;
Оконные функции позволяют выполнять подзапросы и собирать статистику для каждого результирующего кортежа по некоторому окну данных. Обычно окном данных выступают кортежи сгруппированные по значению какого-либо атрибута.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим небольшой сэмпл данных через представление (см. ниже), чтобы упростить демонстрационные запросы:&lt;br /&gt;
&lt;br /&gt;
 create view movie_contries as (&lt;br /&gt;
  select info as country, movie_id, title, t.production_year &lt;br /&gt;
  from movie_info mi &lt;br /&gt;
  join title t on mi.movie_id=t.id and mi.info_type_id=8 and t.kind_id=1&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Фильмы с указанием страны и года выпуска:&lt;br /&gt;
 select * from movie_contries;&lt;br /&gt;
&lt;br /&gt;
При этом каждый фильм может упоминаться несколько раз, если в производстве участвовало несколько стран.&lt;br /&gt;
&lt;br /&gt;
Данный запрос позволяет узнать, в каком году страны выпустили свой первый фильм:&lt;br /&gt;
&lt;br /&gt;
 select distinct(country), min(production_year) over (partition by country) from movie_contries;&lt;br /&gt;
&lt;br /&gt;
* partition by country - означает, что выборка будет прохоидть для каждой группы с одинаковым значением country&lt;br /&gt;
* min(production_year) - для каждой из групп, которые определены далее, выбрать минимальное значение&lt;br /&gt;
* distinct(country) - так как over не производит группировку сам и вычисляет результат окна для каждой строки исходного отношения, то добавим distinct, чтобы вернуть только уникальные значения для country и соответствующие значения результатов выборки по окну.&lt;br /&gt;
&lt;br /&gt;
Дополнительно:&lt;br /&gt;
* https://habrahabr.ru/post/268983/&lt;br /&gt;
* http://www.postgresql.org/docs/9.3/static/tutorial-window.html&lt;br /&gt;
&lt;br /&gt;
== Создание представлений CREATE VIEW ==&lt;br /&gt;
&lt;br /&gt;
Запросы можно сохранять в виде представлений, чтобы затем обращаться к ним как к таблицам. &lt;br /&gt;
&lt;br /&gt;
 create view female_actors as&lt;br /&gt;
 select * from name where gender=&#039;f&#039;&lt;br /&gt;
&lt;br /&gt;
После этого вы сможете выбирать из представлений как из таблиц:&lt;br /&gt;
&lt;br /&gt;
 select count(1) from female_actors;&lt;br /&gt;
&lt;br /&gt;
Представления поддерживают целостность базы данных, и, если обновятся данные в таблице, из которой строится представление, то обновятся данные и в представлении. &lt;br /&gt;
&lt;br /&gt;
Можно обновлять данные через представления. При этом значения обновятся в соответствующих таблицах. Ограничением в данном случае являются представления, составленные из запросов с использованием функций агрегации. Так как результаты таких представлений не хранят исходные данные, через них невозможно найти кортежи, которые нужно обновить.&lt;br /&gt;
&lt;br /&gt;
Дополнительно о синтаксисе:&lt;br /&gt;
&lt;br /&gt;
* http://www.postgresql.org/docs/9.3/static/sql-createview.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задание:&#039;&#039;&#039;&lt;br /&gt;
Создайте представление, которое будет показывать проблемы с объектами в базе. Это будет несколько выборок с полями: имя сущности (фильм, актер, компания, персонаж), идентификатор объекта в его таблице, текстовое название объекта, комментарий с описанием проблемы. Эти выборки должны быть объединены с помощью UNION. Выборки следующего содержания:&lt;br /&gt;
* Фильмы без актеров (именно фильмы, см. kind_type)&lt;br /&gt;
* Актеры, которые нигде не снимались&lt;br /&gt;
* Компании, которые не выпустили ни одного фильма.&lt;br /&gt;
* Персонажи, не участвовавшие ни в одном фильме.&lt;br /&gt;
&lt;br /&gt;
После создания представления, намеренно испортите некоторые кортежи в таблицах, чтобы выборки возвращали новые значения. Убедитесь, что ваши изменения попадают в результаты выборки из представления.&lt;br /&gt;
&lt;br /&gt;
== Комплексные выборки ==&lt;br /&gt;
&lt;br /&gt;
Для защиты выполните любые две выборки. Для выполнения этих заданий используйте всё, что знаете.&lt;br /&gt;
&lt;br /&gt;
# Выберите 5 своих любимых (или случайных) сериалов, поля: название сериала, количество эпизодов, среднее количество персонажей в каждом эпизоде, название эпизода с наибольшим количеством актеров, количество актеров в этом эпизоде.&lt;br /&gt;
# Выберите фильмы, в ключевых словах которых есть &#039;math&#039; и выберите для них: название фильма, суммарные кассовые сборы, количество человек, участвовавших над созданием фильма, средний доход с фильма на человека: чистая прибыль (сборы минус бюджет) поделенная на количество людей.&lt;br /&gt;
# Выберите топ 10 фильмов, над созданием которых потрудилось больше всего людей (таблица complete_cast), поля: название фильма, количество всех, кто участвовал в создании, количество актеров&lt;br /&gt;
# Выберите топ 10 актеров, которые снялись в наибольшем количестве фильмов, поля: имя актера, дата рождения, количество фактов, количество фильмов, в которых он снялся, кинокомпания, с которой актер сотрудника над наибольшим количеством фильмов.&lt;br /&gt;
# Выберите топ 10 кинорежиссеров, которые сняли фильмы с наибольшим количеством задействованных людей, поля: название фильма, среднее количество людей, которые принимают участие в фильме режиссера, дата рождения режиссера, количество фактов о режиссере.&lt;br /&gt;
&lt;br /&gt;
== Защита лабораторной ==&lt;br /&gt;
# Объяснить, как работают составленные запросы.&lt;br /&gt;
# По просьбе преподавателя модифицировать написанный ранее запрос.&lt;br /&gt;
&lt;br /&gt;
Рекомендуется сохранить все запросы, так как в последующих лабораторных работах они понадобятся.&lt;br /&gt;
&lt;br /&gt;
== Полезные материалы ==&lt;br /&gt;
Интерактивные уроки по SQL (уроки строятся на работе с СУБД SQLite, поэтому некоторые функции не будут работать в PostgreSQL, но обычные запросы объясняются хорошо):&lt;br /&gt;
# Learn SQL: https://www.codecademy.com/learn/learn-sql&lt;br /&gt;
# Table Transformation: https://www.codecademy.com/learn/sql-table-transformation&lt;/div&gt;</summary>
		<author><name>Luc1ph3r</name></author>
	</entry>
	<entry>
		<id>https://wiki.cs.hse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_2&amp;diff=19297</id>
		<title>Базы данных/Лабораторная работа 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.cs.hse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_2&amp;diff=19297"/>
		<updated>2016-04-22T18:05:25Z</updated>

		<summary type="html">&lt;p&gt;Luc1ph3r: Исправил отображение кода (добавил в рамку)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Задачи: освоить операции реляционной алгебры, оконные функции. Сохранение запросов в виде представлений. Фактически после этой работы вы сможете составить запрос любой сложности и создать удобное представление результатов.&lt;br /&gt;
&lt;br /&gt;
== Алиасы таблиц и выбираемых полей ==&lt;br /&gt;
&lt;br /&gt;
Для удобства составления запросов можно присваивать таблицам или выборкам алиасы. Это удобно в случае, если в запросе участвует несколько таблиц и вы хотите обратиться к конкретной.&lt;br /&gt;
&lt;br /&gt;
 select (select title from title t where t.id=ci.movie_id) from cast_info ci;&lt;br /&gt;
&lt;br /&gt;
Также можно присваивать алиасы значениям выбираемых полей. Это, например, удобно для последующей работы с этими полями:&lt;br /&gt;
&lt;br /&gt;
 select * from &lt;br /&gt;
 (select production_year, count(1) as cnt from title group by production_year) t&lt;br /&gt;
 where t.cnt &amp;gt; 50000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Работа с реляционной алгеброй ==&lt;br /&gt;
&lt;br /&gt;
В предыдущей лабораторной работе вы работали как правило с одной таблицей, выполняя операции селекции (добавляя условия в WHERE) и проекцией (перечисляя, что именно вы хотите выбрать между SELECT и FROM, в том числе, выполняя подзапросы к другим базам). Основные механизмы, которые дают большое преимущество реляционным СУБД относятся к взаимодействию нескольких отношений или результатов выборок. Эта лабораторная работа завершает введение и исчерпывает тему DML.&lt;br /&gt;
&lt;br /&gt;
=== Объединения ===&lt;br /&gt;
&lt;br /&gt;
Объединять множества в реляционных базах данных можно двумя способами: вертикально и горизонтально. Горизонтальные объединения используются намного чаще, так как реляционные базы нормализованы и нужные вам атрибуты могут быть раскиданы по разным сущностям. Посмотрите, как это выглядит в базе IMDb:&lt;br /&gt;
&lt;br /&gt;
http://i.imgur.com/pDq0n.png&lt;br /&gt;
&lt;br /&gt;
Используя связи между сущностями, вы можете горизонтально объединять таблицы и таким образом расширять результаты вышей выборки. Операции горизонтального соединения таблиц представлены в языках стандарта SQL ключевым словом JOIN. Рассмотрим варианты использования горизонтальных объединений.&lt;br /&gt;
&lt;br /&gt;
Исчерпывающее руководство для визуалов:&lt;br /&gt;
&lt;br /&gt;
https://lh3.googleusercontent.com/-7yCwOQ8wjL0/VBPfTmSuq0I/AAAAAAAAF0Q/1LS_wD5cJPY/w1024-h724/LEFT%2Bvs%2BRight%2BOuter%2BJoin%2Bin%2BSQL.png&lt;br /&gt;
&lt;br /&gt;
Но если вы любите копировать команды из методички и смотреть, что получается, читайте дальше:)&lt;br /&gt;
&lt;br /&gt;
=== Введение в JOIN ===&lt;br /&gt;
&lt;br /&gt;
Присоединение обычно происходит по некоторым атрибутам, которые называются первичными и внешними ключами. Первичный ключ обычно называется id, он содержится во всех таблицах, которые претендуют на участие в верно построенной реляционной базе. Также таблицы могут содержать внешние ключи - это атрибуты, как правило типа unsigned integer, которые содержат те же значения, что и первичные ключи соответствующих сущностей. &lt;br /&gt;
&lt;br /&gt;
Например, теперь, если вы хотите получить отчет, в котором будут следующие поля: имя актера, имя персонажа, фильм, год выпуска фильма, то вам нужно присоединить к таблице cast_info таблицы, где содержатся названия фильмов, имена актеров и имена персонажей, а именно: char_name, title и name, которые нужно присоединить по их первичным ключам.&lt;br /&gt;
&lt;br /&gt;
Синтаксис команды join:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM t1&lt;br /&gt;
 JOIN t2 ON t1.id=t2.t1_id&lt;br /&gt;
&lt;br /&gt;
В условии соединения ON можно указывать множество условий используя скобки и AND/OR.&lt;br /&gt;
&lt;br /&gt;
Альтернативный способ выборки из нескольких таблиц:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM t1, t2 &lt;br /&gt;
 WHERE t1.id=t2.t1_id&lt;br /&gt;
&lt;br /&gt;
В результате запросов вы получите все сопоставленные записи и атрибуты из обеих таблиц.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Внутреннее объединение INNER JOIN ====&lt;br /&gt;
&lt;br /&gt;
Обычный JOIN сопоставляет кортежи соединяемых сущностей по указаному в ON правилу. Если какое-либо из значений по которому соединяется сущность не задано (NULL), то кортеж не попадет в результирующую выборку.&lt;br /&gt;
&lt;br /&gt;
Пример человекопонятной выборки, кто где снимался:&lt;br /&gt;
&lt;br /&gt;
 select t.title, n.name, c.name from cast_info ca&lt;br /&gt;
 join title t on t.id=ca.movie_id&lt;br /&gt;
 join name n on n.id=ca.person_id&lt;br /&gt;
 join char_name c on c.id=ca.person_role_id&lt;br /&gt;
 where t.kind_id=1&lt;br /&gt;
 limit 10;&lt;br /&gt;
&lt;br /&gt;
Лимит указан для быстрой демонтсрации запроса.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задания:&#039;&#039;&#039;&lt;br /&gt;
* Сделайте следующий отчет: название компании, выпускающей кинофильмы; название фильма; факты о фильме - для какой-либо выбранной вами кинокомпании (выберите более менее активную) за период в 5 последних лет. Диапазон дат укажите не конкретными датами, а относительно сегодняшнего дня, поищите соответствующие функции работы с временем.&lt;br /&gt;
* Соберите статистику по количеству фильмов выпускаемых разными странами (ищите страну в movie_info) и количество фильмов, для которых не указана страна.&lt;br /&gt;
&lt;br /&gt;
==== Объединения слева и справа LEFT JOIN, RIGHT JOIN ====&lt;br /&gt;
&lt;br /&gt;
В случае, если вы хотите обязательно выбрать все кортежи из первой таблицы, даже если нет соответствующих картежей во второй, используйте LEFT JOIN. Если соответствующих записей не будет, то атрибуты второй таблицы будут указаны как NULL.&lt;br /&gt;
&lt;br /&gt;
Выбрать ключевые слова с названиями фильмов, но так чтобы все фильмы попали в выборку.&lt;br /&gt;
&lt;br /&gt;
 select t.title, k.keyword from title t &lt;br /&gt;
 left join movie_keyword mk on mk.movie_id=t.id &lt;br /&gt;
 left join keyword k on k.id=mk.keyword_id &lt;br /&gt;
 where mk.id is null &lt;br /&gt;
 limit 100;&lt;br /&gt;
&lt;br /&gt;
Лимит указан для быстрой демонтсрации запроса.&lt;br /&gt;
&lt;br /&gt;
RIGHT JOIN соответственно оставляет все значения в присоединяемой таблице, а для кортежей, для которых не удалось сопоставить кортежи из первой таблицы, прописывает NULL.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задания:&#039;&#039;&#039;&lt;br /&gt;
# Найдите фильмы, в которых нет персонажей.&lt;br /&gt;
# Найдите актеров, которые никогда не снимались в фильмах. (двумя способами: с помощью JOIN и с помощью WHERE NOT EXIST)&lt;br /&gt;
&lt;br /&gt;
==== Полное объединение FULL JOIN ====&lt;br /&gt;
&lt;br /&gt;
Работает аналогично LEFT и RIGHT JOIN: в случае, если какому-то кортежу из первой или второй таблице не удалось найти пару, то вместо соответствующих значений прописывается NULL.&lt;br /&gt;
&lt;br /&gt;
Пока никаких идей для полезного запроса, full join нужен обычно для того, чтобы обнаруживать нарушения целостности. Попробуйте узнать, есть ли в cast_info записи с невалидными идентификаторами актеров, фильмов или ролей и фильмы и роли, для которых нет записей в cast_info. Или проверьте, что в таблице фактов об актерах нет невалидных идентификаторов (ссылки на несуществующих актеров). Если вы корректно удалили актера в первой лабораторной работе или просто ничего не делали, то таких записей не должно быть.&lt;br /&gt;
&lt;br /&gt;
==== Декартово произведение ====&lt;br /&gt;
&lt;br /&gt;
Как выбло ранее показано, существует альтернативный способ выборки из нескольких таблиц:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM t1, t2 WHERE t1.id=t2.t1_id&lt;br /&gt;
&lt;br /&gt;
Если не указывать условий, то таблицы перемножатся: то есть в результате вы получите выборку, в которой каждая запись из одной таблицы сопоставляется с каждой записью из другой таблицы.&lt;br /&gt;
&lt;br /&gt;
Посчитайте, сколько всего различных комбинаций актеров и персонажей может быть исходя из базы. В этой выборке следует также учесть, что персонаж может появляться в разных фильмах, но называться одинаково, при этом просто умножив cast_info на что-то не получится. Выбирайте сразу количество, не выводя результаты выборки.&lt;br /&gt;
&lt;br /&gt;
=== Операции над множествами ===&lt;br /&gt;
&lt;br /&gt;
Вертикальные объединения обычно используют для манипуляции с готовыми запросами. Для того, чтобы объединить две выборки, нужно, чтобы у них совпадали имена атрибутов.&lt;br /&gt;
&lt;br /&gt;
Синтаксис:&lt;br /&gt;
&lt;br /&gt;
 select * from t1&lt;br /&gt;
 union&lt;br /&gt;
 select * from t2&lt;br /&gt;
&lt;br /&gt;
==== Объединение UNION ====&lt;br /&gt;
&lt;br /&gt;
Объединяет кортежи выборок, при этом убирает дубли.&lt;br /&gt;
&lt;br /&gt;
==== Полное объединение UNION ALL ====&lt;br /&gt;
&lt;br /&gt;
Объединяет кортежи выборок, при этом не убирает дубли.&lt;br /&gt;
&lt;br /&gt;
==== Пересечение INTERSECT ====&lt;br /&gt;
&lt;br /&gt;
Возвращает кортежи, которые есть в обоих отношениях.&lt;br /&gt;
&lt;br /&gt;
==== Вычитание EXCEPT ====&lt;br /&gt;
&lt;br /&gt;
Возвращает кортежи, которые есть в первом, но нет во втором отношениях.&lt;br /&gt;
&lt;br /&gt;
== Оконные функции ==&lt;br /&gt;
&lt;br /&gt;
Оконные функции - это наиболее мощный инструмент, заложенный в стандарте SQL. Применение оконных функций к месту обычно помогает существенно упростить запросы.&lt;br /&gt;
&lt;br /&gt;
Оконные функции позволяют выполнять подзапросы и собирать статистику для каждого результирующего кортежа по некоторому окну данных. Обычно окном данных выступают кортежи сгруппированные по значению какого-либо атрибута.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим небольшой сэмпл данных через представление (см. ниже), чтобы упростить демонстрационные запросы:&lt;br /&gt;
&lt;br /&gt;
 create view movie_contries as (&lt;br /&gt;
  select info as country, movie_id, title, t.production_year &lt;br /&gt;
  from movie_info mi &lt;br /&gt;
  join title t on mi.movie_id=t.id and mi.info_type_id=8 and t.kind_id=1&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Фильмы с указанием страны и года выпуска:&lt;br /&gt;
 select * from movie_contries;&lt;br /&gt;
&lt;br /&gt;
При этом каждый фильм может упоминаться несколько раз, если в производстве участвовало несколько стран.&lt;br /&gt;
&lt;br /&gt;
Данный запрос позволяет узнать, в каком году страны выпустили свой первый фильм:&lt;br /&gt;
&lt;br /&gt;
 select distinct(country), min(production_year) over (partition by country) from movie_contries;&lt;br /&gt;
&lt;br /&gt;
* partition by country - означает, что выборка будет прохоидть для каждой группы с одинаковым значением country&lt;br /&gt;
* min(production_year) - для каждой из групп, которые определены далее, выбрать минимальное значение&lt;br /&gt;
* distinct(country) - так как over не производит группировку сам и вычисляет результат окна для каждой строки исходного отношения, то добавим distinct, чтобы вернуть только уникальные значения для country и соответствующие значения результатов выборки по окну.&lt;br /&gt;
&lt;br /&gt;
Дополнительно:&lt;br /&gt;
* https://habrahabr.ru/post/268983/&lt;br /&gt;
* http://www.postgresql.org/docs/9.3/static/tutorial-window.html&lt;br /&gt;
&lt;br /&gt;
== Создание представлений CREATE VIEW ==&lt;br /&gt;
&lt;br /&gt;
Запросы можно сохранять в виде представлений, чтобы затем обращаться к ним как к таблицам. &lt;br /&gt;
&lt;br /&gt;
 create view female_actors as&lt;br /&gt;
 select * from name where gender=&#039;f&#039;&lt;br /&gt;
&lt;br /&gt;
После этого вы сможете выбирать из представлений как из таблиц:&lt;br /&gt;
&lt;br /&gt;
 select count(1) from female_actors;&lt;br /&gt;
&lt;br /&gt;
Представления поддерживают целостность базы данных, и, если обновятся данные в таблице, из которой строится представление, то обновятся данные и в представлении. &lt;br /&gt;
&lt;br /&gt;
Можно обновлять данные через представления. При этом значения обновятся в соответствующих таблицах. Ограничением в данном случае являются представления, составленные из запросов с использованием функций агрегации. Так как результаты таких представлений не хранят исходные данные, через них невозможно найти кортежи, которые нужно обновить.&lt;br /&gt;
&lt;br /&gt;
Дополнительно о синтаксисе:&lt;br /&gt;
&lt;br /&gt;
* http://www.postgresql.org/docs/9.3/static/sql-createview.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задание:&#039;&#039;&#039;&lt;br /&gt;
Создайте представление, которое будет показывать проблемы с объектами в базе. Это будет несколько выборок с полями: имя сущности (фильм, актер, компания, персонаж), идентификатор объекта в его таблице, текстовое название объекта, комментарий с описанием проблемы. Эти выборки должны быть объединены с помощью UNION. Выборки следующего содержания:&lt;br /&gt;
* Фильмы без актеров (именно фильмы, см. kind_type)&lt;br /&gt;
* Актеры, которые нигде не снимались&lt;br /&gt;
* Компании, которые не выпустили ни одного фильма.&lt;br /&gt;
* Персонажи, не участвовавшие ни в одном фильме.&lt;br /&gt;
&lt;br /&gt;
После создания представления, намеренно испортите некоторые кортежи в таблицах, чтобы выборки возвращали новые значения. Убедитесь, что ваши изменения попадают в результаты выборки из представления.&lt;br /&gt;
&lt;br /&gt;
== Комплексные выборки ==&lt;br /&gt;
&lt;br /&gt;
Для защиты выполните любые две выборки. Для выполнения этих заданий используйте всё, что знаете.&lt;br /&gt;
&lt;br /&gt;
# Выберите 5 своих любимых (или случайных) сериалов, поля: название сериала, количество эпизодов, среднее количество персонажей в каждом эпизоде, название эпизода с наибольшим количеством актеров, количество актеров в этом эпизоде.&lt;br /&gt;
# Выберите фильмы, в ключевых словах которых есть &#039;math&#039; и выберите для них: название фильма, суммарные кассовые сборы, количество человек, участвовавших над созданием фильма, средний доход с фильма на человека: чистая прибыль (сборы минус бюджет) поделенная на количество людей.&lt;br /&gt;
# Выберите топ 10 фильмов, над созданием которых потрудилось больше всего людей (таблица complete_cast), поля: название фильма, количество всех, кто участвовал в создании, количество актеров&lt;br /&gt;
# Выберите топ 10 актеров, которые снялись в наибольшем количестве фильмов, поля: имя актера, дата рождения, количество фактов, количество фильмов, в которых он снялся, кинокомпания, с которой актер сотрудника над наибольшим количеством фильмов.&lt;br /&gt;
# Выберите топ 10 кинорежиссеров, которые сняли фильмы с наибольшим количеством задействованных людей, поля: название фильма, среднее количество людей, которые принимают участие в фильме режиссера, дата рождения режиссера, количество фактов о режиссере.&lt;br /&gt;
&lt;br /&gt;
== Защита лабораторной ==&lt;br /&gt;
# Объяснить, как работают составленные запросы.&lt;br /&gt;
# По просьбе преподавателя модифицировать написанный ранее запрос.&lt;br /&gt;
&lt;br /&gt;
Рекомендуется сохранить все запросы, так как в последующих лабораторных работах они понадобятся.&lt;br /&gt;
&lt;br /&gt;
== Полезные материалы ==&lt;br /&gt;
Интерактивные уроки по SQL (уроки строятся на работе с СУБД SQLite, поэтому некоторые функции не будут работать в PostgreSQL, но обычные запросы объясняются хорошо):&lt;br /&gt;
# Learn SQL: https://www.codecademy.com/learn/learn-sql&lt;br /&gt;
# Table Transformation: https://www.codecademy.com/learn/sql-table-transformation&lt;/div&gt;</summary>
		<author><name>Luc1ph3r</name></author>
	</entry>
	<entry>
		<id>https://wiki.cs.hse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_2&amp;diff=19295</id>
		<title>Базы данных/Лабораторная работа 2</title>
		<link rel="alternate" type="text/html" href="https://wiki.cs.hse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_2&amp;diff=19295"/>
		<updated>2016-04-22T13:48:59Z</updated>

		<summary type="html">&lt;p&gt;Luc1ph3r: Добавлены ссылки на интерактивные уроки по SQL запросам.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Задачи: освоить операции реляционной алгебры, оконные функции. Сохранение запросов в виде представлений. Фактически после этой работы вы сможете составить запрос любой сложности и создать удобное представление результатов.&lt;br /&gt;
&lt;br /&gt;
== Алиасы таблиц и выбираемых полей ==&lt;br /&gt;
&lt;br /&gt;
Для удобства составления запросов можно присваивать таблицам или выборкам алиасы. Это удобно в случае, если в запросе участвует несколько таблиц и вы хотите обратиться к конкретной.&lt;br /&gt;
&lt;br /&gt;
 select (select title from title t where t.id=ci.movie_id) from cast_info ci;&lt;br /&gt;
&lt;br /&gt;
Также можно присваивать алиасы значениям выбираемых полей. Это, например, удобно для последующей работы с этими полями:&lt;br /&gt;
&lt;br /&gt;
 select * from &lt;br /&gt;
 (select production_year, count(1) as cnt from title group by production_year) t&lt;br /&gt;
 where t.cnt &amp;gt; 50000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Работа с реляционной алгеброй ==&lt;br /&gt;
&lt;br /&gt;
В предыдущей лабораторной работе вы работали как правило с одной таблицей, выполняя операции селекции (добавляя условия в WHERE) и проекцией (перечисляя, что именно вы хотите выбрать между SELECT и FROM, в том числе, выполняя подзапросы к другим базам). Основные механизмы, которые дают большое преимущество реляционным СУБД относятся к взаимодействию нескольких отношений или результатов выборок. Эта лабораторная работа завершает введение и исчерпывает тему DML.&lt;br /&gt;
&lt;br /&gt;
=== Объединения ===&lt;br /&gt;
&lt;br /&gt;
Объединять множества в реляционных базах данных можно двумя способами: вертикально и горизонтально. Горизонтальные объединения используются намного чаще, так как реляционные базы нормализованы и нужные вам атрибуты могут быть раскиданы по разным сущностям. Посмотрите, как это выглядит в базе IMDb:&lt;br /&gt;
&lt;br /&gt;
http://i.imgur.com/pDq0n.png&lt;br /&gt;
&lt;br /&gt;
Используя связи между сущностями, вы можете горизонтально объединять таблицы и таким образом расширять результаты вышей выборки. Операции горизонтального соединения таблиц представлены в языках стандарта SQL ключевым словом JOIN. Рассмотрим варианты использования горизонтальных объединений.&lt;br /&gt;
&lt;br /&gt;
Исчерпывающее руководство для визуалов:&lt;br /&gt;
&lt;br /&gt;
https://lh3.googleusercontent.com/-7yCwOQ8wjL0/VBPfTmSuq0I/AAAAAAAAF0Q/1LS_wD5cJPY/w1024-h724/LEFT%2Bvs%2BRight%2BOuter%2BJoin%2Bin%2BSQL.png&lt;br /&gt;
&lt;br /&gt;
Но если вы любите копировать команды из методички и смотреть, что получается, читайте дальше:)&lt;br /&gt;
&lt;br /&gt;
=== Введение в JOIN ===&lt;br /&gt;
&lt;br /&gt;
Присоединение обычно происходит по некоторым атрибутам, которые называются первичными и внешними ключами. Первичный ключ обычно называется id, он содержится во всех таблицах, которые претендуют на участие в верно построенной реляционной базе. Также таблицы могут содержать внешние ключи - это атрибуты, как правило типа unsigned integer, которые содержат те же значения, что и первичные ключи соответствующих сущностей. &lt;br /&gt;
&lt;br /&gt;
Например, теперь, если вы хотите получить отчет, в котором будут следующие поля: имя актера, имя персонажа, фильм, год выпуска фильма, то вам нужно присоединить к таблице cast_info таблицы, где содержатся названия фильмов, имена актеров и имена персонажей, а именно: char_name, title и name, которые нужно присоединить по их первичным ключам.&lt;br /&gt;
&lt;br /&gt;
Синтаксис команды join:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM t1&lt;br /&gt;
 JOIN t2 ON t1.id=t2.t1_id&lt;br /&gt;
&lt;br /&gt;
В условии соединения ON можно указывать множество условий используя скобки и AND/OR.&lt;br /&gt;
&lt;br /&gt;
Альтернативный способ выборки из нескольких таблиц:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM t1, t2 &lt;br /&gt;
 WHERE t1.id=t2.t1_id&lt;br /&gt;
&lt;br /&gt;
В результате запросов вы получите все сопоставленные записи и атрибуты из обеих таблиц.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Внутреннее объединение INNER JOIN ====&lt;br /&gt;
&lt;br /&gt;
Обычный JOIN сопоставляет кортежи соединяемых сущностей по указаному в ON правилу. Если какое-либо из значений по которому соединяется сущность не задано (NULL), то кортеж не попадет в результирующую выборку.&lt;br /&gt;
&lt;br /&gt;
Пример человекопонятной выборки, кто где снимался:&lt;br /&gt;
&lt;br /&gt;
 select t.title, n.name, c.name from cast_info ca&lt;br /&gt;
 join title t on t.id=ca.movie_id&lt;br /&gt;
 join name n on n.id=ca.person_id&lt;br /&gt;
 join char_name c on c.id=ca.person_role_id&lt;br /&gt;
 where t.kind_id=1&lt;br /&gt;
 limit 10;&lt;br /&gt;
&lt;br /&gt;
Лимит указан для быстрой демонтсрации запроса.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задания:&#039;&#039;&#039;&lt;br /&gt;
* Сделайте следующий отчет: название компании, выпускающей кинофильмы; название фильма; факты о фильме - для какой-либо выбранной вами кинокомпании (выберите более менее активную) за период в 5 последних лет. Диапазон дат укажите не конкретными датами, а относительно сегодняшнего дня, поищите соответствующие функции работы с временем.&lt;br /&gt;
* Соберите статистику по количеству фильмов выпускаемых разными странами (ищите страну в movie_info) и количество фильмов, для которых не указана страна.&lt;br /&gt;
&lt;br /&gt;
==== Объединения слева и справа LEFT JOIN, RIGHT JOIN ====&lt;br /&gt;
&lt;br /&gt;
В случае, если вы хотите обязательно выбрать все кортежи из первой таблицы, даже если нет соответствующих картежей во второй, используйте LEFT JOIN. Если соответствующих записей не будет, то атрибуты второй таблицы будут указаны как NULL.&lt;br /&gt;
&lt;br /&gt;
Выбрать ключевые слова с названиями фильмов, но так чтобы все фильмы попали в выборку.&lt;br /&gt;
&lt;br /&gt;
select t.title, k.keyword from title t &lt;br /&gt;
left join movie_keyword mk on mk.movie_id=t.id &lt;br /&gt;
left join keyword k on k.id=mk.keyword_id &lt;br /&gt;
where mk.id is null &lt;br /&gt;
limit 100;&lt;br /&gt;
&lt;br /&gt;
Лимит указан для быстрой демонтсрации запроса.&lt;br /&gt;
&lt;br /&gt;
RIGHT JOIN соответственно оставляет все значения в присоединяемой таблице, а для кортежей, для которых не удалось сопоставить кортежи из первой таблицы, прописывает NULL.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задания:&#039;&#039;&#039;&lt;br /&gt;
# Найдите фильмы, в которых нет персонажей.&lt;br /&gt;
# Найдите актеров, которые никогда не снимались в фильмах. (двумя способами: с помощью JOIN и с помощью WHERE NOT EXIST)&lt;br /&gt;
&lt;br /&gt;
==== Полное объединение FULL JOIN ====&lt;br /&gt;
&lt;br /&gt;
Работает аналогично LEFT и RIGHT JOIN: в случае, если какому-то кортежу из первой или второй таблице не удалось найти пару, то вместо соответствующих значений прописывается NULL.&lt;br /&gt;
&lt;br /&gt;
Пока никаких идей для полезного запроса, full join нужен обычно для того, чтобы обнаруживать нарушения целостности. Попробуйте узнать, есть ли в cast_info записи с невалидными идентификаторами актеров, фильмов или ролей и фильмы и роли, для которых нет записей в cast_info. Или проверьте, что в таблице фактов об актерах нет невалидных идентификаторов (ссылки на несуществующих актеров). Если вы корректно удалили актера в первой лабораторной работе или просто ничего не делали, то таких записей не должно быть.&lt;br /&gt;
&lt;br /&gt;
==== Декартово произведение ====&lt;br /&gt;
&lt;br /&gt;
Как выбло ранее показано, существует альтернативный способ выборки из нескольких таблиц:&lt;br /&gt;
&lt;br /&gt;
 SELECT * FROM t1, t2 WHERE t1.id=t2.t1_id&lt;br /&gt;
&lt;br /&gt;
Если не указывать условий, то таблицы перемножатся: то есть в результате вы получите выборку, в которой каждая запись из одной таблицы сопоставляется с каждой записью из другой таблицы.&lt;br /&gt;
&lt;br /&gt;
Посчитайте, сколько всего различных комбинаций актеров и персонажей может быть исходя из базы. В этой выборке следует также учесть, что персонаж может появляться в разных фильмах, но называться одинаково, при этом просто умножив cast_info на что-то не получится. Выбирайте сразу количество, не выводя результаты выборки.&lt;br /&gt;
&lt;br /&gt;
=== Операции над множествами ===&lt;br /&gt;
&lt;br /&gt;
Вертикальные объединения обычно используют для манипуляции с готовыми запросами. Для того, чтобы объединить две выборки, нужно, чтобы у них совпадали имена атрибутов.&lt;br /&gt;
&lt;br /&gt;
Синтаксис:&lt;br /&gt;
&lt;br /&gt;
 select * from t1&lt;br /&gt;
 union&lt;br /&gt;
 select * from t2&lt;br /&gt;
&lt;br /&gt;
==== Объединение UNION ====&lt;br /&gt;
&lt;br /&gt;
Объединяет кортежи выборок, при этом убирает дубли.&lt;br /&gt;
&lt;br /&gt;
==== Полное объединение UNION ALL ====&lt;br /&gt;
&lt;br /&gt;
Объединяет кортежи выборок, при этом не убирает дубли.&lt;br /&gt;
&lt;br /&gt;
==== Пересечение INTERSECT ====&lt;br /&gt;
&lt;br /&gt;
Возвращает кортежи, которые есть в обоих отношениях.&lt;br /&gt;
&lt;br /&gt;
==== Вычитание EXCEPT ====&lt;br /&gt;
&lt;br /&gt;
Возвращает кортежи, которые есть в первом, но нет во втором отношениях.&lt;br /&gt;
&lt;br /&gt;
== Оконные функции ==&lt;br /&gt;
&lt;br /&gt;
Оконные функции - это наиболее мощный инструмент, заложенный в стандарте SQL. Применение оконных функций к месту обычно помогает существенно упростить запросы.&lt;br /&gt;
&lt;br /&gt;
Оконные функции позволяют выполнять подзапросы и собирать статистику для каждого результирующего кортежа по некоторому окну данных. Обычно окном данных выступают кортежи сгруппированные по значению какого-либо атрибута.&lt;br /&gt;
&lt;br /&gt;
Для начала создадим небольшой сэмпл данных через представление (см. ниже), чтобы упростить демонстрационные запросы:&lt;br /&gt;
&lt;br /&gt;
 create view movie_contries as (&lt;br /&gt;
  select info as country, movie_id, title, t.production_year &lt;br /&gt;
  from movie_info mi &lt;br /&gt;
  join title t on mi.movie_id=t.id and mi.info_type_id=8 and t.kind_id=1&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
Фильмы с указанием страны и года выпуска:&lt;br /&gt;
 select * from movie_contries;&lt;br /&gt;
&lt;br /&gt;
При этом каждый фильм может упоминаться несколько раз, если в производстве участвовало несколько стран.&lt;br /&gt;
&lt;br /&gt;
Данный запрос позволяет узнать, в каком году страны выпустили свой первый фильм:&lt;br /&gt;
&lt;br /&gt;
 select distinct(country), min(production_year) over (partition by country) from movie_contries;&lt;br /&gt;
&lt;br /&gt;
* partition by country - означает, что выборка будет прохоидть для каждой группы с одинаковым значением country&lt;br /&gt;
* min(production_year) - для каждой из групп, которые определены далее, выбрать минимальное значение&lt;br /&gt;
* distinct(country) - так как over не производит группировку сам и вычисляет результат окна для каждой строки исходного отношения, то добавим distinct, чтобы вернуть только уникальные значения для country и соответствующие значения результатов выборки по окну.&lt;br /&gt;
&lt;br /&gt;
Дополнительно:&lt;br /&gt;
* https://habrahabr.ru/post/268983/&lt;br /&gt;
* http://www.postgresql.org/docs/9.3/static/tutorial-window.html&lt;br /&gt;
&lt;br /&gt;
== Создание представлений CREATE VIEW ==&lt;br /&gt;
&lt;br /&gt;
Запросы можно сохранять в виде представлений, чтобы затем обращаться к ним как к таблицам. &lt;br /&gt;
&lt;br /&gt;
 create view female_actors as&lt;br /&gt;
 select * from name where gender=&#039;f&#039;&lt;br /&gt;
&lt;br /&gt;
После этого вы сможете выбирать из представлений как из таблиц:&lt;br /&gt;
&lt;br /&gt;
 select count(1) from female_actors;&lt;br /&gt;
&lt;br /&gt;
Представления поддерживают целостность базы данных, и, если обновятся данные в таблице, из которой строится представление, то обновятся данные и в представлении. &lt;br /&gt;
&lt;br /&gt;
Можно обновлять данные через представления. При этом значения обновятся в соответствующих таблицах. Ограничением в данном случае являются представления, составленные из запросов с использованием функций агрегации. Так как результаты таких представлений не хранят исходные данные, через них невозможно найти кортежи, которые нужно обновить.&lt;br /&gt;
&lt;br /&gt;
Дополнительно о синтаксисе:&lt;br /&gt;
&lt;br /&gt;
* http://www.postgresql.org/docs/9.3/static/sql-createview.html&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Задание:&#039;&#039;&#039;&lt;br /&gt;
Создайте представление, которое будет показывать проблемы с объектами в базе. Это будет несколько выборок с полями: имя сущности (фильм, актер, компания, персонаж), идентификатор объекта в его таблице, текстовое название объекта, комментарий с описанием проблемы. Эти выборки должны быть объединены с помощью UNION. Выборки следующего содержания:&lt;br /&gt;
* Фильмы без актеров (именно фильмы, см. kind_type)&lt;br /&gt;
* Актеры, которые нигде не снимались&lt;br /&gt;
* Компании, которые не выпустили ни одного фильма.&lt;br /&gt;
* Персонажи, не участвовавшие ни в одном фильме.&lt;br /&gt;
&lt;br /&gt;
После создания представления, намеренно испортите некоторые кортежи в таблицах, чтобы выборки возвращали новые значения. Убедитесь, что ваши изменения попадают в результаты выборки из представления.&lt;br /&gt;
&lt;br /&gt;
== Комплексные выборки ==&lt;br /&gt;
&lt;br /&gt;
Для защиты выполните любые две выборки. Для выполнения этих заданий используйте всё, что знаете.&lt;br /&gt;
&lt;br /&gt;
# Выберите 5 своих любимых (или случайных) сериалов, поля: название сериала, количество эпизодов, среднее количество персонажей в каждом эпизоде, название эпизода с наибольшим количеством актеров, количество актеров в этом эпизоде.&lt;br /&gt;
# Выберите фильмы, в ключевых словах которых есть &#039;math&#039; и выберите для них: название фильма, суммарные кассовые сборы, количество человек, участвовавших над созданием фильма, средний доход с фильма на человека: чистая прибыль (сборы минус бюджет) поделенная на количество людей.&lt;br /&gt;
# Выберите топ 10 фильмов, над созданием которых потрудилось больше всего людей (таблица complete_cast), поля: название фильма, количество всех, кто участвовал в создании, количество актеров&lt;br /&gt;
# Выберите топ 10 актеров, которые снялись в наибольшем количестве фильмов, поля: имя актера, дата рождения, количество фактов, количество фильмов, в которых он снялся, кинокомпания, с которой актер сотрудника над наибольшим количеством фильмов.&lt;br /&gt;
# Выберите топ 10 кинорежиссеров, которые сняли фильмы с наибольшим количеством задействованных людей, поля: название фильма, среднее количество людей, которые принимают участие в фильме режиссера, дата рождения режиссера, количество фактов о режиссере.&lt;br /&gt;
&lt;br /&gt;
== Защита лабораторной ==&lt;br /&gt;
# Объяснить, как работают составленные запросы.&lt;br /&gt;
# По просьбе преподавателя модифицировать написанный ранее запрос.&lt;br /&gt;
&lt;br /&gt;
Рекомендуется сохранить все запросы, так как в последующих лабораторных работах они понадобятся.&lt;br /&gt;
&lt;br /&gt;
== Полезные материалы ==&lt;br /&gt;
Интерактивные уроки по SQL (уроки строятся на работе с СУБД SQLite, поэтому некоторые функции не будут работать в PostgreSQL, но обычные запросы объясняются хорошо):&lt;br /&gt;
# Learn SQL: https://www.codecademy.com/learn/learn-sql&lt;br /&gt;
# Table Transformation: https://www.codecademy.com/learn/sql-table-transformation&lt;/div&gt;</summary>
		<author><name>Luc1ph3r</name></author>
	</entry>
	<entry>
		<id>https://wiki.cs.hse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_1&amp;diff=19178</id>
		<title>Базы данных/Лабораторная работа 1</title>
		<link rel="alternate" type="text/html" href="https://wiki.cs.hse.ru/index.php?title=%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9B%D0%B0%D0%B1%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BD%D0%B0%D1%8F_%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B0_1&amp;diff=19178"/>
		<updated>2016-04-08T08:34:19Z</updated>

		<summary type="html">&lt;p&gt;Luc1ph3r: Добавлена ссылка на интерактивный урок по основам SQL запросов.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Задачи: освоить самые необходимые навыки настройки СУБД, получения данных и манипуляции с ними, а также составления простых отчетов.&lt;br /&gt;
&lt;br /&gt;
=== Введение ===&lt;br /&gt;
&lt;br /&gt;
Так как у некоторых групп лабораторные работы начинаются раньше первой лекции, то предлагается [http://wiki.cs.hse.ru/%D0%91%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D1%82%D0%B5%D1%80%D0%BC%D0%B8%D0%BD%D1%8B краткий список терминов], используемых в лабораторной работе.&lt;br /&gt;
&lt;br /&gt;
PostgreSQL - популярная реляционная система управления базами данных. Эта СУБД используется многими крупными компаниями, являясь единственной хорошо развитой свободной альтернативой наряду с MySQL. Но по сравнению с MySQL, PostgreSQL предоставляет больше возможностей для работы с большими объемами данных (не &amp;quot;big data&amp;quot;, но до терабайта).&lt;br /&gt;
&lt;br /&gt;
В качестве базы данных в лабораторных работах будет использоваться база фильмов IMDB (сам сайт также использует эту СУБД). Дамп базы достаточно большой, поэтому, если у вас есть возможность, скачайте и импортируйте его заранее.&lt;br /&gt;
&lt;br /&gt;
Рекомендуется использовать Ubuntu 14.04 и PostgreSQL 8.1+. Также нужно примерно 10 Гб места на диске.&lt;br /&gt;
&lt;br /&gt;
Для выполнения запросов подойдет и терминал, но можно использовать IDE (например, DataGrip или любую другую от JetBrains с аналогичным плагином).&lt;br /&gt;
&lt;br /&gt;
База данных, которая используется в лабораторных работах: https://yadi.sk/d/EVhJUiroqgzWj&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 1: Установка PostgreSQL ===&lt;br /&gt;
&lt;br /&gt;
Первая задача состоит в том, чтобы установить СУБД и проверить ее работоспособность.&lt;br /&gt;
&lt;br /&gt;
Выполните в терминале:&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install postgresql postgresql-contrib&lt;br /&gt;
&lt;br /&gt;
Сервер PostgreSQL создает отдельно пользователя в системе для доступа к базе. Чтобы переключиться на этого пользователя, выполните:&lt;br /&gt;
&lt;br /&gt;
 sudo -i -u postgres &lt;br /&gt;
&lt;br /&gt;
Теперь вы можете войти в интерактивный режим работы с СУБД:&lt;br /&gt;
&lt;br /&gt;
 psql&lt;br /&gt;
&lt;br /&gt;
Приглашение в интерактивном режиме выглядит так:&lt;br /&gt;
&lt;br /&gt;
 postgres=# &lt;br /&gt;
&lt;br /&gt;
Чтобы посмотреть, какие базы уже есть в системе, наберите:&lt;br /&gt;
&lt;br /&gt;
 \l&lt;br /&gt;
&lt;br /&gt;
Примерный результат:&lt;br /&gt;
&lt;br /&gt;
 postgres=# \l&lt;br /&gt;
                                  List of databases&lt;br /&gt;
    Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   &lt;br /&gt;
 -----------+----------+----------+-------------+-------------+-----------------------&lt;br /&gt;
  postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | &lt;br /&gt;
  template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +&lt;br /&gt;
            |          |          |             |             | postgres=CTc/postgres&lt;br /&gt;
  template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +&lt;br /&gt;
            |          |          |             |             | postgres=CTc/postgres&lt;br /&gt;
 (3 rows)&lt;br /&gt;
&lt;br /&gt;
Альтернативно, можно выполнить запрос:&lt;br /&gt;
&lt;br /&gt;
 SELECT datname FROM pg_database;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Чтобы работать с конкретной базой, ее нужно выбрать. Выполните \c database_name:&lt;br /&gt;
&lt;br /&gt;
 postgres=# \c imdb&lt;br /&gt;
 You are now connected to database &amp;quot;imdb&amp;quot; as user &amp;quot;postgres&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Чтобы узнать, какие таблицы есть базе, выполните:&lt;br /&gt;
&lt;br /&gt;
 \d&lt;br /&gt;
&lt;br /&gt;
Альтернативный запрос:&lt;br /&gt;
&lt;br /&gt;
 SELECT table_name FROM information_schema.tables WHERE table_schema = &#039;public&#039;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Чтобы узнать, какие есть колонки в таблице:&lt;br /&gt;
&lt;br /&gt;
 \d+ table&lt;br /&gt;
&lt;br /&gt;
или&lt;br /&gt;
&lt;br /&gt;
 \d table&lt;br /&gt;
&lt;br /&gt;
Альтернативный запрос:...&lt;br /&gt;
&lt;br /&gt;
 SELECT column_name FROM information_schema.columns WHERE table_name =&#039;table&#039;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 2: Основы администрирования PostgreSQL ===&lt;br /&gt;
&lt;br /&gt;
Следующая задача состоит в том, чтобы настроить два важный параметра:&lt;br /&gt;
&lt;br /&gt;
* логирование запросов - чтобы подтвердить, что вы честно выполняли лабу&lt;br /&gt;
* ручное подтверждение вносимых изменений - чтобы в случае некорректных запросов вы могли откатить свои изменения простым способом.&lt;br /&gt;
&lt;br /&gt;
Про второй механизм подробнее. Когда вы вносите изменения в данные, они не сразу вступают в силу. СУБД создает diff аналогичный тому, который можно видеть в git. После этого вы начинаете работать с измененной версией, но в других сессиях данные по-прежнему старые. Если вы что-то сделали неправильно, вы можете откатить изменения в своей сессии с помощью команды rollback. Если же все изменения корректны, подтвердите их, выполнив commit. Закоммиченные изменения откатить намного сложнее, поэтому как правило в СУБД отключают опцию autocommit, которая подтверждает изменения автоматически.&lt;br /&gt;
&lt;br /&gt;
Когда вы завершаете сессию, выполняется rollback. Если вы убиваете процесс, то он может еще некоторое время &amp;quot;держать&amp;quot; данные, не давая их изменить.&lt;br /&gt;
&lt;br /&gt;
Приступим к конфигурированию.&lt;br /&gt;
&lt;br /&gt;
PostgreSQL представлен в системе в виде сервиса, управлять которым можно как и обычно через команду service. Как правило, для внесения каких-либо изменений нужно перезапустить сервис.&lt;br /&gt;
&lt;br /&gt;
Конфигурационный файл:&lt;br /&gt;
&lt;br /&gt;
 sudo vim /etc/postgresql/9.*/main/postgresql.conf&lt;br /&gt;
&lt;br /&gt;
Допишите или раскомментируйте:&lt;br /&gt;
&lt;br /&gt;
 log_line_prefix = &#039;%t %c %u &#039; # time sessionid user&lt;br /&gt;
 log_statement = &#039;all&#039;&lt;br /&gt;
&lt;br /&gt;
Управлять некоторыми параметрами можно прямо из сессии с СУБД. Например включение подробного логирования:&lt;br /&gt;
&lt;br /&gt;
 SELECT set_config(&#039;log_statement&#039;, &#039;all&#039;, true);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Чтобы отключить автокоммит, от пользователя postgres допишите в файл ~/.psqlrc:&lt;br /&gt;
&lt;br /&gt;
 \set AUTOCOMMIT off &lt;br /&gt;
&lt;br /&gt;
Также можно инициировать процедуру, которая внесет изменения глобально только в случае выполнения commit:&lt;br /&gt;
&lt;br /&gt;
 BEGIN;&lt;br /&gt;
 -- манипуляции с данными&lt;br /&gt;
 COMMIT;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 3: импорт и экспорт базы данных IMDB ===&lt;br /&gt;
&lt;br /&gt;
Две наиболее важные операции. Выполняйте в сессии пользователя postgres.&lt;br /&gt;
&lt;br /&gt;
Экспортировать базу данных:&lt;br /&gt;
&lt;br /&gt;
 pg_dump dbname | gzip &amp;gt; filename.gz&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Импортировать базу:&lt;br /&gt;
&lt;br /&gt;
 gunzip -c filename.gz | psql dbname&lt;br /&gt;
&lt;br /&gt;
Попробуйте импортировать базу IMDB:&lt;br /&gt;
&lt;br /&gt;
https://yadi.sk/d/EVhJUiroqgzWj&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Важно:&#039;&#039;&#039; прежде чем импортировать дамп, нужно создать базу данных:&lt;br /&gt;
&lt;br /&gt;
В psql выполните:&lt;br /&gt;
&lt;br /&gt;
 create database imdb;&lt;br /&gt;
&lt;br /&gt;
Это займет некоторое время (20 минут - норм). &lt;br /&gt;
&lt;br /&gt;
Также можно импортировать только конкретные таблицы, указав их через ключ  --table.&lt;br /&gt;
&lt;br /&gt;
Можно импортировать только схему: --schema-only или только данные: --data-only&lt;br /&gt;
&lt;br /&gt;
==== Структура базы IMDB ====&lt;br /&gt;
&lt;br /&gt;
У каждой таблицы есть идентификатор, указанный как первичный ключ (id). По нему выбирать быстрее всего.&lt;br /&gt;
&lt;br /&gt;
Основные таблицы и их описание:&lt;br /&gt;
* title - названия фильмов (поле title) и год выпуска (поле production_year); если это сериал, то также здесь можно найти номер эпизода&lt;br /&gt;
* movie_info - характеристики и факты о фильме: movie_id - идентификатор из таблицы title (далее для краткой записи: title.id), info_type_id - идентификатор из таблицы info_type (info_type.id), info - текстовое поле со значением характеристики.&lt;br /&gt;
* name - актеры (имя и пол)&lt;br /&gt;
* person_info - характеристики и факты об актерах также с названиями характеристик из (info_type.id)&lt;br /&gt;
* char_name - роли (имена персонажей)&lt;br /&gt;
* cast_info - таблица со связью ролей (person_role_id), актеров (person_id) и фильмов (movie_id)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 4: Простые операции CRUD ===&lt;br /&gt;
&lt;br /&gt;
К простым операциям манипуляции данными (Create, Read, Update, Delete) относятся:&lt;br /&gt;
&lt;br /&gt;
* Добавление: INSERT&lt;br /&gt;
* Выборка: SELECT &lt;br /&gt;
* Обновление: UPDATE&lt;br /&gt;
* Удаление: DELETE&lt;br /&gt;
&lt;br /&gt;
==== Добавление данных INSERT ====&lt;br /&gt;
&lt;br /&gt;
Чтобы добавить новую запись в таблицу, нужно вычислить ее идентификатор. Для этого в PostgreSQL используются последовательности - числа, которые меняются по заданным правилам (обычно просто инкрементируются на единицу). &lt;br /&gt;
&lt;br /&gt;
Чтобы посмотреть список всех последовательностей выполните:&lt;br /&gt;
&lt;br /&gt;
 SELECT c.relname FROM pg_class c WHERE c.relkind = &#039;S&#039;;&lt;br /&gt;
&lt;br /&gt;
Именование последовательностей обычно выбирают предсказуемым, чтобы легко было понять, к какой таблице они относятся. &lt;br /&gt;
&lt;br /&gt;
Синтаксис INSERT выглядит так: сначала в скобках перечисляются атрибуты, которые будут вставлены, а затем после VALUES в скобках указываются значения. Можно также не перечислять атрибуты, тогда в VALUES нужно по порядку указать значения для всех. &lt;br /&gt;
&lt;br /&gt;
Попробуйте добавить себя в список актеров:&lt;br /&gt;
&lt;br /&gt;
 insert into name (id, name, gender) values(nextval(&#039;name_id_seq&#039;), &#039;Ivan Savin&#039;, &#039;m&#039;);&lt;br /&gt;
&lt;br /&gt;
Здесь nextval(&#039;name_id_seq&#039;) генерирует следующее значение для последовательности name_id_seq.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Важно:&#039;&#039;&#039; В предлагаемом дампе базы последовательности обнулены и не могут сгенерировать уникальный идентификатор сразу. Чтобы это исправить, укажите текущее значение последовательности максимальным идентификатором в таблице, к которой она относится. Пример:&lt;br /&gt;
&lt;br /&gt;
 select max(id) from name;&lt;br /&gt;
 ALTER SEQUENCE name_id_seq INCREMENT 5555233;&lt;br /&gt;
&lt;br /&gt;
Если вы отключили автокоммит, то, так как вы вносите изменения в данные, завершите операцию, выполнив:&lt;br /&gt;
&lt;br /&gt;
 commit;&lt;br /&gt;
&lt;br /&gt;
Если вы не уверены в своих изменениях, выполните:&lt;br /&gt;
&lt;br /&gt;
 rollback;&lt;br /&gt;
&lt;br /&gt;
За одну операцию INSERT можно вставлять несколько строк данных. Для этого после VALUES нужно перечислить кортежи данных через запятую:&lt;br /&gt;
&lt;br /&gt;
 insert into name (id, name, gender) &lt;br /&gt;
 values(nextval(&#039;name_id_seq&#039;), &#039;Dmitry Burmistrov&#039;, &#039;m&#039;), &lt;br /&gt;
 (nextval(&#039;name_id_seq&#039;), &#039;Victor Yakovlev&#039;, &#039;m&#039;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Выборка данных SELECT ====&lt;br /&gt;
&lt;br /&gt;
Для чтения данных из базы используется ключевое слово SELECT, после которого указывается список атрибутов, которые нужно получить в выборке. Если указать вместо списка атрибутов &amp;quot;*&amp;quot;, то выберутся все. Самый простой запрос выборки из базы данных выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
 select * from info_type;&lt;br /&gt;
&lt;br /&gt;
Не пробуйте выбрать все данные из больших таблиц (title, name) - это займет много времени. Если вы хотите выбрать несколько кортежей данных для примера, то ограничьте результаты с помощью LIMIT:&lt;br /&gt;
&lt;br /&gt;
 select * from title limit 10;&lt;br /&gt;
&lt;br /&gt;
Условия выборки указываются после ключевого слова WHERE. Условия можно комбинировать с помощью скобок и слов OR и AND. Примеры условий:&lt;br /&gt;
&lt;br /&gt;
* WHERE title=&#039;Databases&#039; - простое условие равенства&lt;br /&gt;
* WHERE title like &#039;%base%&#039; - поиск по подстроке, &amp;quot;%&amp;quot; - любое количество любых символов&lt;br /&gt;
* WHERE created_date &amp;gt; now() - сравнение даты с текущим моментом; см. также http://www.postgresql.org/docs/8.3/static/functions-datetime.html&lt;br /&gt;
* WHERE title not in (&#039;Databases&#039;, &#039;Networks&#039;) - значение не входит в список&lt;br /&gt;
* WHERE not exist (SELECT * FROM ...) - выполняется, если подзапрос вернул хотя бы одну запись&lt;br /&gt;
* WHERE artist_id in (SELECT id FROM artist...) - подзапрос определяет множество значений.&lt;br /&gt;
&lt;br /&gt;
Пример запроса с условиями:&lt;br /&gt;
&lt;br /&gt;
 select * from title where title like &#039;%Matrix&#039; and production_year=1999;&lt;br /&gt;
&lt;br /&gt;
Также в блоке с перечислением атрибутов можно указывать подзапросы. Подзапрос будет выполняться в последнюю очередь для каждого кортежа, удовлетворяющего остальным условиям. Также, чтобы использовать условия из основного запроса в этом подзапросе, лучше указывать название атрибута вместе с таблицей, в которой он принадлежит:&lt;br /&gt;
&lt;br /&gt;
 select (select info from info_type where info_type.id=person_info.info_type_id), person_info.info from person_info where person_id=1732058;&lt;br /&gt;
&lt;br /&gt;
Попробуйте найти ваши любимые фильмы, указывая часть названия и комбинируя условия, указывая год выхода. Попробуйте найти ваших любимых актеров и факты о них.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Обновление данных UPDATE ====&lt;br /&gt;
&lt;br /&gt;
Чтобы обновить данные, нужно указать, какие параметры вы хотите обновить и условия выборки обновляемых данных:&lt;br /&gt;
&lt;br /&gt;
 update cast_info set person_id=1732058 where movie_id=3514559;&lt;br /&gt;
&lt;br /&gt;
Если вы не укажите условия, то обновятся значения во всей таблице, обычно это не нужно.&lt;br /&gt;
&lt;br /&gt;
В запросе на обновление также можно использовать подзапросы. Единственное ограничение: нельзя в подзапросе использовать обновляемую таблицу, так как СУБД в этом случае можно ввести в бесконечный цикл обновления. Пример более понятного запроса на обновление:&lt;br /&gt;
&lt;br /&gt;
 update cast_info set person_id=(select id from name where name=&#039;Savin Ivan&#039;) &lt;br /&gt;
 where movie_id=(select id from title where title like &#039;The Matrix&#039; and production_year=1999);&lt;br /&gt;
&lt;br /&gt;
Если вы не закоммитите изменения, то обновляемые записи останутся залоченными, то есть их невозможно будет обновить в других сессиях. Попробуйте не выполняя коммит, открыть новую сессию, обновить те же данные и попытаться их закоммитить. После этого закоммитьте изменения в первой сессии.&lt;br /&gt;
&lt;br /&gt;
Попробуйте назначить себя и своих друзей на подходящие роли в ваших любимых фильмах. Составьте запрос, который будет демонстрировать, кто где и какую роль играет (используя подзапросы).&lt;br /&gt;
&lt;br /&gt;
==== Удаление данных DELETE ====&lt;br /&gt;
&lt;br /&gt;
Синтаксис удаления данных аналогичен синтаксису выборки за исключением того, что вместо &amp;quot;SELECT * FROM&amp;quot; достаточно написать &amp;quot;DELETE FROM&amp;quot;. Будьте внимательны, удаляя данные и проверяйте условия перед отправкой коммита.&lt;br /&gt;
&lt;br /&gt;
Удалите актеров, которые вам не нравятся (или актера, выбранного случайно). Это сделать не так просто, как может показаться, потому что их идентификаторы используются в других таблицах, а нарушать целостность данных нельзя. Для корректного удаления, нужно найти все связи актера с фильмами и удалить сначала их, после этого удалить информацию о них из таблицы фактов, после этого станет доступно удаление.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Часть 5: Агрегация данных ===&lt;br /&gt;
&lt;br /&gt;
Часто с помощью СУБД генерируют различные полезные отчеты. В любой популярной СУБД есть агрегирующие функции, с помощью которых, можно собрать статистику о данных. Самая простая статистика: количество записей, удовлетворяющих заданным условиям. Пример выбора количества фильмов в базе:&lt;br /&gt;
&lt;br /&gt;
 select count(1) from title where kind_id=(select id from kind_type where kind=&#039;movie&#039;);&lt;br /&gt;
&lt;br /&gt;
Для числовых атрибутов также помимо COUNT можно использовать SUM, AVG и другие востребованные функции.&lt;br /&gt;
&lt;br /&gt;
Попробуйте вывести, в скольких фильмах снимались ваши любимые актеры.&lt;br /&gt;
&lt;br /&gt;
==== Группировка агрегированных данных GROUP BY ====&lt;br /&gt;
&lt;br /&gt;
Статистику можно также сгруппировать по некоторому атрибуту, который возвращается запросом. Например, чтобы вывести количества фильмов, выпущенных в каждый год, выполните запрос:&lt;br /&gt;
&lt;br /&gt;
 select production_year, count(1) from title&lt;br /&gt;
 where kind_id=(select id from kind_type where kind=&#039;movie&#039;)&lt;br /&gt;
 group by production_year&lt;br /&gt;
 order by production_year;&lt;br /&gt;
&lt;br /&gt;
В запросе также результаты отсортированы по году выпуска с помощью ORDER BY.&lt;br /&gt;
&lt;br /&gt;
Попробуйте собрать следующие статистики: количество актеров и актрис; среднее количество фильмов в год, выпущенных в XX веке, и, выпущенных в XXI веке (с учетом текущего года). &lt;br /&gt;
&lt;br /&gt;
Попробуйте также узнать среднее количество ролей в фильмах в различные годы. Этот запрос может выполняться долго, поэтому рекомендуется сначала отлаживать его на небольшом количестве данных, используя LIMIT или какие-либо условия.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Защита лабораторной работы ===&lt;br /&gt;
# Показать логи выполнения запросов. &lt;br /&gt;
# Прокомментировать для агрегаций, что и как происходит. &lt;br /&gt;
# Написать запрос по просьбе семинариста.&lt;br /&gt;
&lt;br /&gt;
=== Полезные материалы ===&lt;br /&gt;
&lt;br /&gt;
Интерактивный урок по основам SQL запросов (видео лекции + задания): https://www.codeschool.com/courses/try-sql&lt;/div&gt;</summary>
		<author><name>Luc1ph3r</name></author>
	</entry>
</feed>