Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I treat a subquery with one row and one column as a scalar?

Tags:

sql

sql-server

Suppose I have the following SQL (which can be run against the Data Explorer, if you'd like):

SELECT COUNT(Id) AS "Count" 
  INTO #temp 
  FROM Posts
  
PRINT (SELECT * FROM #temp)

This produces an error:

"Subqueries are not allowed in this context. Only scalar expressions are allowed."

Now, in this case, I know that #temp is a table of one row and one column, and hence that (SELECT * FROM #temp) will produce only one value. Is there any way to persuade SQL Server to treat it as a scalar?

I am aware that I can save it off to a variable and then PRINT that instead:

DECLARE @count int = (SELECT * FROM #temp)
PRINT @count

But this seems like an extra step that shouldn't be necessary.

like image 640
senshin Avatar asked Jul 14 '15 20:07

senshin


People also ask

Can a subquery be scalar?

A scalar subquery is a subquery that returns a single value. This is the simplest form of a subquery, and can be used in most places a literal or single column value is valid. The data type, length and character set and collation are all taken from the result returned by the subquery.

What is a scalar subquery Cannot be used in?

You can use scalar subqueries in most statements that call for an expression. Scalar subqueries are not valid expressions in the following cases: As default values for expressions. In GROUP BY and HAVING clauses.

How many columns can you SELECT using a scalar subquery?

A scalar subquery is a subquery that selects only one column or expression and returns one row.


1 Answers

No this isn't possible according to the grammar.

The only way of doing it other than assigning to a variable at the same scope would be to wrap the select in a UDF as far as I can see.

The documentation States

PRINT msg_str | @local_variable | string_expr

msg_str Is a character string or Unicode string constant. For more information, see Constants (Transact-SQL).

@ local_variable Is a variable of any valid character data type. @local_variable must be char, nchar, varchar, or nvarchar, or it must be able to be implicitly converted to those data types.

string_expr Is an expression that returns a string. Can include concatenated literal values, functions, and variables. For more information, see Expressions (Transact-SQL).

So assuming that "functions" includes user defined functions and not just built in functions this would work. Otherwise you're out of luck.

And for your specific use case you are certainly out of luck as, even ignoring the ridiculousness of creating a scalar UDF for this, they can't access temp tables anyway.

like image 71
Martin Smith Avatar answered Sep 28 '22 03:09

Martin Smith