diff --git a/Week2/assigments/aggregateFunctions.js b/Week2/assigments/aggregateFunctions.js new file mode 100644 index 000000000..0e6e3391a --- /dev/null +++ b/Week2/assigments/aggregateFunctions.js @@ -0,0 +1,69 @@ +import { client } from './database.js'; + +async function exercise4Aggregates() { + try { + await client.connect(); + + const papersCountQuery = ` + SELECT rp.paper_title, + COUNT(ap.author_id) AS author_count + FROM research_papers AS rp + LEFT JOIN author_paper AS ap + ON rp.paper_id = ap.paper_id + GROUP BY rp.paper_title + ORDER BY rp.paper_title; + `; + const papersCountResult = await client.query(papersCountQuery); + console.table(papersCountResult.rows); + + const femalePapersQuery = ` + SELECT COUNT(ap.paper_id) AS total_papers_by_female_authors + FROM authors AS a + JOIN author_paper AS ap + ON a.author_id = ap.author_id + WHERE a.gender = 'Female'; + `; + const femalePapersResult = await client.query(femalePapersQuery); + console.table(femalePapersResult.rows); + + const avgHIndexQuery = ` + SELECT a.university, + AVG(a.h_index) AS avg_h_index + FROM authors AS a + GROUP BY a.university + ORDER BY a.university; + `; + const avgHIndexResult = await client.query(avgHIndexQuery); + console.table(avgHIndexResult.rows); + + const papersByUniversityQuery = ` + SELECT a.university, + COUNT(ap.paper_id) AS total_papers + FROM authors AS a + LEFT JOIN author_paper AS ap + ON a.author_id = ap.author_id + GROUP BY a.university + ORDER BY a.university; + `; + const papersByUniversityResult = await client.query(papersByUniversityQuery); + console.table(papersByUniversityResult.rows); + + const hIndexMinMaxQuery = ` + SELECT a.university, + MIN(a.h_index) AS min_h_index, + MAX(a.h_index) AS max_h_index + FROM authors AS a + GROUP BY a.university + ORDER BY a.university; + `; + const hIndexMinMaxResult = await client.query(hIndexMinMaxQuery); + console.table(hIndexMinMaxResult.rows); + + } catch (error) { + console.error("Error:", error); + } finally { + await client.end(); + } +} + +exercise4Aggregates(); diff --git a/Week2/assigments/database.js b/Week2/assigments/database.js new file mode 100644 index 000000000..384d21b0b --- /dev/null +++ b/Week2/assigments/database.js @@ -0,0 +1,10 @@ +import pkg from 'pg'; +const { Client } = pkg; + +export const client = new Client({ + user: 'hyfuser', + host: 'localhost', + database: 'authors_db', + password: 'hyfpassword', + port: 5432, +}); \ No newline at end of file diff --git a/Week2/assigments/joins.js b/Week2/assigments/joins.js new file mode 100644 index 000000000..cdf3f8b05 --- /dev/null +++ b/Week2/assigments/joins.js @@ -0,0 +1,36 @@ +import { client } from './database.js'; + +async function exercise3Joins() { + try { + await client.connect(); + + const mentorQuery = ` + SELECT a.author_name AS author, + m.author_name AS mentor + FROM authors a + LEFT JOIN authors m ON a.mentor = m.author_id + ORDER BY a.author_id; + `; + const mentorResult = await client.query(mentorQuery); + console.log("Authors and their mentors:"); + console.table(mentorResult.rows); + + const papersQuery = ` + SELECT a.*, rp.paper_title + FROM authors a + LEFT JOIN author_paper ap ON a.author_id = ap.author_id + LEFT JOIN research_papers rp ON ap.paper_id = rp.paper_id + ORDER BY a.author_id, rp.paper_id; + `; + const papersResult = await client.query(papersQuery); + console.log("Authors and their papers:"); + console.table(papersResult.rows); + + } catch (error) { + console.error("Error:", error); + } finally { + await client.end(); + } +} + +exercise3Joins(); diff --git a/Week2/assigments/key.js b/Week2/assigments/key.js new file mode 100644 index 000000000..b573fa5cd --- /dev/null +++ b/Week2/assigments/key.js @@ -0,0 +1,41 @@ +import { client } from './database.js'; + +async function setupAuthorsTable() { + try { + await client.connect(); + + const sql = ` + DROP TABLE IF EXISTS author_paper CASCADE; + DROP TABLE IF EXISTS research_papers CASCADE; + DROP TABLE IF EXISTS authors CASCADE; + + CREATE TABLE authors + ( + author_id SERIAL PRIMARY KEY, + author_name VARCHAR(255), + university VARCHAR(255), + date_of_birth DATE, + h_index INT, + gender VARCHAR(10) + ); + + ALTER TABLE authors + ADD COLUMN mentor INT; + + ALTER TABLE authors + ADD CONSTRAINT fk_mentor + FOREIGN KEY (mentor) + REFERENCES authors (author_id) + ON DELETE SET NULL; + `; + + await client.query(sql); + console.log('Authors table created'); + } catch (err) { + console.error('Problem creating authors table', err); + } finally { + await client.end(); + } +} + +setupAuthorsTable(); diff --git a/Week2/assigments/package-lock.json b/Week2/assigments/package-lock.json new file mode 100644 index 000000000..4cad5d8f3 --- /dev/null +++ b/Week2/assigments/package-lock.json @@ -0,0 +1,162 @@ +{ + "name": "assigments", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "assigments", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "pg": "^8.16.3" + } + }, + "node_modules/pg": { + "version": "8.16.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", + "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.9.1", + "pg-pool": "^3.10.1", + "pg-protocol": "^1.10.3", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.2.7" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz", + "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz", + "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz", + "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/Week2/assigments/package.json b/Week2/assigments/package.json new file mode 100644 index 000000000..586f64e6c --- /dev/null +++ b/Week2/assigments/package.json @@ -0,0 +1,16 @@ +{ + "name": "assigments", + "type": "module", + "version": "1.0.0", + "description": "", + "main": "database.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "pg": "^8.16.3" + } +} diff --git a/Week2/assigments/relationships.js b/Week2/assigments/relationships.js new file mode 100644 index 000000000..b917ea731 --- /dev/null +++ b/Week2/assigments/relationships.js @@ -0,0 +1,155 @@ +import { client } from './database.js'; + +async function setupDatabase() { + try { + await client.connect(); + + + await client.query(` + DROP TABLE IF EXISTS author_paper CASCADE; + DROP TABLE IF EXISTS research_papers CASCADE; + DROP TABLE IF EXISTS authors CASCADE; + `); + + await client.query(` + CREATE TABLE authors + ( + author_id SERIAL PRIMARY KEY, + author_name VARCHAR(255) UNIQUE, + university VARCHAR(255), + date_of_birth DATE, + h_index INT, + gender VARCHAR(10), + mentor INT, + CONSTRAINT fk_mentor FOREIGN KEY (mentor) + REFERENCES authors (author_id) + ON DELETE SET NULL + ); + `); + + + await client.query(` + CREATE TABLE research_papers + ( + paper_id SERIAL PRIMARY KEY, + paper_title VARCHAR(255) UNIQUE, + conference VARCHAR(100), + publish_date DATE + ); + `); + + + await client.query(` + CREATE TABLE author_paper + ( + author_id INT, + paper_id INT, + PRIMARY KEY (author_id, paper_id), + FOREIGN KEY (author_id) REFERENCES authors (author_id) ON DELETE CASCADE, + FOREIGN KEY (paper_id) REFERENCES research_papers (paper_id) ON DELETE CASCADE + ); + `); + + + await client.query(` + INSERT INTO authors (author_name, university, date_of_birth, h_index, gender, mentor) + VALUES ('Daryna Tkachenko', 'Taras Shevchenko National University of Kyiv', '2000-05-21', 14, 'Female', + NULL), + ('Andrii Shevchenko', 'V. N. Karazin Kharkiv National University', '2001-02-14', 22, 'Male', 1), + ('Oksana Kovalenko', 'Ivan Franko National University of Lviv', '2002-11-02', 18, 'Female', 2), + ('Kateryna Tkachenko', 'National Technical University of Ukraine "Igor Sikorsky KPI"', '2001-10-01', + 25, 'Female', 1), + ('Dmytro Bondarenko', 'Odesa I. I. Mechnikov National University', '2000-12-18', 30, 'Male', 3), + ('Iryna Melnyk', 'Sumy State University', '2003-09-10', 20, 'Female', NULL), + ('Taras Kravets', 'Lviv Polytechnic National University', '2002-04-30', 17, 'Male', 6), + ('Maria Polishchuk', 'Yuriy Fedkovych Chernivtsi National University', '2001-08-15', 12, 'Female', + 1), + ('Oleksii Havrylenko', 'Oles Honchar Dnipro National University', '2000-01-16', 28, 'Male', 4), + ('Sofia Lysenko', 'Vasyl Stefanyk Precarpathian National University', '2003-07-08', 16, 'Female', 9), + ('Yurii Hrytsenko', 'National University of Kyiv-Mohyla Academy', '2001-10-03', 24, 'Male', 5), + ('Viktoria Kuzmenko', 'Zaporizhzhia National University', '2002-02-27', 9, 'Female', 6), + ('Bohdan Petrenko', 'Poltava National Technical University', '2000-12-21', 19, 'Male', NULL), + ('Natalia Horobets', 'V. O. Sukhomlynskyi Mykolaiv National University', '2002-03-05', 31, 'Female', + 3), + ('Roman Yaremchuk', 'Uzhhorod National University', '2001-06-14', 26, 'Male', NULL) + `); + + + await client.query(` + INSERT INTO research_papers (paper_title, conference, publish_date) + VALUES ('Design', 'A', '2025-05-05'), + ('Energy', 'B', '2025-05-06'), + ('Vision', 'C', '2025-05-07'), + ('Robots', 'D', '2025-05-08'), + ('Systems', 'E', '2025-05-09'), + ('Health', 'F', '2025-05-10'), + ('Models', 'G', '2025-05-11'), + ('Networks', 'H', '2025-05-12'), + ('Privacy', 'I', '2025-05-13'), + ('Finance', 'J', '2025-05-14'), + ('Learning', 'K', '2025-05-15'), + ('Control', 'L', '2025-05-16'), + ('Climate', 'M', '2025-05-17'), + ('Security', 'N', '2025-05-18'), + ('Agriculture', 'O', '2025-05-19'), + ('Mining', 'P', '2025-05-20'), + ('Sensors', 'Q', '2025-05-21'), + ('Mobility', 'R', '2025-05-22'), + ('Tracking', 'S', '2025-05-23'), + ('Analytics', 'T', '2025-05-24'), + ('Optimization', 'U', '2025-05-25'), + ('Chemistry', 'V', '2025-05-26'), + ('Dynamics', 'W', '2025-05-27'), + ('Physics', 'X', '2025-05-28'), + ('Cognition', 'Y', '2025-05-29'), + ('Materials', 'Z', '2025-05-30'), + ('Testing', 'A1', '2025-05-31'), + ('Training', 'B1', '2025-06-01'), + ('BioTech', 'C1', '2025-06-02'), + ('Automation', 'D1', '2025-06-03') + `); + + + await client.query(` + INSERT INTO author_paper (author_id, paper_id) + VALUES (1, 1), + (1, 2), + (2, 3), + (2, 4), + (3, 5), + (3, 6), + (4, 7), + (4, 8), + (5, 9), + (5, 10), + (6, 11), + (6, 12), + (7, 13), + (7, 14), + (8, 15), + (8, 16), + (9, 17), + (9, 18), + (10, 19), + (10, 20), + (11, 21), + (11, 22), + (12, 23), + (12, 24), + (13, 25), + (13, 26), + (14, 27), + (14, 28), + (15, 29), + (15, 30) + `); + + console.log("Database setup completed successfully."); + } catch (err) { + console.error("Error setting up database:", err); + } finally { + await client.end(); + } +} + +setupDatabase();