{"id":22039460,"url":"https://github.com/mpolinowski/postgresql-getting-started","last_synced_at":"2026-04-30T12:34:11.267Z","repository":{"id":111484079,"uuid":"146161336","full_name":"mpolinowski/postgresql-getting-started","owner":"mpolinowski","description":"PostgreSQL and Structured Query Language :: Getting Started","archived":false,"fork":false,"pushed_at":"2018-08-26T07:43:01.000Z","size":622,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-30T22:38:59.485Z","etag":null,"topics":["postgresql","postgresql-database","sql","sql-query"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mpolinowski.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-26T07:42:51.000Z","updated_at":"2018-08-26T07:47:35.000Z","dependencies_parsed_at":"2023-05-09T17:31:56.226Z","dependency_job_id":null,"html_url":"https://github.com/mpolinowski/postgresql-getting-started","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mpolinowski/postgresql-getting-started","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpolinowski%2Fpostgresql-getting-started","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpolinowski%2Fpostgresql-getting-started/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpolinowski%2Fpostgresql-getting-started/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpolinowski%2Fpostgresql-getting-started/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mpolinowski","download_url":"https://codeload.github.com/mpolinowski/postgresql-getting-started/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mpolinowski%2Fpostgresql-getting-started/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32465009,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T22:27:22.272Z","status":"online","status_checked_at":"2026-04-30T02:00:05.929Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["postgresql","postgresql-database","sql","sql-query"],"created_at":"2024-11-30T11:10:52.268Z","updated_at":"2026-04-30T12:34:11.246Z","avatar_url":"https://github.com/mpolinowski.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Getting started with PostgreSQL in Windows 10\n\n\u003c!-- TOC --\u003e\n\n- [Getting started with PostgreSQL in Windows 10](#getting-started-with-postgresql-in-windows-10)\n  - [Installation](#installation)\n  - [Adding some Dummy Data to work with](#adding-some-dummy-data-to-work-with)\n    - [SELECT Queries](#select-queries)\n      - [ORDER BY](#order-by)\n      - [WHERE](#where)\n      - [OR](#or)\n      - [AND](#and)\n      - [LIKE \u0026 LOWER](#like--lower)\n      - [LIKE \u0026 UPPER](#like--upper)\n      - [Working with numbers](#working-with-numbers)\n  - [Adding a another Dataset](#adding-a-another-dataset)\n    - [ALTER TABLE \u0026 ADD COLUMN](#alter-table--add-column)\n    - [UPDATE \u0026 SET](#update--set)\n    - [VARCHARS](#varchars)\n      - [length](#length)\n      - [left \u0026 right](#left--right)\n      - [reverse](#reverse)\n    - [Working with Dates](#working-with-dates)\n      - [AS](#as)\n      - [AGE](#age)\n      - [DATE_PART \u0026 COUNT](#date_part--count)\n    - [Changing the Data Type](#changing-the-data-type)\n      - [CAST](#cast)\n        - [to_date](#to_date)\n    - [IS null](#is-null)\n\n\u003c!-- /TOC --\u003e\n\n## Installation\n\n[Download the Version](https://www.postgresql.org/download/) of PostgreSQL that suits your OS. In my case I will choose the installer certified by EnterpriseDB for Windows 64bit.\n\n\n\nStart the installer and accept the defaults - only add __your own password__ that you will be able to use with the __username: postgres__ to log in to the pgAdmin Control Panel.\n\n\n## Adding some Dummy Data to work with\n\nWe are going to use the free available [Consumer Complaint Database](https://www.consumerfinance.gov/data-research/consumer-complaints/) from the Consumer Financial Protection Bureau.\n\nStart the __pgAdmin4__ Admin Panel and right-click __Databases__ to create a new db. Give it a name, e.g. `consumer complaints`:\n\n\n![PostgrSQL](./postgresql_01.png)\n\n\nNow right-click the newly created Database and selct the __Query Tool__. Paste the following in and click on __Execute__ to create the `consumer_complaint` table:\n\n```sql\nCREATE TABLE consumer_complaints (\n    date_received varchar,\n    product_name varchar,\n    sub_product varchar,\n    issue varchar,\n    sub_issue varchar,\n    consumer_complaint_narrative varchar,\n    company_public_response varchar,\n    company varchar,\n    state_name varchar,\n    zip_code varchar,\n    tags varchar,\n    consumer_consent_provided varchar,\n    submitted_via varchar,\n    date_sent varchar,\n    company_response_to_consumer varchar,\n    timely_response varchar,\n    consumer_disputed varchar,\n    complaint_id integer\n);\n```\n\n\u003e Note: If you are running the Astrill VPN client on your System, this will block access to the Query Tool. Add pgAdmin4 to the list of allowed programs that are not forced through the VPN tunnel.\n\n\nNow we can add the data from the earlier downloaded _ConsumerComplaints.csv_ file, by executing the following query (change the path-to-file according to your download folder)\n\n\n```sql\nCOPY consumer_complaints FROM 'E:\\postgresql-getting-started\\ConsumerComplaints.csv' DELIMITER ',' CSV HEADER;\n```\n\n\n![PostgrSQL](./postgresql_02.png)\n\n\nWe have now created our schema with 18 columns and copied 65499 data entries from the CSV file into our table. We can check our data by running the following query:\n\n\n```sql\nSELECT *\nFROM consumer_complaints;\n```\n\n\n### SELECT Queries\n\nThe `SELECT *` allows you to grab the content of _all columns_ of your table. If you want to select specific columns you can string them together, separated by commas - e.g. `SELECT date_received, issue, state_name, tags`.\n\n\n![PostgrSQL](./postgresql_03.png)\n\n\n#### ORDER BY\n\n```sql\nSELECT *\nFROM consumer_complaints\nORDER BY company;\n```\n\n```sql\nSELECT *\nFROM consumer_complaints\nORDER BY zip_code ASC;\n```\n\n```sql\nSELECT *\nFROM consumer_complaints\nORDER BY zip_code, date_received DESC;\n```\n\n#### WHERE\n\nTo Filter your results, by adding a condition with the __Where__ statement:\n\n```sql\nSELECT product_name, issue\nFROM consumer_complaints\nWHERE state_name = 'NY';\n```\n\nThis query only displays results from the two selected columns inside the referenced table where the _state_name_ equals New York. We can also add some logic to our queries - e.g. if we want to know how many complaints weren't answered on the same day we can write the following SQL query:\n\n\n```sql\nSELECT company, product_name, issue\nFROM consumer_complaints\nWHERE date_sent != date_received;\n```\n\n#### OR\n\n```sql\nSELECT company, product_name, issue\nFROM consumer_complaints\nWHERE state_name = 'NY' OR state_name = 'CA';\n```\n\n#### AND\n\n```sql\nSELECT company, product_name\nFROM consumer_complaints\nWHERE tags = 'Servicemember' AND timely_response = 'Yes';\n```\n\n\n#### LIKE \u0026 LOWER\n\n```sql\nSELECT product_name\nFROM consumer_complaints\nWHERE LOWER(product_name) LIKE '%credit%';\n```\n\nThe __LIKE__ condition allows us to use %-wildcards to search for every value of _product\\_name_ that contains the word _credit_. The Select query is case sensitive - by adding __LOWER__ we transform all _product\\_name_ values to lower-case and then compare it against a lower-case search query. The same can be achieved with using __UPPER__ instead:\n\n\n#### LIKE \u0026 UPPER\n\n```sql\nSELECT company\nFROM consumer_complaints\nWHERE UPPER(issue) LIKE '%LATE%';\n```\n\n#### Working with numbers\n\nDisplay all companies that are in an area that zip-code starts with `12*`:\n\n```sql\nSELECT company, product_name\nFROM consumer_complaints\nWHERE zip_code LIKE '12___';\n```\n\n All zip-codes have 5 digits - we signify the position of our search number by adding underscore for every digit that is a wildcard - e.g. `__1__` would hit all zip-codes that have a 1 in the middle. Alternatively, you can also use the `%` syntax to get the same result:\n\n\n```sql\nSELECT company, product_name\nFROM consumer_complaints\nWHERE zip_code LIKE '12%';\n```\n\n\nUsing `%1%` instead would give you all the zip-codes that have a number 1 in __any position__.\n\n\n__COUNT__\n\n```sql\nSELECT COUNT(company)\nFROM consumer_complaints\nWHERE LOWER(company) LIKE '%bell%';\n```\n\nCount all instances where a company with the word _bell_ in its name filed a complaint.\n\n\n## Adding a another Dataset\n\nThe .csv files used here can be downloaded from here ([Section 5](https://www.superdatascience.com/sql/)). Right-click __Databases__ to add a new db and name it `console games`. Then create the following tables with the 2 .csv files you just downloaded:\n\n```sql\nCREATE TABLE console_games (\n    game_rank integer,\n    game_name varchar(1200),\n    platform varchar(1200),\n    game_year integer,\n    genre varchar(20),\n    publisher varchar(1200),\n    na_sales float8,\n    eu_sales float8,\n    jp_sales float8,\n    other_sales float8\n);\n\nCOPY console_games FROM 'E:\\postgresql-getting-started\\ConsoleGames.csv' DELIMITER ',' CSV HEADER;\n```\n\nand\n\n```sql\nCREATE TABLE console_dates (\n    platform_name char(120),\n    first_retail_availability date,\n    discontinued date,\n    units_sold_mill float8,\n    platform_comment varchar(120)    \n);\n\nCOPY console_dates FROM 'E:\\postgresql-getting-started\\ConsoleDates.csv' DELIMITER ',' CSV HEADER;\n```\n\nLets work with our data and add all NA, EU and JP sales together to get a new colum with `global_sales`:\n\n### ALTER TABLE \u0026 ADD COLUMN\n\n```sql\nALTER TABLE console_games\nADD COLUMN global_sales float8;\n```\n\nThis will alternate the table _console\\_games_  and add a column named _global\\_sales_ that will receive a number with decimal point. We can now fill in the value by a simple addition:\n\n### UPDATE \u0026 SET\n\n```sql\nUPDATE console_games\nSET global_sales = na_sales + eu_sales + jp_sales;\n```\n\nNow we can calculate the percentage of the North-American sales from the global sales:\n\n```sql\nALTER TABLE console_games\nADD COLUMN na_sales_percent float8;\n\nUPDATE console_games\nSET na_sales_percent = na_sales / global_sales * 100\nWHERE global_sales \u003e 0;\n```\n\n### VARCHARS\n\nWorking with __String Functions__\n\n#### length\n\n```sql\nSELECT game_name, length(game_name)\nFROM console_games\nORDER BY length(game_name) DESC;\n```\n\nWill give us a column with the count of characters inside the name of the game:\n\n![PostgrSQL](./postgresql_04.png)\n\n\n#### left \u0026 right\n\nTo only grab the first 4 letters of the publisher name:\n\n```sql\nSELECT left(publisher, 4)\nFROM console_games\nORDER BY left(publisher, 1) DESC;\n```\n\n#### reverse\n\nWill reverse the order of the characters or numbers of the values of the selected column:\n\n```sql\nSELECT reverse(genre)\nFROM console_games;\n```\n\n### Working with Dates\n\n#### AS\n\n```sql\nSELECT *, discontinued - first_retail_availability AS days_existed\nFROM console_dates;\n```\n\n__AS__ will create a __temporary column__ (we need to use ALTER TABLE add it permanently) with the number of days a console system was available on the market:\n\n\n![PostgrSQL](./postgresql_05.png)\n\n\nThis can help you to get a quick overview over your data - but isn't very precise e.g.:\n\n\n```sql\nSELECT *, (discontinued - first_retail_availability)/365 AS years_existed\nFROM console_dates\nORDER BY years_existed DESC;\n```\n\n\n#### AGE\n\nThe more accurate way to calculate it:\n\n```sql\nSELECT *, AGE(discontinued, first_retail_availability) AS platform_alive\nFROM console_dates\nORDER BY platform_alive DESC;\n```\n\n\n![PostgrSQL](./postgresql_06.png)\n\n\n#### DATE_PART \u0026 COUNT\n\nThe PostgreSQL DATE_PART() function, that allows you to retrieve subfields e.g., year, month, week from a date or time value. E.g. DATE_PART(month) will only subtract the subfield month of a date - you have one date in November and the second in December this will be `11 - 12 = -1`. One use case of this function is to check how many entries are from a specific month of the year:\n\n```sql\nSELECT COUNT(platform_name)\nFROM console_dates\nWHERE DATE_PART('month', first_retail_availability) - 11 = 0 OR DATE_PART('month', first_retail_availability) - 12 = 0;\n```\n\nThis query will __COUNT__ all the console systems that were released in November __OR__ December - just in time for the X-mas present madness.\n\n\n![PostgrSQL](./postgresql_07.png)\n\n\nOr you can check what consoles where released in a specific year:\n\n\n```sql\nSELECT *\nFROM console_dates\nWHERE DATE_PART('year', first_retail_availability) - 1990 = 0;\n```\n\n\n![PostgrSQL](./postgresql_08.png)\n\n\nThe values of the field must be in a list of permitted values mentioned below:\n\n* century\n* decade\n* year\n* month\n* day\n* hour\n* minute\n* second\n* microseconds\n* milliseconds\n* dow\n* doy\n* epoch\n* isodow\n* isoyear\n* timezone\n* timezone_hour\n* timezone_minute\n\n\n### Changing the Data Type\n\n#### CAST\n\n```sql\nSELECT CAST(game_year as varchar(4))\nFROM console_games\nORDER BY game_year;\n```\n\nA shortcut is that will do the same:\n\n```sql\nSELECT game_year::varchar(4)\nFROM console_games\nORDER BY game_year;\n```\n\n##### to_date\n\nMore useful is the conversion to a date data type:\n\n```sql\nSELECT to_date(CAST(game_year as varchar(4)), 'yyyy')\nFROM console_games\nORDER BY game_year;\n```\n\n\n### IS null\n\nFinding undefined fields (notice: we have to use __IS__ instead of an equal sign when working with _null_ :\n\n```sql\nSELECT *\nFROM console_games\nWHERE game_name IS NULL;\n```\n\nAdding a value to an undefined field:\n\n```sql\nUPDATE console_games\nSET jp_sales = round((na_sales + eu_sales + other_sales) / 3)\nWHERE jp_sales IS null;\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpolinowski%2Fpostgresql-getting-started","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmpolinowski%2Fpostgresql-getting-started","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmpolinowski%2Fpostgresql-getting-started/lists"}