A First Course in Database Systems |
SELECT address FROM Studio WHERE name = 'MGM';
If you interpret the question as asking only that Love
appear as a substring, then the following is OK:
SELECT starName FROM StarsIn WHERE movieYear = 1980 OR movieTitle LIKE '%Love%';However, another reasonable interpretation is that we want the word
Love
as a word by itself.
The query above returns stars of a movie like The Cook, the Thief,
His Wife, and Her Lover.
To identify only titles that have Love
as a word by itself,
either at the beginning, the middle, the endor as the entire title,
we need to use four patterns.
The following query works; notice the judiciously placed blanks in the
patterns.
SELECT starName FROM StarsIn WHERE movieYear = 1980 OR movieTitle LIKE 'Love %' OR movieTitle LIKE '% Love %' OR movieTitle LIKE '% Love' OR movieTitle = 'Love';
SELECT model, speed, hd FROM PC WHERE price < 1600;The result:
model | speed | hd |
---|---|---|
1001 | 133 | 1.6 |
1002 | 120 | 1.6 |
1010 | 160 | 1.2 |
SELECT model, speed AS megahertz, hd AS gigabytes FROM PC WHERE price < 1600;The result:
model | megahertz | gigabytes |
---|---|---|
1001 | 133 | 1.6 |
1002 | 120 | 1.6 |
1010 | 160 | 1.2 |
SELECT * FROM Printer WHERE color;The result:
model | color | type | price |
---|---|---|---|
3001 | true | ink-jet | 275 |
3002 | true | ink-jet | 269 |
3006 | true | dry | 470 |
SELECT name FROM MovieStar, StarsIn WHERE gender = 'M' AND name = starName AND movieTitle = 'Terms of Endearment';
SELECT M1.title FROM Movie AS M1, Movie AS M2 WHERE M2.title = 'Gone With the Wind' AND M1.length > M2.length;
SELECT maker, speed FROM Product, Laptop WHERE hd >= 1.0 AND Product.model = Laptop.model;
(SELECT Product.model, price FROM Product, PC WHERE Product.model = PC.model AND maker = 'B') UNION (SELECT Product.model, price FROM Product, Laptop WHERE Product.model = Laptop.model AND maker = 'B') UNION (SELECT Product.model, price FROM Product, Printer WHERE Product.model = Printer.model AND maker = 'B');
FROM
clause is
FROM R1 AS T1, R2 AS T2,...,Rn AS Tn.Now, build the
WHERE
clause from C by replacing every
reference to some attribute A of Ri by Ti.A.
Also, build the SELECT
clause from list of attributes L by
replacing every attribute A of Ri by Ti.A.
SELECT maker FROM Product WHERE model IN (SELECT model FROM PC WHERE speed >= 160); SELECT maker FROM Product WHERE EXISTS (SELECT * FROM PC WHERE speed >= 160 AND Product.model = model);Notice that the second solution uses a correlated subquery, and ``model'' refers to the more local PC.model unless we explicitly say that the ``model'' of the outer query is wanted by
Product.model
.
SELECT class FROM Ships WHERE name IN (SELECT ship FROM Outcomes WHERE result = 'sunk'); SELECT class FROM Ships WHERE EXISTS (SELECT * FROM Outcomes WHERE Ships.name = Outcomes.ship AND result = 'sunk');
SELECT name, address FROM MovieStar WHERE gender = 'F' AND (name, address) IN (SELECT name, address FROM MovieExec WHERE netWorth > 10000000);
SELECT model FROM PC WHERE speed >= 150;As the model number is a key, we do not expect to find duplicates, so
DISTINCT
is not useful here and could slow down the query.
SELECT DISTINCT P1.hd FROM PC AS P1, PC AS P2 WHERE P1.hd = P2.hd AND P1.model <> P2.model;
SELECT DISTINCT P1.maker FROM Product AS P1, Product AS P2 WHERE P1.maker = P2.maker AND P1.model <> P2.model AND P1.model IN ( (SELECT model FROM PC WHERE speed >= 133) UNION (SELECT model FROM Laptop WHERE speed >= 133) ) AND P2.model IN ( (SELECT model FROM PC WHERE speed >= 133) UNION (SELECT model FROM Laptop WHERE speed >= 133) );We look at all pairs of products, constraining them first to have the same manufacturer, different model numbers, and finally to be ``fast'' computers. The union of the PC's and laptops with speed at least 133 needs to be used twice, so we can constrain the two different model numbers to be ``fast'' computers. The
DISTINCT
in the outer query is essential.
WHERE
clause.
Thus, DISTINCT
in the outer query is advisable.
DISTINCT
in the outer query.
SELECT AVG(speed) FROM PC;
SELECT maker, AVG(screen) FROM Product, Laptop WHERE Product.model = Laptop.model GROUP BY maker;
SELECT speed, AVG(price) FROM PC WHERE speed > 150 GROUP BY speed;Notice that the condition about speed is not a property of a group, so we do not need a
HAVING
clause.
INSERT INTO Classes VALUES('Nelson', 'bb', 'Gt. Britain', 9, 16, 34000); INSERT INTO Ships VALUES('Nelson', 'Nelson', 1927); INSERT INTO Ships VALUES('Rodney', 'Nelson', 1927);
DELETE FROM Ships WHERE name IN (SELECT ship FROM Outcomes WHERE result = 'sunk');
UPDATE Classes SET bore = bore * 2.5, displacement = displacement/1.1;
CREATE TABLE Movie ( title VARCHAR(255), year INTEGER, length INTEGER, inColor BIT(1), studioName CHAR(50), producerC# INTEGER ); CREATE TABLE StarsIn ( movieTitle VARCHAR(255), movieYear INTEGER, starName CHAR(30) ); CREATE TABLE MovieExec ( name CHAR(30), address VARCHAR(255), cert# INTEGER, netWorth INTEGER ); CREATE TABLE Studio ( name CHAR(50), address VARCHAR(255), presC# INTEGER );
CREATE TABLE Laptop ( model INTEGER, speed INTEGER, ram INTEGER, hd FLOAT, screen FLOAT, price INTEGER );
ALTER TABLE Laptop ADD cd CHAR(5) DEFAULT 'none';
CREATE VIEW RichExec AS SELECT * FROM MovieExec WHERE netWorth >= 10000000;
SELECT RichExec.name FROM RichExec, StudioPres WHERE RichExec,name = StudioPres.name;
Once we have this outerjoin, we can join it with Product. There are two problems.
type
from Product and Printer are
different, and we need to rename the type
from Product.
(SELECT maker, model, type AS productType FROM Product) RIGHT NATURAL OUTER JOIN ((PC FULL NATURAL OUTER JOIN Laptop) FULL NATURAL OUTER JOIN Printer);
SELECT
clause with a list of all the
attributes of R followed by all the attributes of S.
Then, the FROM
clause would be
FROM R, S
WITH RECURSIVE Single(class, eclass) AS (SELECT class, eclass FROM Rel WHERE mult = 'single') UNION (SELECT Single.class, Rel.eclass FROM Single, Rel WHERE Single.eclass = Rel.class AND mult = 'single') SELECT * FROM Single;
WITH RECURSIVE Multi(class, eclass) AS (SELECT class, eclass FROM Rel WHERE mult = 'multi') UNION (SELECT Multi.class, Rel.eclass FROM Multi, Rel WHERE Multi.eclass = Rel.class) UNION (SELECT Rel.class, Multi.eclass FROM Multi, Rel WHERE Rel.eclass = Multi.class) SELECT * FROM Multi;In the above, we start with a connection known to be ``multi'' as the basis. We then allow an arbitrary connection to be attached to the end (the middle term of the union) or the beginning (the last term of the union) of a connection known to have at least one ``multi'' connection. The reader may wish to compare this approach with the approach taken in Exercise 4.4.3(b). Either approach is appropriate for both Datalog and SQL3, except that SQL3 does not support nonlinear recursion as was used in Exercise 4.4.3(b).