SQL: Replacing part of query by subquery in FROM clause - sql

I have a database including a table called [Table] which lists all tables in that database. Now I want to write a SQL query using some JOINS, which gets a specific tablename from [Table] in a subquery to select from that table... I hope this is not too confusing.
So [Table] looks like this:
IdTable Tablename
1 Adress
2 Project
3 User
...
The query should look like this:
SELECT * FROM (SELECT Type FROM dbo.[Table] WHERE tablename = 12)
Would something like that be possible?
I know, that subqueries are possible, but I do not know how to do that in this case.
Thanks in advance.
Regards
Lars

Try this below dynamic code to get your expected result.
DECLARE #sqlCommand AS NVARCHAR(MAX)
DECLARE #TableName AS NVARCHAR(MAX)
SELECT #TableName = tablename FROM dbo.[Table] WHERE Type = 12
SET #sqlCommand= N'SELECT * FROM '+#TableName+''
EXEC (#sqlCommand)
Note: I guess you wants to select TableName where Type = 12 and I alter the selection and filtering accordingly.
You can also execute the query directly as below without creating the command string-
DECLARE #TableName AS NVARCHAR(MAX)
SELECT #TableName = tablename FROM dbo.[Table] WHERE Type = 12
EXEC (N'SELECT * FROM '+#TableName+'')

Related

Selecting columns in a table where table name is selected from another table and concatenate them selecting only specific columns

I have a table:
TableName rn
Tab_1 1
Tab_2 2
Tab_3 3
Tab_1, Tab_2 and Tab_3 are tables stored in the database.
What i want is to read all these tables using a loop, select specific columns (say col1, col2, and col3) and concatenate them.
What i tried was:
'''
DECLARE
#table NVARCHAR(128),
#sql NVARCHAR(MAX);
SET #table = N'select tablename from #db2 where rn=1';
SET #sql = N'SELECT * FROM ' + #table;
EXEC sp_executesql #sql;
'''
This query does not exactly concatenate the tables one by one but i am first trying to select the tables dynamically first before i use them in a loop. This does not seem to be working, it returns 'incorrect syntax near 'select''.
#db2 is the temp table that has all the table names.
I have looked at various methods but am not able to figure one out to suit this specific problem.
How do i go about working this out?
You are actually storing SQL select statement into #table by the Set Statement
SET #table = N'select tablename from #db2 where rn=1';
Due to which the final #sql has the statement like "SELECT * FROM select tablename from #db2 where rn=1"
While you need to set the value into #table by
Select #table = db.TableName From #db2 As db With (Nolock) Where db.rn = 1
Try this way, it will work. You need either use While Loop or Cursor for your requirments.

Find total number of data written in two same table from two different databases

I have been trying to write an easy query for my problem. I wrote something but it takes so long when I try to use it for 20 different database which is first I declare an integer than I keep adding the numbers that I summed each other it looks like this;
DECLARE #counter int
SET #counter = (SELECT COUNT(*) as TOTAL FROM database1.dbo.User);
SET #counter = #counter + (SELECT COUNT(*) as TOTAL FROM database2.dbo.User);
SET #counter = #counter + (SELECT COUNT(*) as TOTAL FROM database3.dbo.User);
PRINT #counter;
But I'm looking for an easier way because in my server there is more than 200 databases and I have to choose nearly 35 of them which there names starts same than they have numbers that defines them for example:
database1
database2
But other than that 35 of them are different names so I have to put something in my query that allows me to access the number of users in that database easily.
You could use the undocumented sp_MsForEachDb
The ? is replaced by the DB name.
Try something like:
CREATE TABLE #T (Total INT, DbName SYSNAME)
exec sp_MsForEachDb '
IF EXISTS (SELECT 1 FROM ?.sys.tables WHERE Name = ''Users'')
AND ''?'' LIKE ''Database%''
BEGIN
INSERT INTO #T(Total, DbName)
SELECT count(1) Total, ''?'' DbName
FROM ?.dbo.Users
END
'
SELECT *
FROM #T
--
-- WHERE DbName LIKE '%SOMECONDITION%'
To get the documentation you could execute: EXEC sp_helptext sp_msforeachdb
The following would also give you your desired results without creating a temp table:
declare
#sql varchar(max) = ''
, #maxid int = (select max(database_id) from sys.databases)
select #sql = #sql +
'select '''+name+''' DatabaseName, count(*) [Count] from '+quotename(name)+'.[dbo].[User]'+char(10)+ case when database_id = #maxid then '' else 'union all' end+char(10)
from sys.databases
where name not in ('master','model','msdb','tempdb')
order by database_id
print (#sql)
exec (#sql)
Note: You need to exclude databases that do not have the User Table in the database in the where clause, where I excluded the system databases...
Results will look like this before executing the Dynamic SQL:
For security reasons, I removed the actual Database Names on my machine...

Using variables inline SQL ( MSSQL )

Possible to do something like this... MSSQL ?
where the #myText variable equals a string of 'id = 5'
SELECT * FROM someTable WHERE ( #myText )
Thanks guys. With your help led me to using temporary tables like so....
DECLARE #companies TABLE (comp_code INT) -- create temporary table
INSERT INTO #companies VALUES (5) -- ( repeat this line for each additional company you wish to keep )
DELETE FROM tableOne Where (Comp_Code NOT IN (select comp_code from #companies));
DELETE FROM tableTwo Where (Comp_Code NOT IN (select comp_code from #companies));
DELETE FROM tableThree Where (Comp_Code NOT IN (select comp_code from #companies));
-- etc etc
You need to use dynamic SQL. In SQL Server, this looks like:
declare #sql nvarchar(max);
set #sql = 'SELECT * FROM someTable WHERE ([myText])';
set #SQL = replace(#sql, '[mytext]', #mytext);
exec sp_executesql #sql;

Dynamically choose table

There are two tables with the same structure (same columns, same column names, etc).
How can I design a query so that a certain table is queried from, depending on a variable?
DECLARE #MYVAR SMALLINT = 0;
DECLARE #TABLENAME VARCHAR(MAX);
SET #TABLENAME = CASE WHEN #MYVAR = 1 THEN 'TABLE1' ELSE 'TABLE2' END
SELECT #TABLENAME
-- HOW TO DYNAMICALLY SELECT TABLE NAME HERE?
SELECT TOP 1 * FROM #TABLENAME
Technet docs hint at maybe using a table alias here, but the examples don't show anything related to this.
As you mentioned, you need to build query dynamically and execute it
DECLARE #MYVAR SMALLINT = 0;
DECLARE #TABLENAME VARCHAR(MAX);
SET #TABLENAME = CASE WHEN #MYVAR = 1 THEN 'TABLE1' ELSE 'TABLE2' END
declare #sql = 'SELECT TOP 1 * FROM '+ quotename(#TABLENAME)
Exec (#sql) -- To execute the query that is built dynamically
Beside the obvious solution with dynamic SQL (which you would need especially if your column lists might not be the same) you can go like this:
DECLARE #tblName VARCHAR(100)='tbl1';
SELECT Col1, Col2, Col3
FROM tbl1
WHERE #tblName='tbl1'
UNION ALL
SELECT Col1, Col2, Col3
FROM tbl2
WHERE #tblName='tbl2'
The biggest advantage was, that this approach is inlineable, can be used as VIEW or better as inline TVF.
If you want to keep it in plain SQL (without the procedural part) it can be done like this:
SELECT * FROM TABLE1 WHERE #MYVAR = 1
UNION ALL
SELECT * FROM TABLE2 WHERE #MYVAR = 0
SQL Server should be smart enough to evaluate one of the conditions as "always false" and skip reading the other table. Consult EXPLAIN to confirm that.

T-Sql getting data from tempdb table

I'm using Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64) and I'm trying to make a SELECT statement to a table that have been created like this:
DECLARE #Sql AS VARCHAR(1500)
SET #Sql = 'SELECT 1 AS id, ''123'' AS value INTO #tmp_prueba'
EXECUTE ( #Sql )
SELECT * FROM #tmp_prueba
But I'm noticed that the table not exists
How can I get the data from the table?
The temporary table that you created in #sql is out-of-scope of the outer query.
Here is one way to do what you want:
DECLARE #Sql AS VARCHAR(1500);
SET #Sql = 'SELECT 1 AS id, ''123'' AS value INTO #tmp_prueba;
select * from #tmp_prueba'
create table #tmp_prueba (id int, value varchar(255));
insert into #tmp_prueba
EXECUTE( #Sql );
SELECT * FROM #tmp_prueba
Here are the changes. FIrst, I select everything from the temproary table in the #sql query. Second, I create a temporary table (with the same name in this case) to hold the results. Now, I can insert the results from the execute into the table. Voila! The data is there.
Temp table are created on Tempdb, therefor you can also do this:
SET #Sql = 'SELECT 1 AS id, ''123'' AS value INTO ##tmp_prueba'
EXECUTE ( #Sql )
Select * from tempdb..##tmp_prueba