Is it possible to use a subquery more than once? - sql

I was wondering if it was possible to use a subquery in SQL more than once.
For example:
with subQuery as (
select id from someTable1
)
update someTable2
set someValue = 1
where id in (select * from subQuery)
select * from someTable2
where id in (select * from subQuery)
...
As of right now, SQL throws an error on the (select * from subQuery) in the select * someTable2 clause saying "Invalid Object Name subQuery". So is there a way to use subQuery more than once without having to add a table or run the query multiple times changing out the first statement?

A CTE is in scope only for a single query, but a query can both UPDATE and OUTPUT data. eg
with subQuery as (
select id from someTable1
)
update someTable2
set someValue = 1
output inserted.*
where id in (select * from subQuery)

Related

SQL Server Database Error: Only one expression can be specified in the select list when the subquery is not introduced with EXISTS

Can any one please help me regarding that error in SQL server
" SQL Server Database Error: Only one expression can be specified in the select list when the subquery is not introduced with EXISTS."
select * from
(select row_number() over ( order by (select null) ) rn,
(select distinct test1,test2,test3
from table1
where table1.test1= 1
EXCEPT
select distinct test1,test2,test3
from table2
where table2.test1= 1)
)
where rn between 0 and 100
Try this:
select * from
(select row_number() over ( order by (select null) ) rn,a.test1,a.test2,a.test3
from (select distinct test1,test2,test3
from table1
where table1.test1= 1
EXCEPT
select distinct test1,test2,test3
from table2
where table2.test1= 1) a
) b
where b.rn between 0 and 100
There are multi errors in your query:-
First one:-
Incorrect syntax near the keyword 'where'
Fix: Type alias for derived table (I am gonna type myTable as an alias below)
second one:-
No column name was specified for column 2 of 'myTable'
Fix: Type alias for derived column (I am gonna type myCol as an alias below)
Third one:- (Thant you mentioned in your question)
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Reason: You can't return two (or multiple) columns in your subquery.
The resolved Query:-
select * from
(
select
row_number() over ( order by (select null) ) rn,
(
select distinct test1
from table1
where table1.test1= 1
EXCEPT
select distinct test1
from table2
where table2.test1= 1
) myCol
) myTable
where rn between 0 and 100
Maybe the result is not what you need, but unless this a working query and now you have the keys for handling yours as your needs.

Choose which query will be used / Conditional query in Oracle

I have two queries, query1 and query2. What I would like to do is, if returned rows of query1 is empty, return query2 instead. Is that possible using basic SQL query alone? They have same returning columns btw, but different table sources.
eg:
query1:
SELECT name, message
FROM table1
query2:
SELECT name, message
FROM table 2
If query1 is empty, return name, message from query2.
This will select from table1 if not empty, otherwise select from table2:
SELECT * FROM table1
WHERE EXISTS (select * from table1)
UNION ALL
SELECT * FROM table2
WHERE NOT EXISTS (select * from table1)
This checks if table1 has no rows:
EXISTS (SELECT * FROM TABLE)
Found an answer here: https://stackoverflow.com/a/25122516/3747493
Basically:
SELECT *
FROM table1
UNION ALL
SELECT *
FROM table2
WHERE (SELECT COUNT(*) FROM table1) = 0
Thanks guys!

Using a value from one query in second query sql

SELECT AS, COUNT(*)
FROM Table1
HAVING COUNT(AS)>1
group BY AS;
This produces the result
AS COUNT
5 2
I then want to use the AS value in another query and only output the end result. Is this possible.i was thinking something like.
SELECT *
FROM
TABLE 2
Where AS =(
SELECT AS, COUNT(*)
FROM Table1
HAVING COUNT(AS)>1
group BY AS;
);
This is called a subquery. To be safe, you would use in instead of = (and as is a bad name for a column, because it is a SQL key word):
SELECT *
FROM TABLE2
WHERE col IN (SELECT col
FROM Table1
GROUP BY col
HAVING COUNT(col) > 1
);
Your first query is also incorrect, because the having clause goes after the group by.
You could use a subquery with the in operator:
SELECT *
FROM table2
WHERE AS IN (SELECT AS
FROM table1
GROUP BY AS
HAVING COUNT(*) > 1)

Count rows in more than one table with tSQL

I need to count rows in more than one table in SQL Server 2008. I do this:
select count(*) from (select * from tbl1 union all select * from tbl2)
But it gives me an error of incorrect syntax near ). Why?
PS. The actual number of tables can be more than 2.
In case you have different number of columns in your tables try this way
SELECT count(*)
FROM (
SELECT NULL as columnName
FROM tbl1
UNION ALL
SELECT NULL
FROM tbl2
) T
try this:
You have to give a name to your derived table
select count(*) from
(select * from tbl1 union all select * from tbl2)a
I think you have to alias the SELECT in the FROM clause:
select count(*)
from
(
select * from tbl1
union all
select * from tbl2
) AS SUB
You also need to ensure that the * in both tables tbl1 and tbl2 return exactly the same number of columns and they have to be matched in their type.
I don't like doing the union before doing the count. It gives the SQL optimizer an opportunithy to choose to do more work.
AlexK's (deleted) solution is fine. You could also do:
select (select count(*) from tbl1) + (select count(*) from tbl2) as cnt

Sql inner query issue

I have a table tbl_test:
create table tbl_test (
tabid int identity
)
with the values:
Insert into tbl_test values 1 union 2 union 3 .... union 1000
Query:
select MAX(b.tabid) from
(
select top 100 * from tbl_test
) as b
I expect this query to return 100 but instead it returns 1000.
select top 100 * from tbl_test
There is no explicit order on the inner statement, so there is no guarentee in which order the rows are read. If you order it by tabid ASC you should see the expected 100.
You're not including an order by clause in your subquery (which is allowed in conjunction with TOP), so there's no telling what records will come back. 1000 is obviously being included in the data returned from the subquery, which means it will be returned by MAX.