""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
SQL TIP: COMPARE HEADERS & DETAILS
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
PRODUCT : R:BASE VERSION : 3.1
CATEGORY : SQL SUBCATEGORY : COMPARISONS
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Replace programs, complex reports, and relational commands with SQL to
achieve maximum performance.
We've had several requests for a SELECT command that will list all the
rows where a total in a header (master) row doesn't match the total of
all the detail values as stored in that transaction's detail row.
Here's a solution using the CONCOMP database as the example. In
CONCOMP, the TRANSMASTER table is on the one side of a one-to-many
relationship, and TRANSDETAIL is on the many side. They're related by
the TRANSID column.
TRANSMASTER holds the total dollar figure for a given transaction in
its NETAMOUNT column, and TRANSDETAIL has a total for each detail row
in its EXTPRICE column.
The following SELECT command lists those TRANSID values where the sum
of the details is not equal to the total shown in the master row:
SELECT t2.transid, +
MAX(t1.netamount), SUM(t2.extprice) +
FROM transmaster t1, transdetail t2 +
WHERE (t1.transid = t2.transid) +
GROUP BY t2.transid HAVING +
SUM(t2.extprice) <> MAX(t1.netamount)
You have to use the maximum of the NETAMOUNT column instead of just
listing NETAMOUNT in the SELECT list because you're not grouping by
NETAMOUNT. If R:BASE saw a bare column name in the SELECT list, it
would expect to see that column in the GROUP BY clause. Therefore, you
have to use a SELECT function. Because there's only one row, you can
use any of these functions and still get the same answer: AVG, MIN, or
MAX.