Browse Source

week6

master
RinRi 1 year ago
parent
commit
89ceace26e
5 changed files with 1268 additions and 0 deletions
  1. +548
    -0
      week06/lab6.html
  2. +237
    -0
      week06/lab6.org
  3. BIN
      week06/lab6.pdf
  4. +197
    -0
      week06/lab6.sql
  5. +286
    -0
      week06/lab6.tex

+ 548
- 0
week06/lab6.html View File

@@ -0,0 +1,548 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2023-02-28 Tue 23:48 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Lab 6 Amirlan Sharipov (BS-CS21-01)</title>
<meta name="author" content="Amirlan Sharipov (BS-CS21-01)" />
<meta name="generator" content="Org Mode" />
<style>
#content { max-width: 60em; margin: auto; }
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #e6e6e6;
border-radius: 3px;
background-color: #f2f2f2;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: auto;
}
pre.src:before {
display: none;
position: absolute;
top: -8px;
right: 12px;
padding: 3px;
color: #555;
background-color: #f2f2f299;
}
pre.src:hover:before { display: inline; margin-top: 14px;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-authinfo::before { content: 'Authinfo'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }

table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { }
</style>
</head>
<body>
<div id="content" class="content">
<h1 class="title">Lab 6 Amirlan Sharipov (BS-CS21-01)</h1>
<div id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org66e9ff0">1. Disclaimer</a></li>
<li><a href="#orge252c5e">2. Exercise 1</a>
<ul>
<li><a href="#org7e66bfe">2.1. Table creation and insertion</a></li>
<li><a href="#org4bc389b">2.2. Queries</a></li>
</ul>
</li>
<li><a href="#org613a69d">3. Exercise 2</a>
<ul>
<li><a href="#orgd2fe10b">3.1. Normalization</a>
<ul>
<li><a href="#org3192edb">3.1.1. 1NF</a></li>
<li><a href="#org7985b8c">3.1.2. 2NF</a></li>
<li><a href="#orgcc1c4fe">3.1.3. 3NF</a></li>
<li><a href="#org5a0e8c4">3.1.4. BCNF and 4NF</a></li>
<li><a href="#org19e9a14">3.1.5. Code</a></li>
</ul>
</li>
<li><a href="#org7829592">3.2. Queries</a></li>
</ul>
</li>
</ul>
</div>
</div>

<div id="outline-container-org66e9ff0" class="outline-2">
<h2 id="org66e9ff0"><span class="section-number-2">1.</span> Disclaimer</h2>
<div class="outline-text-2" id="text-1">
<p>
Please, use the lab6.sql file to read/copy the source code. Also, the html version of this document looks better than the pdf one.
</p>
</div>
</div>

<div id="outline-container-orge252c5e" class="outline-2">
<h2 id="orge252c5e"><span class="section-number-2">2.</span> Exercise 1</h2>
<div class="outline-text-2" id="text-2">
</div>
<div id="outline-container-org7e66bfe" class="outline-3">
<h3 id="org7e66bfe"><span class="section-number-3">2.1.</span> Table creation and insertion</h3>
<div class="outline-text-3" id="text-2-1">
<p>
I used the schema provided in the slides. And then manually inserted data into the tables.
</p>

<div class="org-src-container">
<pre class="src src-sql"><span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">customers</span> (
customerId <span style="color: #c792ea;">INT</span>,
customerName <span style="color: #c792ea;">VARCHAR</span>(<span style="color: #f78c6c; font-weight: bold;">50</span>),
city <span style="color: #c792ea;">VARCHAR</span>(<span style="color: #f78c6c; font-weight: bold;">50</span>),
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (customerId)
);

<span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">items</span> (
itemId <span style="color: #c792ea;">INT</span>,
itemName <span style="color: #c792ea;">VARCHAR</span>(<span style="color: #f78c6c; font-weight: bold;">50</span>),
price <span style="color: #c792ea;">FLOAT</span>,
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (itemId)
);

<span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">orders</span> (
orderId <span style="color: #c792ea;">INT</span>,
customerId <span style="color: #c792ea;">INT</span>,
<span style="color: #c792ea;">date</span> <span style="color: #c792ea;">DATE</span>,
<span style="color: #89DDFF;">FOREIGN</span> <span style="color: #89DDFF;">KEY</span> (customerId) <span style="color: #89DDFF;">REFERENCES</span> customers(customerId),
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (orderId)
);

<span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">order_details</span> (
orderId <span style="color: #c792ea;">INT</span>,
itemId <span style="color: #c792ea;">INT</span>,
quantity <span style="color: #c792ea;">INT</span>,
<span style="color: #89DDFF;">FOREIGN</span> <span style="color: #89DDFF;">KEY</span> (itemId) <span style="color: #89DDFF;">REFERENCES</span> items(itemId),
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (orderId, itemId)
);

