Compare commits
10 Commits
1ccd885208
...
17b9df5450
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17b9df5450 | ||
|
|
98feb63296 | ||
|
|
5d8a060610 | ||
|
|
f8f394190a | ||
|
|
2f660ae98d | ||
|
|
e9a117c085 | ||
|
|
5b2032536b | ||
|
|
41a9bb7eae | ||
|
|
712cec0d31 | ||
|
|
b35f9dff17 |
@ -64,7 +64,7 @@ VALUES
|
|||||||
SELECT * FROM date_time_types;
|
SELECT * FROM date_time_types;
|
||||||
|
|
||||||
-- Listing 4-5: Using the interval data type
|
-- Listing 4-5: Using the interval data type
|
||||||
-- Assumes script 4-4 has been run
|
-- (Assumes Listing 4-4 has been run)
|
||||||
|
|
||||||
SELECT
|
SELECT
|
||||||
timestamp_column,
|
timestamp_column,
|
||||||
|
|||||||
@ -212,9 +212,7 @@ ORDER BY id;
|
|||||||
SELECT '2020' AS year,
|
SELECT '2020' AS year,
|
||||||
school_2020 AS school
|
school_2020 AS school
|
||||||
FROM district_2020
|
FROM district_2020
|
||||||
|
|
||||||
UNION ALL
|
UNION ALL
|
||||||
|
|
||||||
SELECT '2035' AS year,
|
SELECT '2035' AS year,
|
||||||
school_2035
|
school_2035
|
||||||
FROM district_2035
|
FROM district_2035
|
||||||
|
|||||||
@ -201,12 +201,10 @@ WITH
|
|||||||
(SELECT state_name, sum(pop_est_2018)
|
(SELECT state_name, sum(pop_est_2018)
|
||||||
FROM us_counties_pop_est_2019
|
FROM us_counties_pop_est_2019
|
||||||
GROUP BY state_name),
|
GROUP BY state_name),
|
||||||
|
|
||||||
establishments (st, establishment_count) AS
|
establishments (st, establishment_count) AS
|
||||||
(SELECT st, sum(establishments) AS establishment_count
|
(SELECT st, sum(establishments) AS establishment_count
|
||||||
FROM cbp_naics_72_establishments
|
FROM cbp_naics_72_establishments
|
||||||
GROUP BY st)
|
GROUP BY st)
|
||||||
|
|
||||||
SELECT counties.st,
|
SELECT counties.st,
|
||||||
pop_est_2018,
|
pop_est_2018,
|
||||||
establishment_count,
|
establishment_count,
|
||||||
@ -223,7 +221,6 @@ WITH us_median AS
|
|||||||
(SELECT percentile_cont(.5)
|
(SELECT percentile_cont(.5)
|
||||||
WITHIN GROUP (ORDER BY pop_est_2019) AS us_median_pop
|
WITHIN GROUP (ORDER BY pop_est_2019) AS us_median_pop
|
||||||
FROM us_counties_pop_est_2019)
|
FROM us_counties_pop_est_2019)
|
||||||
|
|
||||||
SELECT county_name,
|
SELECT county_name,
|
||||||
state_name AS st,
|
state_name AS st,
|
||||||
pop_est_2019,
|
pop_est_2019,
|
||||||
@ -266,12 +263,10 @@ FROM crosstab('SELECT office,
|
|||||||
FROM ice_cream_survey
|
FROM ice_cream_survey
|
||||||
GROUP BY office, flavor
|
GROUP BY office, flavor
|
||||||
ORDER BY office',
|
ORDER BY office',
|
||||||
|
|
||||||
'SELECT flavor
|
'SELECT flavor
|
||||||
FROM ice_cream_survey
|
FROM ice_cream_survey
|
||||||
GROUP BY flavor
|
GROUP BY flavor
|
||||||
ORDER BY flavor')
|
ORDER BY flavor')
|
||||||
|
|
||||||
AS (office text,
|
AS (office text,
|
||||||
chocolate bigint,
|
chocolate bigint,
|
||||||
strawberry bigint,
|
strawberry bigint,
|
||||||
@ -303,10 +298,8 @@ FROM crosstab('SELECT
|
|||||||
GROUP BY station_name,
|
GROUP BY station_name,
|
||||||
date_part(''month'', observation_date)
|
date_part(''month'', observation_date)
|
||||||
ORDER BY station_name',
|
ORDER BY station_name',
|
||||||
|
|
||||||
'SELECT month
|
'SELECT month
|
||||||
FROM generate_series(1,12) month')
|
FROM generate_series(1,12) month')
|
||||||
|
|
||||||
AS (station text,
|
AS (station text,
|
||||||
jan numeric(3,0),
|
jan numeric(3,0),
|
||||||
feb numeric(3,0),
|
feb numeric(3,0),
|
||||||
@ -349,7 +342,6 @@ WITH temps_collapsed (station_name, max_temperature_group) AS
|
|||||||
ELSE 'No reading'
|
ELSE 'No reading'
|
||||||
END
|
END
|
||||||
FROM temperature_readings)
|
FROM temperature_readings)
|
||||||
|
|
||||||
SELECT station_name, max_temperature_group, count(*)
|
SELECT station_name, max_temperature_group, count(*)
|
||||||
FROM temps_collapsed
|
FROM temps_collapsed
|
||||||
GROUP BY station_name, max_temperature_group
|
GROUP BY station_name, max_temperature_group
|
||||||
|
|||||||
@ -189,7 +189,6 @@ SET date_1 =
|
|||||||
(regexp_match(original_text, '\/\d{2}\n(\d{4})'))[1]
|
(regexp_match(original_text, '\/\d{2}\n(\d{4})'))[1]
|
||||||
||' US/Eastern'
|
||' US/Eastern'
|
||||||
)::timestamptz,
|
)::timestamptz,
|
||||||
|
|
||||||
date_2 =
|
date_2 =
|
||||||
CASE
|
CASE
|
||||||
-- if there is no second date but there is a second hour
|
-- if there is no second date but there is a second hour
|
||||||
@ -201,7 +200,6 @@ SET date_1 =
|
|||||||
(regexp_match(original_text, '\/\d{2}\n\d{4}-(\d{4})'))[1]
|
(regexp_match(original_text, '\/\d{2}\n\d{4}-(\d{4})'))[1]
|
||||||
||' US/Eastern'
|
||' US/Eastern'
|
||||||
)::timestamptz
|
)::timestamptz
|
||||||
|
|
||||||
-- if there is both a second date and second hour
|
-- if there is both a second date and second hour
|
||||||
WHEN (SELECT regexp_match(original_text, '-(\d{1,2}\/\d{1,2}\/\d{2})') IS NOT NULL)
|
WHEN (SELECT regexp_match(original_text, '-(\d{1,2}\/\d{1,2}\/\d{2})') IS NOT NULL)
|
||||||
AND (SELECT regexp_match(original_text, '\/\d{2}\n\d{4}-(\d{4})') IS NOT NULL)
|
AND (SELECT regexp_match(original_text, '\/\d{2}\n\d{4}-(\d{4})') IS NOT NULL)
|
||||||
|
|||||||
@ -293,7 +293,7 @@ SELECT ST_SetSRID(
|
|||||||
FROM earthquakes
|
FROM earthquakes
|
||||||
ORDER BY id;
|
ORDER BY id;
|
||||||
|
|
||||||
-- Listing 16-19: Converting JSON coordinates to a PostGIS geometry column
|
-- Listing 16-19: Converting JSON coordinates to a PostGIS geography column
|
||||||
|
|
||||||
-- Add a column of the geography data type
|
-- Add a column of the geography data type
|
||||||
ALTER TABLE earthquakes ADD COLUMN earthquake_point geography(POINT, 4326);
|
ALTER TABLE earthquakes ADD COLUMN earthquake_point geography(POINT, 4326);
|
||||||
|
|||||||
@ -4,8 +4,13 @@
|
|||||||
[Practical SQL, 2nd Edition](https://nostarch.com/practical-sql-2nd-edition/) is a beginner-friendly guide to the database programming language SQL. Author [Anthony DeBarros](https://www.anthonydebarros.com) starts with beginner SQL concepts such as queries, data types, and basic math and aggregation, and then works through intermediate and advanced topics including statistics, cleaning data, GIS, and automating tasks. Along the way, you'll use real-world data from the U.S. Census and other government agencies and learn the fundamentals of good database design. This is a book not only about SQL but about best practices for using it for thorough, accurate data analysis.
|
[Practical SQL, 2nd Edition](https://nostarch.com/practical-sql-2nd-edition/) is a beginner-friendly guide to the database programming language SQL. Author [Anthony DeBarros](https://www.anthonydebarros.com) starts with beginner SQL concepts such as queries, data types, and basic math and aggregation, and then works through intermediate and advanced topics including statistics, cleaning data, GIS, and automating tasks. Along the way, you'll use real-world data from the U.S. Census and other government agencies and learn the fundamentals of good database design. This is a book not only about SQL but about best practices for using it for thorough, accurate data analysis.
|
||||||
|
|
||||||
## A Note About Editions
|
## A Note About Editions
|
||||||
|
|
||||||
If you're reading the first edition of the book, published in 2018, please [use the code and data in the first edition repository](https://github.com/anthonydb/practical-sql/). If the cover of your copy does not say, "2nd Edition," then you're using the first edition.
|
If you're reading the first edition of the book, published in 2018, please [use the code and data in the first edition repository](https://github.com/anthonydb/practical-sql/). If the cover of your copy does not say, "2nd Edition," then you're using the first edition.
|
||||||
|
|
||||||
|
## Important Updates to pgAdmin
|
||||||
|
|
||||||
|
In the book, we write SQL queries and manage our PostgreSQL databases with [pgAdmin](https://pgadmin.org), a free and open source graphical user interface. pgAdmin is under continuous development, and its current interface may differ from the screenshots and instructions in the book. Please check [the book FAQ](https://github.com/anthonydb/practical-sql-2/blob/master/faq-updates-errata.md) for updates.
|
||||||
|
|
||||||
## Who Is This Book For?
|
## Who Is This Book For?
|
||||||
|
|
||||||
Practical SQL is ideal for beginners as well as those who know some SQL and want to go deeper.
|
Practical SQL is ideal for beginners as well as those who know some SQL and want to go deeper.
|
||||||
|
|||||||
@ -458,7 +458,7 @@ CREATE TABLE songs (
|
|||||||
-- We could consider the catalog_code. We would have to answer yes to
|
-- We could consider the catalog_code. We would have to answer yes to
|
||||||
-- these questions:
|
-- these questions:
|
||||||
-- 1. Is it going to be unique across all albums released by all companies?
|
-- 1. Is it going to be unique across all albums released by all companies?
|
||||||
-- 2. Will an album always have a catelog code?
|
-- 2. Will an album always have a catalog code?
|
||||||
|
|
||||||
|
|
||||||
-- 3. To speed up queries, which columns are good candidates for indexes?
|
-- 3. To speed up queries, which columns are good candidates for indexes?
|
||||||
@ -899,26 +899,27 @@ SELECT (regexp_match('Williams, Sr.', '.*, (.*)'))[1];
|
|||||||
-- regexp_split_to_table() in a subquery to create a table of words to count.
|
-- regexp_split_to_table() in a subquery to create a table of words to count.
|
||||||
-- Bonus: remove commas and periods at the end of each word.
|
-- Bonus: remove commas and periods at the end of each word.
|
||||||
|
|
||||||
-- Answer:
|
|
||||||
-- This query uses a Common Table Expression to first separate each word
|
-- This query uses a Common Table Expression to first separate each word
|
||||||
-- in the text into a separate row in a table named word_list. Then the SELECT
|
-- in the text into a separate row in a table named word_list. As part of the
|
||||||
-- statement counts the words, which are cleaned up with two operations. First,
|
-- operation, we use nested replace functions to remove commas, periods, and
|
||||||
-- several nested replace functions remove commas, periods, and colons. Second,
|
-- colons. Then the SELECT statement counts the words, which we convert
|
||||||
-- all words are converted to lowercase so that when we count we group words
|
-- to lowercase so that when we count we group words that may appear with
|
||||||
-- that may appear with various cases (e.g., "Military" and "military").
|
-- various cases (e.g., "Military" and "military").
|
||||||
|
|
||||||
|
-- Thanks to reader @DavidSwagger for pointing out the replace function
|
||||||
|
-- needed to happen in the WITH statement.
|
||||||
|
|
||||||
WITH
|
WITH
|
||||||
word_list (word)
|
word_list (word)
|
||||||
AS
|
AS
|
||||||
(
|
(
|
||||||
SELECT regexp_split_to_table(speech_text, '\s') AS word
|
SELECT regexp_split_to_table(
|
||||||
|
replace(replace(replace(speech_text, ',', ''), '.', ''), ':', ''),
|
||||||
|
'\s') AS word
|
||||||
FROM president_speeches
|
FROM president_speeches
|
||||||
WHERE speech_date = '1946-01-21'
|
WHERE speech_date = '1946-01-21'
|
||||||
)
|
)
|
||||||
|
SELECT lower(word) AS cleaned_word,
|
||||||
SELECT lower(
|
|
||||||
replace(replace(replace(word, ',', ''), '.', ''), ':', '')
|
|
||||||
) AS cleaned_word,
|
|
||||||
count(*)
|
count(*)
|
||||||
FROM word_list
|
FROM word_list
|
||||||
WHERE length(word) >= 5
|
WHERE length(word) >= 5
|
||||||
|
|||||||
@ -2,9 +2,21 @@
|
|||||||
|
|
||||||
### FAQ, Updates, and Errata
|
### FAQ, Updates, and Errata
|
||||||
|
|
||||||
This page contains answers to Frequently Asked Questions, updates to material and URLs, and errata for Practical SQL, 2nd Edition. Some of these apply to the first couple of printings of the book and may be updated if you have a third printing or later. Check the copyright page to see which printing you have.
|
This page contains answers to Frequently Asked Questions, updates to material and URLs, and errata for Practical SQL, 2nd Edition. Some only apply to the first printings of the book and have been subsequently incorporated in later printings. Check the copyright page to see which printing you have.
|
||||||
|
|
||||||
|
|
||||||
|
### Important pgAdmin 4 Version 9 Update!
|
||||||
|
|
||||||
|
Version 9 of pgAdmin 4, released in February 2025, introduces a new default "workspace" layout that is substantially different from the layout of the tool shown in the book. It's also, in my opinion, less intuitive. Fortunately, it's possible to set the app's layout to the "classic" design shown in the book. To do that:
|
||||||
|
|
||||||
|
1. Launch pgAdmin
|
||||||
|
2. On macOS, select the `pgAdmin` menu, then `Settings`. On Windows, select the `File` menu, then `Preferences`.
|
||||||
|
3. In the Preferences dialog, navigate to `Miscellaneous` and click `User interface`.
|
||||||
|
4. Under `Layout`, choose `Classic`. You can also choose a light or dark theme here.
|
||||||
|
5. Click `Save`.
|
||||||
|
|
||||||
|
Please see additional pgAdmin updates in the chapter sections below.
|
||||||
|
|
||||||
### Introduction
|
### Introduction
|
||||||
|
|
||||||
* No updates
|
* No updates
|
||||||
@ -18,11 +30,15 @@ This page contains answers to Frequently Asked Questions, updates to material an
|
|||||||
|
|
||||||
* **Page 5: Windows Installation (PostGIS)**
|
* **Page 5: Windows Installation (PostGIS)**
|
||||||
|
|
||||||
|
> The EDB installer for Windows no longer includes the Language Pack. See [this issue](https://github.com/anthonydb/practical-sql-2/issues/32) for details on how to configure Python support.
|
||||||
|
|
||||||
> The PostGIS installer for Windows now asks you to check off which components to install rather than providing individual Yes/No prompts. You can select all components including Create Spatial Database. (Applies to printings one through three of the book.)
|
> The PostGIS installer for Windows now asks you to check off which components to install rather than providing individual Yes/No prompts. You can select all components including Create Spatial Database. (Applies to printings one through three of the book.)
|
||||||
|
|
||||||
|
> The Windows 11 Start menu continues to evolve. To see the PostgreSQL and PostGIS folders added during installation, you may need to click `Start` > `All apps`.
|
||||||
|
|
||||||
* **Pages 6 and 7: Configuring Python language support (Windows)**
|
* **Pages 6 and 7: Configuring Python language support (Windows)**
|
||||||
|
|
||||||
> Note that the current version of the EDB Language Pack is updated from the version shown in the book. Use the folder and version name provided via the EDB Windows installer for `PATH` and `PYTHONHOME`. As of October 2023, that is `C:\edb\languagepack\v4\Python-3.11`
|
> The EDB installer for Windows no longer includes the Language Pack. Please see [this issue](https://github.com/anthonydb/practical-sql-2/issues/32) for instructions on how to configure Python support.
|
||||||
|
|
||||||
* **Pages 12 and on: pgAdmin Renamed "Browser" to "Object Explorer"**
|
* **Pages 12 and on: pgAdmin Renamed "Browser" to "Object Explorer"**
|
||||||
|
|
||||||
@ -34,15 +50,18 @@ This page contains answers to Frequently Asked Questions, updates to material an
|
|||||||
|
|
||||||
* **Page 14: pgAdmin: Running a Query**
|
* **Page 14: pgAdmin: Running a Query**
|
||||||
|
|
||||||
> pgAdmin, as of version 8.7 (May 2024), has added new options for running a SQL statement in the Query Tool. Previously, pgAdmin had a single `Execute/Refresh` button in its menu bar. Those have been replaced by two buttons: `Execute Script` and `Execute Query`.
|
> pgAdmin, as of version 8.7 (May 2024), has added new options for running a SQL statement in the Query Tool. Previously, the Query Tool had a single `Execute/Refresh` button in its menu bar. That has been replaced by two buttons: `Execute Script` and `Execute Query`.
|
||||||
|
|
||||||
> Clicking `Execute Script` will run every statement in your Query Tool editor. Clicking `Execute Query` will run the statement where your cursor is positioned. It also will present you with a dialog box to confirm your choice (which you can choose to silence in the future). Applies to printings one through three of the book.)
|
> Clicking `Execute Script` will run every statement in your Query Tool editor (unless you highlight a statement). Clicking `Execute Query` will run only the statement where your cursor is positioned, without a need to highlight the statement. It also will present you with a dialog box to confirm your choice (which you can choose to silence in the future). Applies to printings one through three of the book.
|
||||||
|
|
||||||
* **Page 15, Figure 1-5: pgAdmin Query Tool**
|
* **Page 15, Figure 1-5: pgAdmin Query Tool**
|
||||||
|
|
||||||
> Version 6.9 of pgAdmin, released in May 2022, introduced a redesigned Query Tool Layout. General functionality is the same, but if you are using version 6.9 or later, you will see that some menu icons shown in the book at the top of the window are now placed atop the results grid. (Applies only to first printing of the book.)
|
> Version 6.9 of pgAdmin, released in May 2022, introduced a redesigned Query Tool Layout. General functionality is the same, but if you are using version 6.9 or later, you will see that some menu icons shown in the book at the top of the window are now placed atop the results grid. (Applies only to first printing of the book.)
|
||||||
|
|
||||||
> Version 8.7 of pgAdmin, released in May 2024, updated how queries are executed in the Query Tool.
|
* **Page 15, Customizing pgAdmin**
|
||||||
|
|
||||||
|
> The book states that pgAdmin preferences are accessed by clicking `File` > `Preferences`. This is true for Windows 11. On macOS, click `pgAdmin` > `Preferences`.
|
||||||
|
|
||||||
|
|
||||||
### Chapter 2: Creating Your First Database and Table
|
### Chapter 2: Creating Your First Database and Table
|
||||||
|
|
||||||
@ -150,7 +169,9 @@ SET datestyle to "ISO, MDY";
|
|||||||
|
|
||||||
### Chapter 19: Maintaining Your Database
|
### Chapter 19: Maintaining Your Database
|
||||||
|
|
||||||
* No updates
|
* **Page 392: Listing number**
|
||||||
|
|
||||||
|
> In the first paragraph on the page, the sentence should read, "You can confirm this by rerunning the code in Listing 19-2, which shows the table remains at 35MB even after the automatic vacuum."
|
||||||
|
|
||||||
### Index
|
### Index
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user