tags:

views:

41

answers:

4

Can anyone give me a good example of a subquery using TSQL 2008?

+1  A: 
SELECT
    *,
    (SELECT TOP 1 SomeColumn FROM dbo.SomeOtherTable)
FROM
    dbo.MyTable
Timothy Khouri
That's a subSELECT, a subquery in the SELECT clause
OMG Ponies
@OMG Ponies: Again, have a look at MSDN (http://msdn.microsoft.com/en-us/library/ms176104.aspx). "expression" is defined as "Is a constant, function, any combination of column names, constants, and functions connected by an operator or operators, or a subquery.". You are making distinctions between terms that actually mean the same.
Maximilian Mayerl
+1  A: 
SELECT     a.*, b.*
FROM       TableA AS a
INNER JOIN
(
    SELECT *
    FROM   TableB
) as b
ON        a.id = b.id

Thats a normal subquery, running once for the whole result set.

On the other hand

SELECT     a.*, (SELECT b.somecolumn FROM TableB AS b WHERE b.id = a.id)
FROM       TableA AS a

is a correlated subquery, running once for every row in the result set.

Maximilian Mayerl
The first example is a derived table (AKA inline view), not a subquery. The second is a subselect...
OMG Ponies
That depends on your definition of subquery. Have a look at the MSDN page for FROM, especially the part about "derived_table": "Is a subquery that retrieves rows from the database. ...". http://msdn.microsoft.com/en-us/library/ms177634.aspxI would define subquery as just a query that is nested inside a query.
Maximilian Mayerl
........O RLY? ;)
OMG Ponies
@OMG Ponies: Ya, rly...I didn't say there is no difference between my two examples. But there are no "official" distinct terms for them. You may call them inline view or subselect, and that may be right (it is, I admit), but that doesn't mean that they aren't subqueries ;)
Maximilian Mayerl
OMG Ponies
@OMG Ponies: Why should I delete it? I already admitted that you can use more specific terms for various types of subqueries, but that doesn't make your comment about them not being subqueries correct. But let's quit arguing like this, it's no use anyway :)
Maximilian Mayerl
Sorry - couldn't hear you over the sound of your backpedalling
OMG Ponies
+2  A: 

For variety's sake, here's one in the where clause:

select 
    a.firstname,
    a.lastname
from
    employee a
where
    a.companyid in (
        select top 10
            c.companyid
        from
            company c
        where
            c.num_employees > 1000
        )

...returns all employees in the top ten companies with over 1000 employees.

Ken Redler
+1: An actual subquery
OMG Ponies
+3  A: 

Maximilian Mayer believes that, due to referencing MS documentation, my assertion that there is a difference between a subquery and a subSelect is incorrect. Frankly, I'd consider MSDN's "Subquery Fundamentals" a better choice. Quote:

You are making distinctions between terms that actually mean the same.

O RLY?

A subQUERY...

IE:

WHERE id IN (SELECT n.id FROM TABLE n)
   OR id = (SELECT MAX(m.id) FROM TABLE m) 
   OR EXISTS(SELECT 1/0 FROM TABLE) --won't return a math error for division by zero

...affects the WHERE or HAVING clauses -- the filteration of data -- for a SELECT, INSERT, UPDATE or DELETE statement. The value from a subquery is never directly visible in the SELECT clause.

A subSELECT...

IE:

SELECT t.column,
       (SELECT x.col FROM TABLE x) AS col2
  FROM TABLE t

...does not affect the filteration of data in the main query, and the value is exposed directly in the SELECT clause. But it's only one value - you can't return two or more columns into a single column in the outer query.

A subselect is a consistent means of performing a LEFT JOIN in ANSI-89 join syntax - if there is no supporting row, the column will be null. Additionally, a non-correlated subselect will return the same value for every row of the main query.

Correlation

If a subquery or subselect is correlated, that query runs once for every record of the main query returned -- which doesn't scale well as the number of rows in the result set increases.

Derived Table/Inline View

IE:

SELECT x.*,
       y.max_date,
       y.num
  FROM TABLE x
  JOIN (SELECT t.id,
               t.num,
               MAX(t.date) AS max_date
          FROM TABLE t
      GROUP BY t.id, t.num) y ON y.id = x.id

...is a JOIN to a derived table (AKA inline view).
"Inline view" is a better term, because that is all that happens when you reference a non-materialized view -- a view is just a prepared SQL statement. There's no performance or efficiency difference if you create a view with a query like the one in the example, and reference the view name in place of the SELECT statement within the brackets of the JOIN. The example has the same information as a correlated subquery, but the performance benefit of using a join and none of the subquery detriments. And you can return more than one column, because it is a view/derived table.

Conclusion

It should be obvious why I and others make distinctions. The concept of relying on the word "subquery" to categorize any SELECT statement that isn't the main clause is fatality flawed, because it's also a specific case under a categorization of the same word (IE: subquery-subselect, subquery-subquery, subquery-join...). Now think of helping someone who says "I've got a problem with a subquery..."

Maximilian Mayer's idea of "official" documentation was written by technical writers, who often have no experience in the subject and are only summarizing what they've been told to from knowledgeable people who have simplified things. Ultimately, it's just text on a page or screen -- like what you're reading now -- and the decision is up to you if the details I've laid out make sense to you.

OMG Ponies
As stated in my comment to my own answer: Yes, there is a difference between the concepts you are showing here, and I never said there isn't one. Yes, you can use different terms for these concepts, but they aren't "official". And even if they were, they are subtyped of subqueries, which means that it would never be wrong to just call them "subquery". And that makes your comment "The first example is a derived table (AKA inline view), not a subquery." wrong. It IS a subquery. You may call it inline view to be more precise, but it still is a subquery.
Maximilian Mayerl