From: KS
To: Editor
The comment is about Date's AN INTRODUCTION TO DATABASE
SYSTEMS. I want to send a comment to the author of the book. Help me in
sending these comments to C.J. Date, I do not know who receives this feedback
form.
I know people won't believe this. But given a counter example
calms every one. I found a big blunder in the book of Mr. Date regarding a SQL
query. Let us call it as "Third Great Blunder" as the author himself
reserves the words "First Great Blunder" and "Second Great
Blunder" in his book (p. 237). It is regarding the SQL equivalent of A=B,
where A and B are relvars. The author writes the equivalent query as
NOT EXISTS(SELECT *
FROM a
WHERE(NOT EXISTS
(SELECT *
&nbs
p;
FROM b
&nbs
p;
WHERE a-row = b-row));
I will give you a counter example that this SQL equivalent
query is a big blunder:
Let relvar A be instance of table:
CREATE TABLE A (one integer,PRIMARY KEY(one));
Let relvar B be instance of table:
CREATE TABLE B(two integer,PRIMARY KEY(two));
Let A={a1,a2,a3} at a particular instant
Let B={a1,a2,a3,a4} at a particular instant
Then the query to check A=B at the specified instance values be
written as [sic]
The output of the query should be
2
------------
2
if A=B is true
As per Date ( the query is tested using Oracle
SQL)
SELECT 2
FROM dual
WHERE NOT EXISTS(SELECT *
FROM a
WHERE NOT EXISTS(SELECT *
&nbs
p;
FROM b
&nbs
p;
WHERE one = two));
Answer is:
2
---------
2
Now the same query is written as (to test
B=A)
SELECT 2
FROM dual
WHERE NOT EXISTS(SELECT *
FROM a
WHERE NOT EXISTS(SELECT *
&nbs
p;
FROM a
&nbs
p;
WHERE one = two));
Answer is:
no rows selected
The above two conflicting results are enough to show the
blunder in the book by Mr. Date.
In fact the solution is:
SELECT 2
FROM dual
WHERE NOT EXISTS(
(SELECT * a
MINUS
SELECT *
FROM b)
UNION
(SELECT *
FROM b
MINUS
SELECT *
FROM a));
Answer is:
no rows selected
So the equivalent of A=B (or B=A in RDBMS) is
NOT EXISTS(
(SELECT *
FROM a
MINUS
SELECT *
FROM b)
UNION
(SELECT *
FROM b
MINUS
SELECT *
FROM a));
and not as given in the book.
Hope you will correct the "Third Great Blunder" as
early as possible
Chris Date Responds: Thanks to KS for pointing out an
error in my book AN
INTRODUCTION TO DATABASE SYSTEMS, p. 237. My text currently
reads:
"For example, the comparison
A = B
(where A and B are relvars) can be simulated
by the SQL expression
NOT EXISTS(SELECT *
FROM a
WHERE NOT
EXISTS(SELECT *
&nbs
p;
FROM b
&nbs
p;
WHERE a-row = b-row));
(where A-row and B-row are <row constructor>s--see
Appendix A--representing an entire row of A and an entire row of B,
respectively)."
What it should have said is as follows:
"For example, the comparison
A = B
(where A and B are relvars) can be simulated
by the SQL expression
NOT EXISTS(SELECT *
FROM a
WHERE NOT
EXISTS(SELECT *
&nbs
p;
FROM b
&nbs
p;
WHERE a-row = a-row))
AND
NOT EXISTS(SELECT *
FROM b
WHERE NOT
EXISTS(SELECT *
&nbs
p;
FROM a
&nbs
p;
WHERE b-row = b-row))
(where A-row and B-row are <row
constructor>s--see Appendix A-- representing an entire row of A
and an entire row of B, respectively)."
I'm on record as suggesting (in the THIRD MANIFESTO)
that any logical mistake is a big mistake, so I might agree the mistake under
discussion was a blunder! (I can explain exactly how the blunder occurred,
too--it's a little subtle--but it probably isn't very interesting.) However, we
shouldn't call it, as KS suggests, the "Third Great Blunder", because
(a) it has nothing to do with the First and Second Great Blunders and (b) in
any case, I fear the book in question contains many more than just two logical
mistakes.
Anyway, KS suggests an alternative formulation:
SELECT 2
FROM dual
WHERE NOT EXISTS(
(SELECT * a
MINUS
SELECT *
FROM b)
UNION
(SELECT *
FROM b
MINUS
SELECT *
FROM a));
(I've replaced KS's MINUSes by EXCEPTs in order to conform to
the SQL standard.) This formulation is correct, too, but in context. I
prefer my corrected original, because it appeared in a chapter that was
concerned primarily with the relational calculus, not the relational
algebra. But it's not a big deal.
I note in passing that KS's suggested replacement formulation
relies, rather more than my (corrected) version does, on SQL's nonrelational
notion of there being a left-to-right ordering to the columns of a table. I
note too that neither my corrected version nor KS's suggested replacement works
properly if A or B is allowed to contain duplicates ... Taking
care of duplicates properly is left as a nasty exercise for the reader.
Posted
03/14/02
[ABOUT]
[QUOTES]
[LINKS]