25-Comp-B3 Data Bases and File Systems · December 2015
Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)
Question text not reproduced: the examination questions are © Engineers and Geoscientists BC. Open the official past paper (linked at the top of this page) to read the question, then follow the worked solution below.
Given. Question 5's same four relations, with Artist's key renamed Tid (was Aid) and ArtObject's artist-reference column renamed to match — a pure relabelling, not a schema change. The query in (a) uses an unqualified FROM ArtObject yet references A.Cost/A.Acquired/A.Origin throughout, so the FROM clause is read as the evident FROM ArtObject A (every correlated reference to the alias "A" is present, which is how the intended alias is recovered).
Find. (a) a plain-English reading of the given query; (b) the SQL for artists with zero acquired art objects.
Approach. (a) is read from the inside out: the correlated subquery counts how many rows share a given Cost among post-1999 acquisitions, and the HAVING clause keeps only groups where that count exceeds 1. (b) is the same "never" pattern as Question 5(b), now needed directly in SQL rather than RA, using NOT EXISTS for correctness under NULLs.
> 1, i.e. Cost values shared by TWO OR MORE art objects acquired since 2000. In plain English: the query finds every purchase-cost value that recurs among two or more Art Objects acquired after 1999, and returns that cost together with the Origin of one of the matching objects. Equivalently, it flags art objects that share their exact purchase price with at least one other post-1999 acquisition.A.Origin while grouping only by A.Cost is not valid under strict SQL (a non-aggregated, non-grouped column is ambiguous whenever a Cost group spans more than one Origin) — some engines (e.g. MySQL's default mode) permit it and silently return an arbitrary matching row's Origin per group, while standard-conforming engines (PostgreSQL, SQL Server) reject it outright. The reading above assumes the lenient behaviour, since the question is clearly asking what the query returns rather than whether it is portable.SELECT Ar.Tname
FROM Artist Ar
WHERE NOT EXISTS (
SELECT 1 FROM ArtObject AO WHERE AO.Tid = Ar.Tid
);An equivalent Tid NOT IN (SELECT Tid FROM ArtObject) form reads more simply, but is unsafe if ArtObject.Tid can ever be NULL (a single NULL in the subquery's result set makes the whole NOT IN evaluate to UNKNOWN for every row, silently returning zero artists) — NOT EXISTS has no such trap, since it only tests row EXISTENCE and never compares against a NULL value directly.| Part | Result |
|---|---|
| (a) | "Cost values shared by 2+ Art Objects acquired after 1999" (plus an Origin from one such object; non-standard GROUP BY) |
| (b) | NOT EXISTS correlated subquery (safe under NULLs, unlike NOT IN) |