<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> customers <span style="color: #89DDFF;">VALUES</span>(<span style="color: #c3e88d;">'101'</span>, <span style="color: #c3e88d;">'Martin'</span>, <span style="color: #c3e88d;">'Prague'</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> customers <span style="color: #89DDFF;">VALUES</span>(<span style="color: #c3e88d;">'107'</span>, <span style="color: #c3e88d;">'Herman'</span>, <span style="color: #c3e88d;">'Madrid'</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> customers <span style="color: #89DDFF;">VALUES</span>(<span style="color: #c3e88d;">'110'</span>, <span style="color: #c3e88d;">'Pedro'</span>, <span style="color: #c3e88d;">'Moscow'</span>);

<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> items <span style="color: #89DDFF;">VALUES</span>(<span style="color: #c3e88d;">'3786'</span>, <span style="color: #c3e88d;">'Net'</span>, <span style="color: #f78c6c; font-weight: bold;">35.0</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> items <span style="color: #89DDFF;">VALUES</span>(<span style="color: #c3e88d;">'4011'</span>, <span style="color: #c3e88d;">'Racket'</span>, <span style="color: #f78c6c; font-weight: bold;">65.0</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> items <span style="color: #89DDFF;">VALUES</span>(<span style="color: #c3e88d;">'9132'</span>, <span style="color: #c3e88d;">'Pack-3'</span>, <span style="color: #f78c6c; font-weight: bold;">4.75</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> items <span style="color: #89DDFF;">VALUES</span>(<span style="color: #c3e88d;">'5794'</span>, <span style="color: #c3e88d;">'Pack-6'</span>, <span style="color: #f78c6c; font-weight: bold;">5.0</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> items <span style="color: #89DDFF;">VALUES</span>(<span style="color: #c3e88d;">'3141'</span>, <span style="color: #c3e88d;">'Cover'</span>, <span style="color: #f78c6c; font-weight: bold;">10.0</span>);

<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> orders <span style="color: #89DDFF;">VALUES</span>(<span style="color: #c3e88d;">'2301'</span>, <span style="color: #c3e88d;">'101'</span>, <span style="color: #c3e88d;">'2011-02-23'</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> orders <span style="color: #89DDFF;">VALUES</span>(<span style="color: #c3e88d;">'2302'</span>, <span style="color: #c3e88d;">'107'</span>, <span style="color: #c3e88d;">'2011-02-25'</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> orders <span style="color: #89DDFF;">VALUES</span>(<span style="color: #c3e88d;">'2303'</span>, <span style="color: #c3e88d;">'110'</span>, <span style="color: #c3e88d;">'2011-02-27'</span>);

<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> order_details <span style="color: #89DDFF;">VALUES</span> (<span style="color: #c3e88d;">'2301'</span>, <span style="color: #c3e88d;">'3786'</span>, <span style="color: #f78c6c; font-weight: bold;">3</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> order_details <span style="color: #89DDFF;">VALUES</span> (<span style="color: #c3e88d;">'2301'</span>, <span style="color: #c3e88d;">'4011'</span>, <span style="color: #f78c6c; font-weight: bold;">6</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> order_details <span style="color: #89DDFF;">VALUES</span> (<span style="color: #c3e88d;">'2301'</span>, <span style="color: #c3e88d;">'9132'</span>, <span style="color: #f78c6c; font-weight: bold;">8</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> order_details <span style="color: #89DDFF;">VALUES</span> (<span style="color: #c3e88d;">'2302'</span>, <span style="color: #c3e88d;">'5794'</span>, <span style="color: #f78c6c; font-weight: bold;">4</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> order_details <span style="color: #89DDFF;">VALUES</span> (<span style="color: #c3e88d;">'2303'</span>, <span style="color: #c3e88d;">'4011'</span>, <span style="color: #f78c6c; font-weight: bold;">2</span>);
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> order_details <span style="color: #89DDFF;">VALUES</span> (<span style="color: #c3e88d;">'2303'</span>, <span style="color: #c3e88d;">'3141'</span>, <span style="color: #f78c6c; font-weight: bold;">2</span>);
</pre>
</div>
</div>
</div>

<div id="outline-container-org4bc389b" class="outline-3">
<h3 id="org4bc389b"><span class="section-number-3">2.2.</span> Queries</h3>
<div class="outline-text-3" id="text-2-2">
<p>
First query takes the sum of all prices * quantities groupped by the orders and sorts them.
The second query does the same thing, groups by customers, sorts by sum of quantities (descending order) and takes the first result.
</p>
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #89DDFF;">SELECT</span> order_details.orderId, <span style="color: #82aaff;">SUM</span>(items.price * order_details.quantity)
<span style="color: #89DDFF;">FROM</span> order_details
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> items <span style="color: #89DDFF;">on</span> items.itemId=order_details.itemId
<span style="color: #89DDFF;">group</span> <span style="color: #89DDFF;">by</span> order_details.orderId <span style="color: #89DDFF;">ORDER</span> <span style="color: #89DDFF;">BY</span> <span style="color: #82aaff;">sum</span> <span style="color: #89DDFF;">ASC</span>;

<span style="color: #89DDFF;">SELECT</span> customers.customerName, customers.city <span style="color: #89DDFF;">FROM</span> customers
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> orders <span style="color: #89DDFF;">ON</span> customers.customerId=orders.customerId
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> order_details <span style="color: #89DDFF;">ON</span> order_details.orderId=orders.orderId
<span style="color: #89DDFF;">GROUP</span> <span style="color: #89DDFF;">BY</span> customers.customerId
<span style="color: #89DDFF;">ORDER</span> <span style="color: #89DDFF;">BY</span> <span style="color: #82aaff;">SUM</span>(order_details.quantity) <span style="color: #89DDFF;">DESC</span>
<span style="color: #89DDFF;">LIMIT</span> <span style="color: #f78c6c; font-weight: bold;">1</span>;
</pre>
</div>
</div>
</div>
</div>

<div id="outline-container-org613a69d" class="outline-2">
<h2 id="org613a69d"><span class="section-number-2">3.</span> Exercise 2</h2>
<div class="outline-text-2" id="text-3">
</div>
<div id="outline-container-orgd2fe10b" class="outline-3">
<h3 id="orgd2fe10b"><span class="section-number-3">3.1.</span> Normalization</h3>
<div class="outline-text-3" id="text-3-1">
<p>
I have several assumptions:
</p>
<ul class="org-ul">
<li>Any teacher can work at several schools at once (or change the school)</li>
<li>Room numbers don&rsquo;t depend on schools: the first number of the room name is not enough to assume the opposite</li>
<li>Teachers may teach several courses: it&rsquo;s an elementary school, usually teachers can teach anything in elementary schools</li>
</ul>
</div>

<div id="outline-container-org3192edb" class="outline-4">
<h4 id="org3192edb"><span class="section-number-4">3.1.1.</span> 1NF</h4>
<div class="outline-text-4" id="text-3-1-1">
<p>
It&rsquo;s almost in 1NF state. Each cell is already atomic, values of the same domain, etc. The only thing that&rsquo;s not there is the primary key. Let&rsquo;s say for now that the primary key is a tuple of school, teacher, course, room, grade, and book. This way there are no conflicts. It still looks like a mess, so I will normalize it further.
</p>
</div>
</div>
<div id="outline-container-org7985b8c" class="outline-4">
<h4 id="org7985b8c"><span class="section-number-4">3.1.2.</span> 2NF</h4>
<div class="outline-text-4" id="text-3-1-2">
<p>
Make new tables with relations for partial functional dependencies of non-prime attributes on candidate keys:
</p>
<ul class="org-ul">
<li>lessons (lessonId, schoolName, teacherName, courseName, roomName, gradeName)</li>
<li>books (bookId, bookName, publisherName)</li>
<li>loans (loanId, lessonId, bookId, loanDate)</li>
</ul>
</div>
</div>
<div id="outline-container-orgcc1c4fe" class="outline-4">
<h4 id="orgcc1c4fe"><span class="section-number-4">3.1.3.</span> 3NF</h4>
<div class="outline-text-4" id="text-3-1-3">
<p>
Make new tables (with appropriate IDs) with relations for transitive functional dependencies of non-prime attribute on candidate key:
</p>
<ul class="org-ul">
<li>schools (schoolId, schoolName)</li>
<li>teachers (teacherId, teacherName)</li>
<li>courses (courseId, courseName)</li>
<li>rooms (roomId, roomName)</li>
<li>grades (gradeId, gradeName)</li>
<li>publishers (publisherId, publisherName)</li>
<li>lessons (lessonId, schoolId, teacherId, courseId, roomId, gradeId)</li>
<li>books (bookId, bookName, publisherId)</li>
<li>loans (loanId, lessonId, bookId, loanDate)</li>
</ul>
</div>
</div>
<div id="outline-container-org5a0e8c4" class="outline-4">
<h4 id="org5a0e8c4"><span class="section-number-4">3.1.4.</span> BCNF and 4NF</h4>
<div class="outline-text-4" id="text-3-1-4">
<p>
Already satisfies.
</p>
</div>
</div>

<div id="outline-container-org19e9a14" class="outline-4">
<h4 id="org19e9a14"><span class="section-number-4">3.1.5.</span> Code</h4>
<div class="outline-text-4" id="text-3-1-5">
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">schools</span> (
schoolId SERIAL,
schoolName <span style="color: #c792ea;">VARCHAR</span>(<span style="color: #f78c6c; font-weight: bold;">50</span>),
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (schoolId)
);

<span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">teachers</span> (
teacherId SERIAL,
teacherName <span style="color: #c792ea;">VARCHAR</span>(<span style="color: #f78c6c; font-weight: bold;">30</span>),
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (teacherId)
);

<span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">courses</span> (
courseId SERIAL,
courseName <span style="color: #c792ea;">VARCHAR</span>(<span style="color: #f78c6c; font-weight: bold;">40</span>),
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (courseId)
);

<span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">rooms</span> (
roomId SERIAL,
roomName <span style="color: #c792ea;">VARCHAR</span>(<span style="color: #f78c6c; font-weight: bold;">40</span>),
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (roomId)
);

<span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">grades</span> (
gradeId SERIAL,
gradeName <span style="color: #c792ea;">VARCHAR</span>(<span style="color: #f78c6c; font-weight: bold;">15</span>),
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (gradeId)
);

<span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">publishers</span> (
publisherId SERIAL,
publisherName <span style="color: #c792ea;">VARCHAR</span>(<span style="color: #f78c6c; font-weight: bold;">30</span>),
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (publisherId)
);

<span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">books</span> (
bookId SERIAL,
bookName <span style="color: #c792ea;">VARCHAR</span>(<span style="color: #f78c6c; font-weight: bold;">60</span>),
publisherId <span style="color: #c792ea;">INT</span>,
<span style="color: #89DDFF;">FOREIGN</span> <span style="color: #89DDFF;">KEY</span> (publisherId) <span style="color: #89DDFF;">REFERENCES</span> publishers(publisherId),
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (bookId)
);

<span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">lessons</span> (
lessonId SERIAL,
schoolId <span style="color: #c792ea;">INT</span>,
teacherId <span style="color: #c792ea;">INT</span>,
courseId <span style="color: #c792ea;">INT</span>,
roomId <span style="color: #c792ea;">INT</span>,
gradeId <span style="color: #c792ea;">INT</span>,
<span style="color: #89DDFF;">FOREIGN</span> <span style="color: #89DDFF;">KEY</span> (teacherId) <span style="color: #89DDFF;">REFERENCES</span> teachers(teacherId),
<span style="color: #89DDFF;">FOREIGN</span> <span style="color: #89DDFF;">KEY</span> (courseId) <span style="color: #89DDFF;">REFERENCES</span> courses(courseId),
<span style="color: #89DDFF;">FOREIGN</span> <span style="color: #89DDFF;">KEY</span> (roomId) <span style="color: #89DDFF;">REFERENCES</span> rooms(roomId),
<span style="color: #89DDFF;">FOREIGN</span> <span style="color: #89DDFF;">KEY</span> (gradeId) <span style="color: #89DDFF;">REFERENCES</span> grades(gradeId),
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (lessonId)
);

<span style="color: #89DDFF;">CREATE</span> <span style="color: #89DDFF;">TABLE</span> <span style="color: #82aaff;">loans</span> (
loanId SERIAL,
lessonId <span style="color: #c792ea;">INT</span>,
bookId <span style="color: #c792ea;">INT</span>,
loanDate <span style="color: #c792ea;">DATE</span>,
<span style="color: #89DDFF;">FOREIGN</span> <span style="color: #89DDFF;">KEY</span> (lessonId) <span style="color: #89DDFF;">REFERENCES</span> lessons(lessonId),
<span style="color: #89DDFF;">FOREIGN</span> <span style="color: #89DDFF;">KEY</span> (bookId) <span style="color: #89DDFF;">REFERENCES</span> books(bookId),
<span style="color: #89DDFF;">PRIMARY</span> <span style="color: #89DDFF;">KEY</span> (loanId)
);

<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> schools (schoolName)
<span style="color: #89DDFF;">SELECT</span> <span style="color: #89DDFF;">DISTINCT</span> school <span style="color: #89DDFF;">FROM</span> loan_books;
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> teachers (teacherName)
<span style="color: #89DDFF;">SELECT</span> <span style="color: #89DDFF;">DISTINCT</span> teacher <span style="color: #89DDFF;">FROM</span> loan_books;
<span style="color: #676E95;">-- </span><span style="color: #676E95;">Inserted Numerical thinking 2 times because of case sensitivity. Not gonna change anything.</span>
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> courses (courseName)
<span style="color: #89DDFF;">SELECT</span> <span style="color: #89DDFF;">DISTINCT</span> course <span style="color: #89DDFF;">FROM</span> loan_books;
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> rooms (roomName)
<span style="color: #89DDFF;">SELECT</span> <span style="color: #89DDFF;">DISTINCT</span> room <span style="color: #89DDFF;">FROM</span> loan_books;
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> grades (gradeName)
<span style="color: #89DDFF;">SELECT</span> <span style="color: #89DDFF;">DISTINCT</span> grade <span style="color: #89DDFF;">FROM</span> loan_books;
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> publishers (publisherName)
<span style="color: #89DDFF;">SELECT</span> <span style="color: #89DDFF;">DISTINCT</span> publisher <span style="color: #89DDFF;">FROM</span> loan_books;
<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> books (bookName, publisherId)
<span style="color: #89DDFF;">SELECT</span> <span style="color: #89DDFF;">DISTINCT</span> loan_books.book,
publishers.publisherId <span style="color: #89DDFF;">FROM</span> loan_books
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> publishers <span style="color: #89DDFF;">ON</span>
publishers.publisherName=loan_books.publisher;

<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> lessons (schoolId, teacherId, courseId, roomId, gradeId)
<span style="color: #89DDFF;">SELECT</span> <span style="color: #89DDFF;">DISTINCT</span> schools.schoolId, teachers.teacherId,
courses.courseId, rooms.roomId, grades.gradeId <span style="color: #89DDFF;">FROM</span> loan_books
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> schools <span style="color: #89DDFF;">ON</span> schools.schoolName=loan_books.school
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> teachers <span style="color: #89DDFF;">ON</span> teachers.teacherName=loan_books.teacher
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> courses <span style="color: #89DDFF;">ON</span> courses.courseName=loan_books.course
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> rooms <span style="color: #89DDFF;">ON</span> rooms.roomName=loan_books.room
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> grades <span style="color: #89DDFF;">ON</span> grades.gradeName=loan_books.grade;

<span style="color: #89DDFF;">INSERT</span> <span style="color: #89DDFF;">INTO</span> loans (lessonId, bookId, loanDate)
<span style="color: #89DDFF;">SELECT</span> <span style="color: #89DDFF;">DISTINCT</span> lessons.lessonId, books.bookId,
loan_books.loanDate <span style="color: #89DDFF;">FROM</span> loan_books
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> schools <span style="color: #89DDFF;">ON</span> schools.schoolName=loan_books.school
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> teachers <span style="color: #89DDFF;">ON</span> teachers.teacherName=loan_books.teacher
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> courses <span style="color: #89DDFF;">ON</span> courses.courseName=loan_books.course
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> rooms <span style="color: #89DDFF;">ON</span> rooms.roomName=loan_books.room
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> grades <span style="color: #89DDFF;">ON</span> grades.gradeName=loan_books.grade
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> books <span style="color: #89DDFF;">ON</span> books.bookName=loan_books.book
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> lessons <span style="color: #89DDFF;">ON</span> lessons.gradeId=grades.gradeId
<span style="color: #89DDFF;">and</span> lessons.roomId=rooms.roomId
<span style="color: #89DDFF;">and</span> lessons.courseId=courses.courseId
<span style="color: #89DDFF;">and</span> lessons.teacherId=teachers.teacherId;
</pre>
</div>
</div>
</div>
</div>
<div id="outline-container-org7829592" class="outline-3">
<h3 id="org7829592"><span class="section-number-3">3.2.</span> Queries</h3>
<div class="outline-text-3" id="text-3-2">
<p>
The first query list all the schools that borrowed the books of every publisher using DISTINCT keyword.
The second query orders the results from each school, and takes only 1 loan that has the highest loanDate for each school.
</p>
<div class="org-src-container">
<pre class="src src-sql"><span style="color: #89DDFF;">SELECT</span> <span style="color: #89DDFF;">DISTINCT</span> publishers.publisherName, books.bookName,
schools.schoolName <span style="color: #89DDFF;">FROM</span> books
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> loans <span style="color: #89DDFF;">ON</span> loans.bookId=books.bookId
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> lessons <span style="color: #89DDFF;">ON</span> lessons.lessonId=loans.lessonId
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> schools <span style="color: #89DDFF;">ON</span> schools.schoolId=lessons.schoolId
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> publishers <span style="color: #89DDFF;">ON</span> publishers.publisherId=books.publisherId
<span style="color: #89DDFF;">ORDER</span> <span style="color: #89DDFF;">BY</span> publishers.publisherName;

<span style="color: #89DDFF;">SELECT</span> <span style="color: #89DDFF;">DISTINCT</span> <span style="color: #89DDFF;">ON</span> (schools.schoolName) schools.schoolName,
publishers.publisherName, books.bookName <span style="color: #89DDFF;">FROM</span> loans
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> lessons <span style="color: #89DDFF;">ON</span> lessons.lessonId=loans.lessonId
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> schools <span style="color: #89DDFF;">ON</span> schools.schoolId=lessons.schoolId
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> books <span style="color: #89DDFF;">ON</span> books.bookId=loans.bookId
<span style="color: #89DDFF;">INNER</span> <span style="color: #89DDFF;">JOIN</span> publishers <span style="color: #89DDFF;">ON</span> publishers.publisherId=books.publisherId
<span style="color: #89DDFF;">ORDER</span> <span style="color: #89DDFF;">BY</span> schools.schoolName, loans.loanDate <span style="color: #89DDFF;">DESC</span>, <span style="color: #f78c6c; font-weight: bold;">1</span>;
</pre>
</div>
</div>
</div>
</div>
</div>
<div id="postamble" class="status">
<p class="author">Author: Amirlan Sharipov (BS-CS21-01)</p>
<p class="date">Created: 2023-02-28 Tue 23:48</p>
</div>
</body>
</html>

+ 237
- 0
week06/lab6.org View File

@@ -0,0 +1,237 @@
#+title: Lab 6 Amirlan Sharipov (BS-CS21-01)
#+author: Amirlan Sharipov (BS-CS21-01)

* Exercise 1
** Table creation and insertion
I used the schema provided in the slides. And then manually inserted data into the tables.

#+begin_src sql
CREATE TABLE customers (
customerId INT,
customerName VARCHAR(50),
city VARCHAR(50),
PRIMARY KEY (customerId)
);

CREATE TABLE items (
itemId INT,
itemName VARCHAR(50),
price FLOAT,
PRIMARY KEY (itemId)
);

CREATE TABLE orders (
orderId INT,
customerId INT,
date DATE,
FOREIGN KEY (customerId) REFERENCES customers(customerId),
PRIMARY KEY (orderId)
);

CREATE TABLE order_details (
orderId INT,
itemId INT,
quantity INT,
FOREIGN KEY (itemId) REFERENCES items(itemId),
PRIMARY KEY (orderId, itemId)
);

INSERT INTO customers VALUES('101', 'Martin', 'Prague');
INSERT INTO customers VALUES('107', 'Herman', 'Madrid');
INSERT INTO customers VALUES('110', 'Pedro', 'Moscow');

INSERT INTO items VALUES('3786', 'Net', 35.0);
INSERT INTO items VALUES('4011', 'Racket', 65.0);
INSERT INTO items VALUES('9132', 'Pack-3', 4.75);
INSERT INTO items VALUES('5794', 'Pack-6', 5.0);
INSERT INTO items VALUES('3141', 'Cover', 10.0);

INSERT INTO orders VALUES('2301', '101', '2011-02-23');
INSERT INTO orders VALUES('2302', '107', '2011-02-25');
INSERT INTO orders VALUES('2303', '110', '2011-02-27');

INSERT INTO order_details VALUES ('2301', '3786', 3);
INSERT INTO order_details VALUES ('2301', '4011', 6);
INSERT INTO order_details VALUES ('2301', '9132', 8);
INSERT INTO order_details VALUES ('2302', '5794', 4);
INSERT INTO order_details VALUES ('2303', '4011', 2);
INSERT INTO order_details VALUES ('2303', '3141', 2);
#+end_src

** Queries
First query takes the sum of all prices * quantities groupped by the orders and sorts them.
The second query does the same thing, groups by customers, sorts by sum of quantities (descending order) and takes the first result.
#+begin_src sql
SELECT order_details.orderId, SUM(items.price * order_details.quantity)
FROM order_details
INNER JOIN items on items.itemId=order_details.itemId
group by order_details.orderId ORDER BY sum ASC;

SELECT customers.customerName, customers.city FROM customers
INNER JOIN orders ON customers.customerId=orders.customerId
INNER JOIN order_details ON order_details.orderId=orders.orderId
GROUP BY customers.customerId
ORDER BY SUM(order_details.quantity) DESC
LIMIT 1;
#+end_src

* Exercise 2
** Normalization
I have several assumptions:
- Any teacher can work at several schools at once (or change the school)
- Room numbers don't depend on schools: the first number of the room name is not enough to assume the opposite
- Teachers may teach several courses: it's an elementary school, usually teachers can teach anything in elementary schools

*** 1NF
It's almost in 1NF state. Each cell is already atomic, values of the same domain, etc. The only thing that's not there is the primary key. Let's say for now that the primary key is a tuple of school, teacher, course, room, grade, and book. This way there are no conflicts. It still looks like a mess, so I will normalize it further.
*** 2NF
Make new tables with relations for partial functional dependencies of non-prime attributes on candidate keys:
- lessons (lessonId, schoolName, teacherName, courseName, roomName, gradeName)
- books (bookId, bookName, publisherName)
- loans (loanId, lessonId, bookId, loanDate)
*** 3NF
Make new tables (with appropriate IDs) with relations for transitive functional dependencies of non-prime attribute on candidate key:
- schools (schoolId, schoolName)
- teachers (teacherId, teacherName)
- courses (courseId, courseName)
- rooms (roomId, roomName)
- grades (gradeId, gradeName)
- publishers (publisherId, publisherName)
- lessons (lessonId, schoolId, teacherId, courseId, roomId, gradeId)
- books (bookId, bookName, publisherId)
- loans (loanId, lessonId, bookId, loanDate)
*** BCNF and 4NF
Already satisfies.

*** Code
#+begin_src sql
CREATE TABLE schools (
schoolId SERIAL,
schoolName VARCHAR(50),
PRIMARY KEY (schoolId)
);

CREATE TABLE teachers (
teacherId SERIAL,
teacherName VARCHAR(30),
PRIMARY KEY (teacherId)
);

CREATE TABLE courses (
courseId SERIAL,
courseName VARCHAR(40),
PRIMARY KEY (courseId)
);

CREATE TABLE rooms (
roomId SERIAL,
roomName VARCHAR(40),
PRIMARY KEY (roomId)
);

CREATE TABLE grades (
gradeId SERIAL,
gradeName VARCHAR(15),
PRIMARY KEY (gradeId)
);

CREATE TABLE publishers (
publisherId SERIAL,
publisherName VARCHAR(30),
PRIMARY KEY (publisherId)
);

CREATE TABLE books (
bookId SERIAL,
bookName VARCHAR(60),
publisherId INT,
FOREIGN KEY (publisherId) REFERENCES publishers(publisherId),
PRIMARY KEY (bookId)
);

CREATE TABLE lessons (
lessonId SERIAL,
schoolId INT,
teacherId INT,
courseId INT,
roomId INT,
gradeId INT,
FOREIGN KEY (teacherId) REFERENCES teachers(teacherId),
FOREIGN KEY (courseId) REFERENCES courses(courseId),
FOREIGN KEY (roomId) REFERENCES rooms(roomId),
FOREIGN KEY (gradeId) REFERENCES grades(gradeId),
PRIMARY KEY (lessonId)
);

CREATE TABLE loans (
loanId SERIAL,
lessonId INT,
bookId INT,
loanDate DATE,
FOREIGN KEY (lessonId) REFERENCES lessons(lessonId),
FOREIGN KEY (bookId) REFERENCES books(bookId),
PRIMARY KEY (loanId)
);

INSERT INTO schools (schoolName)
SELECT DISTINCT school FROM loan_books;
INSERT INTO teachers (teacherName)
SELECT DISTINCT teacher FROM loan_books;
-- Inserted Numerical thinking 2 times because of case sensitivity. Not gonna change anything.
INSERT INTO courses (courseName)
SELECT DISTINCT course FROM loan_books;
INSERT INTO rooms (roomName)
SELECT DISTINCT room FROM loan_books;
INSERT INTO grades (gradeName)
SELECT DISTINCT grade FROM loan_books;
INSERT INTO publishers (publisherName)
SELECT DISTINCT publisher FROM loan_books;
INSERT INTO books (bookName, publisherId)
SELECT DISTINCT loan_books.book,
publishers.publisherId FROM loan_books
INNER JOIN publishers ON
publishers.publisherName=loan_books.publisher;

INSERT INTO lessons (schoolId, teacherId, courseId, roomId, gradeId)
SELECT DISTINCT schools.schoolId, teachers.teacherId,
courses.courseId, rooms.roomId, grades.gradeId FROM loan_books
INNER JOIN schools ON schools.schoolName=loan_books.school
INNER JOIN teachers ON teachers.teacherName=loan_books.teacher
INNER JOIN courses ON courses.courseName=loan_books.course
INNER JOIN rooms ON rooms.roomName=loan_books.room
INNER JOIN grades ON grades.gradeName=loan_books.grade;

INSERT INTO loans (lessonId, bookId, loanDate)
SELECT DISTINCT lessons.lessonId, books.bookId,
loan_books.loanDate FROM loan_books
INNER JOIN schools ON schools.schoolName=loan_books.school
INNER JOIN teachers ON teachers.teacherName=loan_books.teacher
INNER JOIN courses ON courses.courseName=loan_books.course
INNER JOIN rooms ON rooms.roomName=loan_books.room
INNER JOIN grades ON grades.gradeName=loan_books.grade
INNER JOIN books ON books.bookName=loan_books.book
INNER JOIN lessons ON lessons.gradeId=grades.gradeId
and lessons.roomId=rooms.roomId
and lessons.courseId=courses.courseId
and lessons.teacherId=teachers.teacherId;
#+end_src
** Queries
The first query list all the schools that borrowed the books of every publisher using DISTINCT keyword.
The second query orders the results from each school, and takes only 1 loan that has the highest loanDate for each school.
#+begin_src sql
SELECT DISTINCT publishers.publisherName, books.bookName,
schools.schoolName FROM books
INNER JOIN loans ON loans.bookId=books.bookId
INNER JOIN lessons ON lessons.lessonId=loans.lessonId
INNER JOIN schools ON schools.schoolId=lessons.schoolId
INNER JOIN publishers ON publishers.publisherId=books.publisherId
ORDER BY publishers.publisherName;

SELECT DISTINCT ON (schools.schoolName) schools.schoolName,
publishers.publisherName, books.bookName FROM loans
INNER JOIN lessons ON lessons.lessonId=loans.lessonId
INNER JOIN schools ON schools.schoolId=lessons.schoolId
INNER JOIN books ON books.bookId=loans.bookId
INNER JOIN publishers ON publishers.publisherId=books.publisherId
ORDER BY schools.schoolName, loans.loanDate DESC, 1;
#+end_src

BIN
week06/lab6.pdf View File


+ 197
- 0
week06/lab6.sql View File

@@ -0,0 +1,197 @@
-- EXERCISE 1
-- I inserted everything manually

CREATE TABLE customers (
customerId INT,
customerName VARCHAR(50),
city VARCHAR(50),
PRIMARY KEY (customerId)
);

CREATE TABLE items (
itemId INT,
itemName VARCHAR(50),
price FLOAT,
PRIMARY KEY (itemId)
);

CREATE TABLE orders (
orderId INT,
customerId INT,
date DATE,
FOREIGN KEY (customerId) REFERENCES customers(customerId),
PRIMARY KEY (orderId)
);

CREATE TABLE order_details (
orderId INT,
itemId INT,
quantity INT,
FOREIGN KEY (itemId) REFERENCES items(itemId),
PRIMARY KEY (orderId, itemId)
);

INSERT INTO customers VALUES('101', 'Martin', 'Prague');
INSERT INTO customers VALUES('107', 'Herman', 'Madrid');
INSERT INTO customers VALUES('110', 'Pedro', 'Moscow');

INSERT INTO items VALUES('3786', 'Net', 35.0);
INSERT INTO items VALUES('4011', 'Racket', 65.0);
INSERT INTO items VALUES('9132', 'Pack-3', 4.75);
INSERT INTO items VALUES('5794', 'Pack-6', 5.0);
INSERT INTO items VALUES('3141', 'Cover', 10.0);

INSERT INTO orders VALUES('2301', '101', '2011-02-23');
INSERT INTO orders VALUES('2302', '107', '2011-02-25');
INSERT INTO orders VALUES('2303', '110', '2011-02-27');

INSERT INTO order_details VALUES ('2301', '3786', 3);
INSERT INTO order_details VALUES ('2301', '4011', 6);
INSERT INTO order_details VALUES ('2301', '9132', 8);
INSERT INTO order_details VALUES ('2302', '5794', 4);
INSERT INTO order_details VALUES ('2303', '4011', 2);
INSERT INTO order_details VALUES ('2303', '3141', 2);

SELECT order_details.orderId, SUM(items.price * order_details.quantity)
FROM order_details
INNER JOIN items on items.itemId=order_details.itemId
group by order_details.orderId ORDER BY sum ASC;


SELECT customers.customerName, customers.city FROM customers
INNER JOIN orders ON customers.customerId=orders.customerId
INNER JOIN order_details ON order_details.orderId=orders.orderId
GROUP BY customers.customerId
ORDER BY SUM(order_details.quantity) DESC
LIMIT 1;

-- Exercise 2
-- Automated insert

CREATE TABLE loan_books
(school VARCHAR(50),
teacher VARCHAR(30),
course VARCHAR(40),
room VARCHAR(10),
grade VARCHAR(15),
book VARCHAR(60),
publisher VARCHAR(30),
loanDate DATE,
PRIMARY KEY (school, teacher, course)
);
INSERT INTO loan_books VALUES ('Horizon Education Institute', 'Chad Russell', 'Logical Thinking', '1.A01', '1st grade', 'Learning and teaching in early childhood education', 'BOA Editions', '2010-09-09');
INSERT INTO loan_books VALUES ('Horizon Education Institute', 'Chad Russell', 'Writing', '1.A01', '1st grade', 'Preschool, N56', 'Taylor & Francis Publishing', '2010-05-05');
INSERT INTO loan_books VALUES ('Horizon Education Institute', 'Chad Russell', 'Numerical thinking', '1.A01', '1st grade', 'Learning and teaching in early childhood education', 'BOA Editions', '2010-05-05');
INSERT INTO loan_books VALUES ('Horizon Education Institute', 'E.F.Codd', 'Spatial, Temporal and Causal Thinking', '1.B01', '1st grade', 'Early Childhood Education N9', 'Prentice Hall', '2010-05-06');
INSERT INTO loan_books VALUES ('Horizon Education Institute', 'E.F.Codd', 'Numerical thinking', '1.B01', '1st grade', 'Learning and teaching in early childhood education', 'BOA Editions', '2010-05-06');
INSERT INTO loan_books VALUES ('Horizon Education Institute', 'Jones Smith', 'Writing', '1.A01', '2nd grade', 'Learning and teaching in early childhood education', 'BOA Editions', '2010-09-09');
INSERT INTO loan_books VALUES ('Horizon Education Institute', 'Jones Smith', 'English', '1.A01', '2nd grade', 'Know how to educate: guide for Parents and Teachers', 'McGraw Hill', '2010-05-05');
INSERT INTO loan_books VALUES ('Bright Institution', 'Adam Baker', 'Logical Thinking', '2.B01', '1st grade', 'Know how to educate: guide for Parents and Teachers', 'McGraw Hill', '2010-12-18');
INSERT INTO loan_books VALUES ('Bright Institution', 'Adam Baker', 'Numerical Thinking', '2.B01', '1st grade', 'Learning and teaching in early childhood education', 'BOA Editions', '2010-05-06');

CREATE TABLE schools (
schoolId SERIAL,
schoolName VARCHAR(50),
PRIMARY KEY (schoolId)
);

CREATE TABLE teachers (
teacherId SERIAL,
teacherName VARCHAR(30),
PRIMARY KEY (teacherId)
);

CREATE TABLE courses (
courseId SERIAL,
courseName VARCHAR(40),
PRIMARY KEY (courseId)
);

CREATE TABLE rooms (
roomId SERIAL,
roomName VARCHAR(40),
PRIMARY KEY (roomId)
);

CREATE TABLE grades (
gradeId SERIAL,
gradeName VARCHAR(15),
PRIMARY KEY (gradeId)
);

CREATE TABLE publishers (
publisherId SERIAL,
publisherName VARCHAR(30),
PRIMARY KEY (publisherId)
);

CREATE TABLE books (
bookId SERIAL,
bookName VARCHAR(60),
publisherId INT,
FOREIGN KEY (publisherId) REFERENCES publishers(publisherId),
PRIMARY KEY (bookId)
);

CREATE TABLE lessons (
lessonId SERIAL,
schoolId INT,
teacherId INT,
courseId INT,
roomId INT,
gradeId INT,
FOREIGN KEY (teacherId) REFERENCES teachers(teacherId),
FOREIGN KEY (courseId) REFERENCES courses(courseId),
FOREIGN KEY (roomId) REFERENCES rooms(roomId),
FOREIGN KEY (gradeId) REFERENCES grades(gradeId),
PRIMARY KEY (lessonId)
);

CREATE TABLE loans (
loanId SERIAL,
lessonId INT,
bookId INT,
loanDate DATE,
FOREIGN KEY (lessonId) REFERENCES lessons(lessonId),
FOREIGN KEY (bookId) REFERENCES books(bookId),
PRIMARY KEY (loanId)
);

INSERT INTO schools (schoolName) SELECT DISTINCT school FROM loan_books;
INSERT INTO teachers (teacherName) SELECT DISTINCT teacher FROM loan_books;
INSERT INTO courses (courseName) SELECT DISTINCT course FROM loan_books; -- Inserted Numerical thinking 2 times because of case sensitivity. Not gonna change anything.
INSERT INTO rooms (roomName) SELECT DISTINCT room FROM loan_books;
INSERT INTO grades (gradeName) SELECT DISTINCT grade FROM loan_books;
INSERT INTO publishers (publisherName) SELECT DISTINCT publisher FROM loan_books;
INSERT INTO books (bookName, publisherId) SELECT DISTINCT loan_books.book, publishers.publisherId FROM loan_books INNER JOIN publishers ON publishers.publisherName=loan_books.publisher;

INSERT INTO lessons (schoolId, teacherId, courseId, roomId, gradeId) SELECT DISTINCT schools.schoolId, teachers.teacherId, courses.courseId, rooms.roomId, grades.gradeId FROM loan_books
INNER JOIN schools ON schools.schoolName=loan_books.school
INNER JOIN teachers ON teachers.teacherName=loan_books.teacher
INNER JOIN courses ON courses.courseName=loan_books.course
INNER JOIN rooms ON rooms.roomName=loan_books.room
INNER JOIN grades ON grades.gradeName=loan_books.grade;

INSERT INTO loans (lessonId, bookId, loanDate) SELECT DISTINCT lessons.lessonId, books.bookId, loan_books.loanDate FROM loan_books
INNER JOIN schools ON schools.schoolName=loan_books.school
INNER JOIN teachers ON teachers.teacherName=loan_books.teacher
INNER JOIN courses ON courses.courseName=loan_books.course
INNER JOIN rooms ON rooms.roomName=loan_books.room
INNER JOIN grades ON grades.gradeName=loan_books.grade
INNER JOIN books ON books.bookName=loan_books.book
INNER JOIN lessons ON lessons.gradeId=grades.gradeId and lessons.roomId=rooms.roomId and lessons.courseId=courses.courseId and lessons.teacherId=teachers.teacherId;

SELECT DISTINCT publishers.publisherName, books.bookName, schools.schoolName FROM books
INNER JOIN loans ON loans.bookId=books.bookId
INNER JOIN lessons ON lessons.lessonId=loans.lessonId
INNER JOIN schools ON schools.schoolId=lessons.schoolId
INNER JOIN publishers ON publishers.publisherId=books.publisherId
ORDER BY publishers.publisherName;

SELECT DISTINCT ON (schools.schoolName) schools.schoolName, publishers.publisherName, books.bookName, loans.loanDate FROM loans
INNER JOIN lessons ON lessons.lessonId=loans.lessonId
INNER JOIN schools ON schools.schoolId=lessons.schoolId
INNER JOIN books ON books.bookId=loans.bookId
INNER JOIN publishers ON publishers.publisherId=books.publisherId
ORDER BY schools.schoolName, loans.loanDate DESC, 1;

+ 286
- 0
week06/lab6.tex View File

@@ -0,0 +1,286 @@
% Created 2023-02-28 Tue 23:48
% Intended LaTeX compiler: pdflatex
\documentclass[11pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{graphicx}
\usepackage{longtable}
\usepackage{wrapfig}
\usepackage{rotating}
\usepackage[normalem]{ulem}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{capt-of}
\usepackage{hyperref}
\author{Amirlan Sharipov (BS-CS21-01)}
\date{\today}
\title{Lab 6 Amirlan Sharipov (BS-CS21-01)}
\hypersetup{
pdfauthor={Amirlan Sharipov (BS-CS21-01)},
pdftitle={Lab 6 Amirlan Sharipov (BS-CS21-01)},
pdfkeywords={},
pdfsubject={},
pdfcreator={Emacs 28.2 (Org mode 9.6)},
pdflang={English}}
\begin{document}

\maketitle
\tableofcontents


\section{Disclaimer}
\label{sec:orgd9c7526}
Please, use the lab6.sql file to read/copy the source code. Also, the html version of this document looks better than the pdf one.

\section{Exercise 1}
\label{sec:orgbb19d8e}
\subsection{Table creation and insertion}
\label{sec:orge2ed6dc}
I used the schema provided in the slides. And then manually inserted data into the tables.

\begin{verbatim}
CREATE TABLE customers (
customerId INT,
customerName VARCHAR(50),
city VARCHAR(50),
PRIMARY KEY (customerId)
);

CREATE TABLE items (
itemId INT,
itemName VARCHAR(50),
price FLOAT,
PRIMARY KEY (itemId)
);

CREATE TABLE orders (
orderId INT,
customerId INT,
date DATE,
FOREIGN KEY (customerId) REFERENCES customers(customerId),
PRIMARY KEY (orderId)
);

CREATE TABLE order_details (
orderId INT,
itemId INT,
quantity INT,
FOREIGN KEY (itemId) REFERENCES items(itemId),
PRIMARY KEY (orderId, itemId)
);

INSERT INTO customers VALUES('101', 'Martin', 'Prague');
INSERT INTO customers VALUES('107', 'Herman', 'Madrid');
INSERT INTO customers VALUES('110', 'Pedro', 'Moscow');

INSERT INTO items VALUES('3786', 'Net', 35.0);
INSERT INTO items VALUES('4011', 'Racket', 65.0);
INSERT INTO items VALUES('9132', 'Pack-3', 4.75);
INSERT INTO items VALUES('5794', 'Pack-6', 5.0);
INSERT INTO items VALUES('3141', 'Cover', 10.0);

INSERT INTO orders VALUES('2301', '101', '2011-02-23');
INSERT INTO orders VALUES('2302', '107', '2011-02-25');
INSERT INTO orders VALUES('2303', '110', '2011-02-27');

INSERT INTO order_details VALUES ('2301', '3786', 3);
INSERT INTO order_details VALUES ('2301', '4011', 6);
INSERT INTO order_details VALUES ('2301', '9132', 8);
INSERT INTO order_details VALUES ('2302', '5794', 4);
INSERT INTO order_details VALUES ('2303', '4011', 2);
INSERT INTO order_details VALUES ('2303', '3141', 2);
\end{verbatim}

\subsection{Queries}
\label{sec:org4f468b3}
First query takes the sum of all prices * quantities groupped by the orders and sorts them.
The second query does the same thing, groups by customers, sorts by sum of quantities (descending order) and takes the first result.
\begin{verbatim}
SELECT order_details.orderId, SUM(items.price * order_details.quantity)
FROM order_details
INNER JOIN items on items.itemId=order_details.itemId
group by order_details.orderId ORDER BY sum ASC;

SELECT customers.customerName, customers.city FROM customers
INNER JOIN orders ON customers.customerId=orders.customerId
INNER JOIN order_details ON order_details.orderId=orders.orderId
GROUP BY customers.customerId
ORDER BY SUM(order_details.quantity) DESC
LIMIT 1;
\end{verbatim}

\section{Exercise 2}
\label{sec:org99a84d3}
\subsection{Normalization}
\label{sec:org77cd4b4}
I have several assumptions:
\begin{itemize}
\item Any teacher can work at several schools at once (or change the school)
\item Room numbers don't depend on schools: the first number of the room name is not enough to assume the opposite
\item Teachers may teach several courses: it's an elementary school, usually teachers can teach anything in elementary schools
\end{itemize}

\subsubsection{1NF}
\label{sec:org4242f0d}
It's almost in 1NF state. Each cell is already atomic, values of the same domain, etc. The only thing that's not there is the primary key. Let's say for now that the primary key is a tuple of school, teacher, course, room, grade, and book. This way there are no conflicts. It still looks like a mess, so I will normalize it further.
\subsubsection{2NF}
\label{sec:orge350be8}
Make new tables with relations for partial functional dependencies of non-prime attributes on candidate keys:
\begin{itemize}
\item lessons (lessonId, schoolName, teacherName, courseName, roomName, gradeName)
\item books (bookId, bookName, publisherName)
\item loans (loanId, lessonId, bookId, loanDate)
\end{itemize}
\subsubsection{3NF}
\label{sec:org627722d}
Make new tables (with appropriate IDs) with relations for transitive functional dependencies of non-prime attribute on candidate key:
\begin{itemize}
\item schools (schoolId, schoolName)
\item teachers (teacherId, teacherName)
\item courses (courseId, courseName)
\item rooms (roomId, roomName)
\item grades (gradeId, gradeName)
\item publishers (publisherId, publisherName)
\item lessons (lessonId, schoolId, teacherId, courseId, roomId, gradeId)
\item books (bookId, bookName, publisherId)
\item loans (loanId, lessonId, bookId, loanDate)
\end{itemize}
\subsubsection{BCNF and 4NF}
\label{sec:org00e5b2a}
Already satisfies.

\subsubsection{Code}
\label{sec:org3de05cf}
\begin{verbatim}
CREATE TABLE schools (
schoolId SERIAL,
schoolName VARCHAR(50),
PRIMARY KEY (schoolId)
);

CREATE TABLE teachers (
teacherId SERIAL,
teacherName VARCHAR(30),
PRIMARY KEY (teacherId)
);

CREATE TABLE courses (
courseId SERIAL,
courseName VARCHAR(40),
PRIMARY KEY (courseId)
);

CREATE TABLE rooms (
roomId SERIAL,
roomName VARCHAR(40),
PRIMARY KEY (roomId)
);

CREATE TABLE grades (
gradeId SERIAL,
gradeName VARCHAR(15),
PRIMARY KEY (gradeId)
);

CREATE TABLE publishers (
publisherId SERIAL,
publisherName VARCHAR(30),
PRIMARY KEY (publisherId)
);

CREATE TABLE books (
bookId SERIAL,
bookName VARCHAR(60),
publisherId INT,
FOREIGN KEY (publisherId) REFERENCES publishers(publisherId),
PRIMARY KEY (bookId)
);

CREATE TABLE lessons (
lessonId SERIAL,
schoolId INT,
teacherId INT,
courseId INT,
roomId INT,
gradeId INT,
FOREIGN KEY (teacherId) REFERENCES teachers(teacherId),
FOREIGN KEY (courseId) REFERENCES courses(courseId),
FOREIGN KEY (roomId) REFERENCES rooms(roomId),
FOREIGN KEY (gradeId) REFERENCES grades(gradeId),
PRIMARY KEY (lessonId)
);

CREATE TABLE loans (
loanId SERIAL,
lessonId INT,
bookId INT,
loanDate DATE,
FOREIGN KEY (lessonId) REFERENCES lessons(lessonId),
FOREIGN KEY (bookId) REFERENCES books(bookId),
PRIMARY KEY (loanId)
);

INSERT INTO schools (schoolName)
SELECT DISTINCT school FROM loan_books;
INSERT INTO teachers (teacherName)
SELECT DISTINCT teacher FROM loan_books;
-- Inserted Numerical thinking 2 times because of case sensitivity. Not gonna change anything.
INSERT INTO courses (courseName)
SELECT DISTINCT course FROM loan_books;
INSERT INTO rooms (roomName)
SELECT DISTINCT room FROM loan_books;
INSERT INTO grades (gradeName)
SELECT DISTINCT grade FROM loan_books;
INSERT INTO publishers (publisherName)
SELECT DISTINCT publisher FROM loan_books;
INSERT INTO books (bookName, publisherId)
SELECT DISTINCT loan_books.book,
publishers.publisherId FROM loan_books
INNER JOIN publishers ON
publishers.publisherName=loan_books.publisher;

INSERT INTO lessons (schoolId, teacherId, courseId, roomId, gradeId)
SELECT DISTINCT schools.schoolId, teachers.teacherId,
courses.courseId, rooms.roomId, grades.gradeId FROM loan_books
INNER JOIN schools ON schools.schoolName=loan_books.school
INNER JOIN teachers ON teachers.teacherName=loan_books.teacher
INNER JOIN courses ON courses.courseName=loan_books.course
INNER JOIN rooms ON rooms.roomName=loan_books.room
INNER JOIN grades ON grades.gradeName=loan_books.grade;

INSERT INTO loans (lessonId, bookId, loanDate)
SELECT DISTINCT lessons.lessonId, books.bookId,
loan_books.loanDate FROM loan_books
INNER JOIN schools ON schools.schoolName=loan_books.school
INNER JOIN teachers ON teachers.teacherName=loan_books.teacher
INNER JOIN courses ON courses.courseName=loan_books.course
INNER JOIN rooms ON rooms.roomName=loan_books.room
INNER JOIN grades ON grades.gradeName=loan_books.grade
INNER JOIN books ON books.bookName=loan_books.book
INNER JOIN lessons ON lessons.gradeId=grades.gradeId
and lessons.roomId=rooms.roomId
and lessons.courseId=courses.courseId
and lessons.teacherId=teachers.teacherId;
\end{verbatim}
\subsection{Queries}
\label{sec:org917674e}
The first query list all the schools that borrowed the books of every publisher using DISTINCT keyword.
The second query orders the results from each school, and takes only 1 loan that has the highest loanDate for each school.
\begin{verbatim}
SELECT DISTINCT publishers.publisherName, books.bookName,
schools.schoolName FROM books
INNER JOIN loans ON loans.bookId=books.bookId
INNER JOIN lessons ON lessons.lessonId=loans.lessonId
INNER JOIN schools ON schools.schoolId=lessons.schoolId
INNER JOIN publishers ON publishers.publisherId=books.publisherId
ORDER BY publishers.publisherName;

SELECT DISTINCT ON (schools.schoolName) schools.schoolName,
publishers.publisherName, books.bookName FROM loans
INNER JOIN lessons ON lessons.lessonId=loans.lessonId
INNER JOIN schools ON schools.schoolId=lessons.schoolId
INNER JOIN books ON books.bookId=loans.bookId
INNER JOIN publishers ON publishers.publisherId=books.publisherId
ORDER BY schools.schoolName, loans.loanDate DESC, 1;
\end{verbatim}
\end{document}

Loading…
Cancel
Save