Disjunction of subquery predicates

The SQL89 standard allows for several forms of subquery predicates. Each subquery can appear within the WHERE or HAVING clause with other predicates, and can be combined using the AND or OR operators. Sybase IQ supports these subqueries, which can be correlated (contain references to a table that appears in the outer query and cannot be evaluated independently) and uncorrelated (do not contain references to remote tables).

The forms of subquery predicates include:

The types of queries you can run include:

The SUBQUERY_CACHING_PREFERENCE option lets experienced DBAs choose which subquery caching method to use. See SUBQUERY_CACHING_PREFERENCE option in Reference: Statements and Options.

Examples

Example 1 Disjunction of uncorrelated EXISTS and IN subqueries:

SELECT COUNT(*)
FROM supplier 
WHERE s_suppkey IN (SELECT MAX(l_suppkey) 
            FROM lineitem 
            GROUP BY l_linenumber) 
OR EXISTS (SELECT p_brand 
      FROM part 
      WHERE p_brand = ‘Brand#43’);

Example 2 Disjunction of uncorrelated EXISTS subqueries:

SELECT COUNT(*)
FROM supplier 
WHERE EXISTS (SELECT l_suppkey 
        FROM lineitem 
        WHERE l_suppkey = 12345) 
OR EXISTS   (SELECT p_brand 
        FROM part 
        WHERE p_brand = ‘Brand#43’);

Example 3 Disjunction of uncorrelated scalar or IN subquery predicates:

SELECT COUNT(*) 
FROM supplier 
WHERE s_acctbal*10 > (SELECT MAX(o_totalprice) 
             FROM orders 
             WHERE o_custkey = 12345)
OR substring(s_name, 1, 6) IN (SELECT c_name 
                  FROM Customers 
                  WHERE c_nationkey = 10);

Example 4 Disjunction of correlated/uncorrelated quantified comparison subqueries:

SELECT COUNT(*) 
FROM lineitem 
WHERE l_suppkey > ANY (SELECT MAX(s_suppkey)
              FROM supplier 
              WHERE s_acctbal >100 
              GROUP BY s_nationkey) 
OR l_partkey >= ANY (SELECT MAX(p_partkey) 
            FROM part 
            GROUP BY p_mfgr);

Example 5 Disjunction of any correlated subquery predicates:

SELECT COUNT(*) 
FROM supplier S 
WHERE EXISTS (SELECT l_suppkey 
        FROM lineitem 
        WHERE l_suppkey = S.s_suppkey) 

OR EXISTS (SELECT p_brand FROM part 
      WHERE p_brand = ‘Brand#43’ 
       AND p_partkey > S.s_suppkey);

Before support for disjunction of subqueries, users were required to write queries in two parts, and then use UNION to merge the final results.

The following query illustrates a merged query that gets the same results as the query in “Example 5”. Performance of the merged query is suboptimal because it scans the supplier table twice and then merges the results from each UNION to return the final result.

SELECT COUNT(*)
FROM (SELECT s_suppkey FROM supplier S
   WHERE EXISTS (SELECT l_suppkey
           FROM lineitem
           WHERE l_suppkey = S.s_suppkey)
UNION 

SELECT s_suppkey
FROM supplier S
WHERE EXISTS (SELECT p_brand
        FROM part
        WHERE p_brand = ‘Brand#43’
         AND p_partkey > S.s_suppkey)) as UD;