Data & database · Easy

Db2 for i & SQL foundations

Build correct queries with joins, grouping, null handling, and safe parameters.

Learn this topic first: Db2 for i: SQL, cursors, commitment and isolation →

9 explained questions · 5 practice MCQs

Questions and answers

1. How do SQL tables, views, and indexes differ? (Easy)

A table holds rows. A view defines a query interface over data. An index provides an access structure the optimizer may choose. A view does not inherently guarantee an indexed access strategy, and an index does not replace a query’s result definition.

Choose each for its purpose: tables for persistence, views for a stable projection or restricted interface, and indexes for measured access needs. Database objects also have IBM i system representations, which matter to native consumers.

2. What is the difference between WHERE and HAVING? (Easy)

WHERE filters input rows before grouping. HAVING filters groups after aggregation. Putting a row condition in the wrong place can change totals or prevent a valid query.

For example, filter cancelled orders before calculating revenue by customer, then use HAVING to retain customers whose total exceeds a threshold. State the business definition of the total before optimizing the query.

Example

SELECT customer_id, SUM(amount) AS total
FROM app.orders WHERE status <> 'CANCELLED'
GROUP BY customer_id HAVING SUM(amount) > 1000;
3. How does SQL NULL differ from blanks or zero? (Easy)

NULL represents a missing or unknown value, not a particular numeric or character value. Comparisons involving NULL usually yield unknown, so use IS NULL rather than = NULL. Many aggregates ignore null operands; COUNT(*) counts rows while COUNT(column) counts non-null values.

Use COALESCE only when a replacement matches the business meaning. Converting an unknown payment amount to zero may make a report look complete while hiding a data-quality issue.

4. How can a LEFT JOIN accidentally become an inner join? (Intermediate)

A LEFT JOIN preserves unmatched left rows by supplying nulls for right-side columns. A WHERE predicate requiring a right-side value can reject those null-extended rows and remove the preservation you intended.

Place a right-side eligibility condition in ON when the requirement is to retain every left row but attach only qualifying matches. Validate the result with customers who have no orders and customers whose orders all fail the condition.

Example

SELECT c.id, o.id
FROM app.customer c LEFT JOIN app.orders o
  ON o.customer_id=c.id AND o.status='OPEN';
5. Why use parameter markers or host variables? (Intermediate)

They separate values from SQL statement structure, helping prevent SQL injection and reducing unnecessary variations in statement text. Embedded SQL uses host variables; prepared dynamic SQL commonly uses parameter markers.

Parameters do not substitute for arbitrary identifiers such as column names. For a selectable sort column, map an approved choice to known SQL text, and bind the value predicates. Also align parameter types with indexed columns to avoid unnecessary conversions.

Example

SELECT id FROM app.orders WHERE customer_id = ?
6. How do UNION and UNION ALL differ? (Intermediate)

UNION combines compatible result sets and removes duplicate result rows. UNION ALL retains duplicates and avoids that duplicate-elimination requirement. The right choice follows the required result semantics, not a universal performance rule.

If two sources can legitimately contain identical transactions, UNION may silently collapse information the report should retain. Apply a final ORDER BY when ordering is required; the order of the input SELECT statements does not establish a guaranteed output order.

7. When is EXISTS preferable to joining a child table? (Intermediate)

EXISTS tests whether a qualifying row is present. It is useful when the required output is one parent row if any matching child exists, rather than a row for every child. It expresses that intent without multiplying the parent by its matches.

Use it for customers with at least one overdue invoice, for example. Do not assume it is always faster than every join; inspect the actual plan. Its main advantage here is correct and clear cardinality.

Example

SELECT c.id FROM app.customer c
WHERE EXISTS (SELECT 1 FROM app.invoice i
 WHERE i.customer_id=c.id AND i.status='OVERDUE');
8. Can you rely on row order without ORDER BY? (Intermediate)

No. An access path used today does not create an SQL ordering contract. Different plans, statistics, data volume, or release levels can change the observed order. Include ORDER BY whenever output order is part of the requirement.

For paging, include a unique tie-breaker so equal sort values have a deterministic sequence. If data can change between pages, choose and document an appropriate consistency strategy. FETCH FIRST without a meaningful order does not reliably select the “latest” business rows.

9. Why does a join produce duplicate totals? (Advanced)

Check the cardinality at every join. Joining a header to both detail lines and payments can multiply rows when both sides are one-to-many. SUM then counts the same line multiple times even though each join predicate is individually valid.

Aggregate each child to the intended grain before joining, or use EXISTS for a pure existence condition. State the desired output grain—one row per order, customer, or line—and verify it with a small case containing multiple children on both sides.

Example

2 order lines × 3 payments can produce 6 joined rows.

Interview pitfall: DISTINCT may hide symptoms without repairing the aggregation logic.

Practice checkpoint

  1. 1. Which condition detects missing values?
    1. = NULL
    2. IS NULL
    3. = blanks
    4. IS ZERO
  2. 2. Which clause filters grouped totals?
    1. ON only
    2. ORDER BY
    3. HAVING
    4. FETCH FIRST
  3. 3. What preserves customers with no qualifying order?
    1. Require order status in WHERE
    2. Use an INNER JOIN
    3. Remove the customer table
    4. Put order eligibility in the LEFT JOIN ON clause
  4. 4. Can a parameter marker safely stand for any table name?
    1. No, validate identifiers separately
    2. Yes, in all statements
    3. Only if it contains quotes
    4. Only under *ALLOBJ
  5. 5. Two lines joined to three payments can yield how many rows?
    1. Two always
    2. Six
    3. Three always
    4. One always
Show answer key and explanations

1. B — IS NULL NULL is tested using IS NULL; ordinary equality does not produce true for unknown values.

2. C — HAVING HAVING applies conditions after grouping and aggregation.

3. D — Put order eligibility in the LEFT JOIN ON clause A right-side WHERE condition can reject unmatched rows.

4. A — No, validate identifiers separately Markers bind values, not arbitrary SQL identifiers or syntax.

5. B — Six Independent one-to-many joins can multiply rows; aggregate at the intended grain.

IBM documentation and further reading