MS SQL Server
  Home arrow MS SQL Server arrow Page 5 - Subqueries and Query Expressions
ASP Free Forums 
.NET  
ASP  
ASP Code  
ASP.NET  
ASP.NET Code  
BrainDump  
C#  
Code Examples  
Database  
Database Code  
IIS  
Microsoft Access  
MS SQL Server  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
ASP Web Hosting  
ASP.NET Web Hosting 
Mobile Linux 
App Generation ROI 
Windows Web Hosting
 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
MS SQL SERVER

Subqueries and Query Expressions
By: McGraw-Hill/Osborne
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 19
    2005-02-23

    Table of Contents:
  • Subqueries and Query Expressions
  • What Is a Subquery?
  • Outer References
  • The Set Membership Test (IN)
  • The ANY Test *
  • Subqueries and Joins
  • Subqueries in the HAVING Clause *
  • The CAST Expression (SQL2)
  • The NULLIF Expression (SQL2)
  • Row-Valued Comparisons (SQL2)
  • The SQL2 Query Specification
  • Query Expressions in the FROM Clause

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Subqueries and Query Expressions - The ANY Test *


    (Page 5 of 12 )

    The ANY test is used in conjunction with one of the six SQL comparison operators (=, <>, <, <=, >, >=) to compare a single test value to a column of data values produced by a subquery. To perform the test, SQL uses the specified comparison operator to compare the test value to each data value in the column, one at a time. If any of the individual comparisons yield a TRUE result, the ANY test returns a TRUE result.

    Here is an example of a request that can be handled with the ANY test:

    List the salespeople who have taken an order that represents more than 10 percent of their quota.

    SELECT NAME
      FROM SALESREPS
     WHERE (.1 * QUOTA) < ANY (SELECT AMOUNT
                               FROM ORDERS
                              WHERE REP = EMPL_NUM)

    NAME

    --------------

    Sam Clark
    Larry Fitch
    Nancy Angelli

    Conceptually, the main query tests each row of the SALESREPS table, one by one. The subquery finds all of the orders taken by the current salesperson and returns a column containing the order amounts for those orders. The WHERE clause of the main query then computes 10 percent of the current salesperson’s quota and uses it as a test value, comparing it to every order amount produced by the subquery. If any order amount exceeds the calculated test value, the ANY test returns TRUE, and the salesperson is included in the query results. If not, the salesperson is not included inthe query results. The keyword SOME is an alternative for ANY specified by the ANSI/ISO SQL standard. Either keyword can generally be used, but some DBMS brands do not support SOME.

    The ANY test can sometimes be difficult to understand because it involves an entire set of comparisons, not just one. It helps if you read the test in a slightly different way than it appears in the statement. If this ANY test appears:

      WHERE X < ANY (SELECT Y …)


    instead of reading the test like this:


    "where X is less than any select Y…"

    try reading it like this:

    "where, for some Y, X is less than Y"

    When you use this trick, the preceding query becomes:

    Select the salespeople where, for some order taken by the salesperson, 10 percent of the salesperson’s quota is less than the order amount.

     If the subquery in an ANY test produces no rows of query results, or if the query results include NULL values, the operation of the ANY test may vary from one DBMS to another. The ANSI/ISO SQL standard specifies these detailed rules describing the results of the ANY test when the test value is compared to the column of subquery results:

    • If the subquery produces an empty column of query results, the ANY test returns FALSE—there is no value produced by the subquery for which the comparison test holds.

    • If the comparison test is TRUE for at least one of the data values in the column, then the ANY search condition returns TRUE—there is indeed some value produced by the subquery for which the comparison test holds.

    • If the comparison test is FALSE for every data value in the column, then the ANY search condition returns FALSE. In this case, you can conclusively state that there is no value produced by the subquery for which the comparison test holds.

    • If the comparison test is not TRUE for any data value in the column, but it is NULL (unknown) for one or more of the data values, then the ANY search condition returns NULL. In this situation, you cannot conclusively state whether there is a value produced by the subquery for which the comparison test holds; there may or may not be, depending on the “actual” (but currently unknown) values for the NULL data.

    The ANY comparison operator can be very tricky to use in practice, especially in conjunction with the inequality (<>) comparison operator. Here is an example that shows the problem:

    List the names and ages of all the people in the sales force who do not manage an office.

    It’s tempting to express this query as shown in this example:

     SELECT NAME, AGE
      FROM SALESREPS
     WHERE EMPL_NUM <> ANY (SELECT MGR
                                                            FROM OFFICES)

    The subquery:

    SELECT MGR
       FROM OFFICES

    obviously produces the employee numbers of the managers, and therefore the query seems to be saying:

    Find each salesperson who is not the manager of any office.

    But that’s not what the query says! What it does say is this:

    Find each salesperson who, for some office, is not the manager of that office.

    Of course for any given salesperson, it’s possible to find some office where that salesperson is not the manager. The query results would include all the salespeople and therefore fail to answer the question that was posed! The correct query is:

     SELECT NAME,  AGE
       FROM SALESREPS
      WHERE NOT  (EMPL_NUM = ANY  (SELECT MGR
                                                             FROM OFFICES

     

      NAME AGE          AGE

      ---------------   -----

    Mary Jones            31
    Sue Smith              48
    Dan Roberts          45
    Tom Snyder           41
    Paul Cruz                29
    Nancy Angelli        49

     

    The ALL Test *

    Like the ANY test, the ALL test is used in conjunction with one of the six SQL comparison operators (=, <>, <, <=, >, >=) to compare a single test value to a column of data values produced by a subquery. To perform the test, SQL uses the specified comparison operator to compare the test value to each data value in the column, one at a time. If all of the individual comparisons yield a TRUE result, the ALL test returns a TRUE result

    Here is an example of a request that can be handled with the ALL test:

    List the offices and their targets where all of the salespeople have sales that exceed 50 percent of the office’s target.

    SELECT CITY,  TARGET
      FROM OFFICES
     WHERE (.50 * TARGET) < ALL (SELECT SALES
                                                                FROM SALESREPS
                                                           WHERE REP_OFFICE = OFFICE)

             CITY                      TARGET

            -----------   --------------

    Denver $300,000.00
    New York $575,000.00
    Atlanta $350,000.00

    Conceptually, the main query tests each row of the OFFICES table, one by one. The subquery finds all of the salespeople who work in the current office and returns a column containing the sales for each salesperson. The WHERE clause of the main query then computes 50 percent of the office’s target and uses it as a test value, comparing it to every sales value produced by the subquery. If all of the sales values exceed the calculated test value, the ALL test returns TRUE, and the office is included in the query results. If not, the office is not included in the query results.

    Like the ANY test, the ALL test can be difficult to understand because it involves an entire set of comparisons, not just one. Again, it helps if you read the test in a slightly different way than it appears in the statement. If this ALL test appears:

    WHERE X < ALL (SELECT Y …)

    instead of reading it like this:

    "where X is less than all select Y…"

    try reading the test like this:

    "where, for all Y, X is less than Y"

    When you use this trick, the preceding query becomes:

    Select the offices where, for all salespeople who work in the office, 50 percent of the office’s target is less than the salesperson’s sales.

    If the subquery in an ALL test produces no rows of query results, or if the query results include NULL values, the operation of the ALL test may vary from one DBMS to another. The ANSI/ISO SQL standard specifies these detailed rules describing the results of the ALL test when the test value is compared to the column of subquery results:

    • If the subquery produces an empty column of query results, the ALL test returns TRUE. The comparison test does hold for every value produced by the subquery; there just aren’t any values.

    • If the comparison test is TRUE for every data value in the column, then the ALL search condition returns TRUE. Again, the comparison test holds true for every value produced by the subquery.

    • If the comparison test is FALSE for any data value in the column, then the ALL search condition returns FALSE. In this case, you can conclusively state that the comparison test does not hold true for every data value produced by the query.

    • If the comparison test is not FALSE for any data value in the column, but it is NULL for one or more of the data values, then the ALL search condition returns NULL. In this situation, you cannot conclusively state whether there is a value produced by the subquery for which the comparison test does not hold true; there may or may not be, depending on the “actual” (but currently unknown) values for the NULL data.

    The subtle errors that can occur when the ANY test is combined with the inequality (<>) comparison operator also occur with the ALL test. As with the ANY test, the ALL test can always be converted into an equivalent EXISTS test by moving the comparison inside the subquery.

    This article is excerpted from MySQL The Complete Reference by Vikram Vaswani (McGraw-Hill, 2003; ISBN 0072224770). Check it out at your favorite bookstore today. Buy this book now.

    More MS SQL Server Articles
    More By McGraw-Hill/Osborne


     

    MS SQL SERVER ARTICLES

    - Completing the Introduction to Transact-SQL
    - A Brief Introduction to Transact-SQL
    - Lookups and Blocking Bad Data
    - Field Validation Rules for Blocking Bad Data
    - Using Masks to Block Bad Data
    - Blocking Bad Data
    - Using @@ROWCOUNT and TABLE Variables for Dat...
    - How to Use Variables, IF and CASE in Databas...
    - Creating Important Aspects of Notification S...
    - Working wth Variables in Database Interactio...
    - Delving Deeper into Notification Services
    - Notification Services
    - Building a Multi-table Report with SQL 2005 ...
    - A Secure Way of Building Connection Strings
    - Transferring a Database Using the SSIS Desig...





    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 4 hosted by Hostway
    Stay green...Green IT