Slides: https://rayvoelker.github.io/chpl-howtosql-2022/
SQL Sandbox: https://wiliug2022.cincy.pl
Ray Voelker
ray.voelker@chpl.org
Keys (typically called ID’s in the Sierra Database) come in two varieties, and they define the relationship between tables.
Relational Databases: Relationships (JOINS)
Relational Databases: Relationships (JOINS) cont.
Relational Databases: Relationships (JOINS) cont.
Relational Databases: Relationships (JOINS) cont.
A good explanation in "Simple English" of SQL JOIN operations can be found on this Wikipedia pageSQL Overview cont.
SQL Overview cont.
SQL Overview cont.
SQL Overview cont.
SQL Overview cont.
SQL Overview cont.
SQL Overview cont.
SELECT
r.id, r.record_type_code,
r.record_num, r.creation_date_gmt,
r.deletion_date_gmt, r.num_revisions
FROM
sierra_view.record_metadata AS r
WHERE
r.record_type_code = 'b'
ORDER BY
r.creation_date_gmt ASC
LIMIT
10
The Sierra Services Platform incorporates a PostgreSQL relational database that captures the library's material, circulation, patron, financial, and operational data. A collection of database views provides direct access to the library's bibliographic and transactional data. Each view is constructed from one or more tables and can be queried as a single table. Views are read-only.
Filter by specific bib numbers ...
SELECT
r.id as bib_record_id,
r.record_num,
r.creation_date_gmt
FROM
record_metadata AS r
WHERE
r.record_type_code = 'b'
AND r.record_num IN (
1000408,
1171546,
2536827,
2588448,
3255849,
3282825,
1012434
)
SQL SELECT Statement cont.
SQL GROUP BY / HAVING and Aggregate Functions cont.
SQL GROUP BY / HAVING and Aggregate Functions cont.
SELECT
p.publish_year,
count(*) as count_titles
FROM
bib_record_property as p
WHERE
p.publish_year = 1977
GROUP BY
p.publish_year
SQL GROUP BY / HAVING and Aggregate Functions cont.
SQL GROUP BY / HAVING and Aggregate Functions cont.
SELECT
p.publish_year,
count(*) as count_titles
FROM
bib_record_property as p
GROUP BY
p.publish_year
HAVING
count(*) > 300
SQL GROUP BY / HAVING and Aggregate Functions cont.
SQL GROUP BY / HAVING and Aggregate Functions cont.
SELECT
p.publish_year,
count(*) as count_titles
FROM
bib_record_property as p
GROUP BY
p.publish_year
HAVING
count(*) > 300
SQL GROUP BY / HAVING and Aggregate Functions cont.
SELECT
p.publish_year,
count(*) as count_titles,
(
SELECT
count(*)
FROM
bib_record_property as p2
LEFT join bib_record_item_record_link as l2 on l2.bib_record_id = p2.bib_record_id
LEFT join item_record as i2 on i2.record_id = l2.item_record_id
WHERE
p2.publish_year = p.publish_year
AND i2.item_status_code = '-'
) as count_available_items
FROM
bib_record_property as p
GROUP BY
p.publish_year
HAVING
count(p.bib_record_id) > 300
SQL Common Table Expression (CTE) WITH Clause
WITH target_bib_item_data AS (
-- first, gather the bib AND attached item data
-- that meet our filter requirements
SELECT
p.publish_year,
p.bib_record_id,
i.record_id AS item_record_id,
i.item_status_code
FROM
bib_record_property as p
LEFT JOIN bib_record_item_record_link as l on l.bib_record_id = p.bib_record_id
LEFT JOIN item_record as i on i.record_id = l.item_record_id
WHERE
p.publish_year IN (
SELECT
p2.publish_year
FROM
bib_record_property as p2
GROUP BY
p2.publish_year
HAVING
count(*) > 300
)
) --
-- second, SELECT from the above CTE
SELECT
t.publish_year,
count(DISTINCT t.bib_record_id) as count_titles,
count(t.item_record_id) FILTER (WHERE t.item_status_code = '-') AS 'count_item_status_dash',
count(t.item_record_id) AS count_total_items
FROM
target_bib_item_data AS t
GROUP BY
t.publish_year
Subquery
Subquery cont.
Subquery cont.
SELECT
ir.record_id
FROM
item_record as ir
JOIN varfield AS vf ON vf.record_id = ir.record_id
AND vf.varfield_type_code = 'b'
GROUP BY
ir.record_id
HAVING
count(*) > 1
Subquery cont.
SELECT
i.record_id as item_record_id,
r.record_num as item_record_num,
i.location_code,
v.field_content,
v.occ_num
FROM
item_record as i
JOIN record_metadata as r ON r.id = i.record_id
JOIN varfield AS v ON v.record_id = i.record_id
AND v.varfield_type_code = 'b'
WHERE
i.record_id IN (
SELECT
ir.record_id
FROM
item_record as ir
JOIN varfield AS vf ON vf.record_id = ir.record_id
AND vf.varfield_type_code = 'b'
GROUP BY
ir.record_id
HAVING
count(*) > 1
)
ORDER BY
i.record_id,
v.occ_num
CASE Statement
CASE Statement cont.
CASE Statement cont.
SELECT
r.record_num AS item_record_num,
i.item_status_code,
CASE
WHEN item_status_code = '-' THEN 'AVAILABLE'
WHEN item_status_code = 'o' THEN 'LIB USE ONLY'
ELSE item_status_code
END as our_item_status
FROM
item_record as i
JOIN record_metadata as r ON r.id = i.record_id
ORDER BY
r.creation_date_gmt ASC
LIMIT
10
CASE Statement cont.
CASE Statement cont.
SELECT
r.record_num as item_record_num,
i.last_checkout_gmt,
CASE
WHEN i.last_checkout_gmt >= '2020-01-01' THEN '1-recent checkouts'
WHEN i.last_checkout_gmt >= '2018-01-01' THEN '2-kinda-recent checkouts'
WHEN i.last_checkout_gmt < '2018-01-01' THEN '3-long-ago checkouts'
WHEN i.last_checkout_gmt is null THEN '4-NO CHECKOUTS!'
END as 'last_checkout_groups'
FROM
item_record as i
JOIN record_metadata as r ON r.id = i.record_id
WHERE
i.location_code = '2sa'
Slides: https://rayvoelker.github.io/chpl-howtosql-2022/
SQL Sandbox: https://wiliug2022.cincy.pl
Ray Voelker
ray.voelker@gmail.com | ray.voelker@cincinnatilibrary.org