tags:

views:

159

answers:

4
select Table1.colID, Table1.colName, 
(select * from Table2 where Table2.colID = Table1.colID) as NestedRows
from Table1

The above query gives you this error: Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used.....

Can anybody explain why this limitation exist?

I had this idea that this kind of multidimentional queries would be nice for building OO objects directly from the database with 1 query

EDIT:

This question is pretty theoretical. To solve this practical I would use a join or simply done 2 queries, but I wondered if there was anything stopping you from returning a column as a table type (In sql server 2008 you can create table types).

Say you have corrensponding classes in code, think Linq2Sql

public class Table1
{
  public int colID,
  public string colName,
  public List<Table2> table2s;
}

I would like to be able to fill instances of this class directly with 1 query

A: 

You would be better off using an INNER JOIN between the two tables and simply selecting the rows you want from each table.

SELECT tab1.colID, tab1.colName, tab2.Column1, tab2.column2
FROM dbo.Table1 AS tab1
    INNER JOIN dbo.Table2 AS tab2
        ON tab1.colID = tab2.colID

However, remember that the data from table1 will be repeated for each matching record in table2. Although I believe the query I posted will get the data in the form you are looking for, I don't think it's the best method for querying the database. I would either execute separate queries, or put the separate queries into a stored procedure and return multiple result sets.

NYSystemsAnalyst
If you really only want one row, you'll need to use a GROUP BY clause and suitable aggregate functions, or a TOP 1 with the original sub query (and a suitable ORDER BY clause).
Joel Coehoorn
But it doesn't sound like he only wants one row. From what I understand, he does indeed want multiple rows from Table2. I'm also operating on the assumption that table 1 contains the primary key for colID.
NYSystemsAnalyst
+2  A: 

Because the subquery in a select clause must be "inserted" into a column value in every row of the result set from the outer query. You cannot put a set of values into a single cell (a single column of a single row) of the result set.

You need to use an inner join. the multiple rows returned by joined table will be output as multiple rows in the final result set.

Charles Bretana
What if you had a column of type table? In sql server 2008 you can define types of table
TT
As far as I know "table" datatypes can be used for local variables, or to temporarily store a resultset for later processing. And can now be passed to/from T-SQL code from external clients, but you still can't declare a column in a table as a "table". Anyone know otherwise?
Charles Bretana
A: 

I think the query you're looking for is probably:

select Table1.colID, Table1.colName,Table2.*
from Table1 inner join Table2 ON Table1.colID = Table2.colID

Subqueries are more typically used (at least by me) in the WHERE clause.

Dana
+3  A: 

It appears as though you want a recordset (multiple columns and multiple rows) returned from Table2 for each row in table1. If this is correct, perhaps you could return the data as XML from the DB. Something like this...

select Table1.colID, Table1.colName, Table2.*
from   Table1
       Inner Join Table2
         On Table1.ColId = Table2.ColId
Order By Table1.ColId
For XML Auto

Then, for each row in Table1, you'll get multiple sub-nodes in your XML for table2 data.

There's likely to be performance implications with returning XML from your database, as well as loading your data structure on the front end. I'm not necessarily suggesting this is the best approach, but it's probably worth investigating.

G Mastros
This is pretty nice, was into the idea of "for xml" but did not try to write the sql as a join. Maybe it would be an idea with a Linq2SqlXML provider. Maybe a little performance overhead but so elegant I think it would be worth it :)
TT