Pull Table Information from code - sql

I have a table in SQL Server 2012 with 3 columns:
RDDID, SPDESC, SQLTEXT
Column SQLTEXT contains inline queries.
Is it possible to extract all table names from SQLTEXT and put them into a separate column?
INPUT:
RDDID|SPDESC|SQLTEXT
10XH1|DAGASC|SELECT COL1 FROM TABLE1 AS A JOIN TABLE2 B ON A.ID=B.ID JOIN TABLE3 AS C ON A.ID=C.ID
OUTPUT
RDDID|SPDESC|COLX1|COLX2|COLX3|
10XH1|DAGASC|TABLE1|TABLE2|TABLE3
Please share your thoughts.

If you could TRY Regex or any simple technique to split the line with delimiter[space],
You could try the following:
declare #query varchar(1000) = 'SELECT COL1 FROM TABLE1 AS A JOIN TABLE2 B ON A.ID=B.ID JOIN TABLE3 AS C ON A.ID=C.ID'
select b.name, 'ColX'+ cast(row_number() over( order by (select 0)) as varchar) as rn into #temp
from dbo.RegExSplit(' ',#query,1) a join sys.tables b on a.match = b.name
declare #cols varchar(100)
select #cols =
stuff((select ',' +rn from #temp for xml path('')),1,1,'')
exec('select * from #temp pivot(max(name) for rn in ('+#cols+' ))piv')
drop table #temp

Related

Show value of particular column as Header in SQL Server

I am creating a web app in which I have a requirement where I want to display a column value as a header
Example
SELECT Name, Leave
FROM tblUser
INNER JOIN tblLeaveMaster ON tblUser.EmployeeID = tblLeaveMaster.EmployeeID
From that query, I get these results:
Name Leave
---------------
Test1 5
Test2 10
test3 2
Now I want to get these values as
Test1 Test2 Test3
-----------------
5 10 2
How can I achieve this?
You can try using pivot
select pv.* from
(SELECT Name,Leave
FROM tblUser INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
)X
pivot
(max(leave) for name in ([Test1],[Test2],[Test3])) as pv
For Dynamic PIVOT
declare #sql varchar(max)='',#col_list varchar(8000)=''
set #col_list = (select distinct quotename([Name])+',' from (SELECT Name,Leave
FROM tblUser INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
)X
for xml path(''))
set #col_list = left (#col_list,len(#col_list)-1)
set #sql = 'select '+#col_list+' from
(SELECT Name,Leave
FROM tblUser INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
)X
pivot (max([Leave]) for [Name] in ('+#col_list+'))pv'
exec(#sql)
try by using case when
select max( case when name='Test1' then Leave end) as test1,
max( case when name='Test2' then Leave end) as test2,
max( case when name='Test3' then Leave end) as test3 from
tblUser INNER JOIN tblLeaveMaster
ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
You can try to use condition aggregate function. CASE WHEN with MAX or MIN
SELECT
MAX(CASE WHEN Name = 'Test1' THEN Leave END) Test1,
MAX(CASE WHEN Name = 'Test2' THEN Leave END) Test2,
MAX(CASE WHEN Name = 'Test3' THEN Leave END) Test3
FROM tblUser
INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
EDIT
If your column want to create dynamic you can try to use Dynamic PIVOT
create your SQL statement and make condition aggregate function by connect SQL string. then use execute it Dynamically.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ', MAX(CASE WHEN Name = ''' + Name+''' THEN Leave END) ' + QUOTENAME(Name)
FROM tblUser
INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #query= 'SELECT '+ #cols+'
FROM tblUser
INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID'
execute(#query)
sqlfiddle
You can find your result from the query as shown below. Here I have taken your query output in a temporary table.
Create table #finalData(ColName Varchar(30), Leave INT)
INSERT INTO #finalData Values('Test1', 5),('Test2', 10),('Test3', 2)
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.ColName)
FROM #finalData c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT ' + #cols + ' from
(
select ColName
, Leave
from #finalData
) x
pivot
(
max(Leave)
for ColName in (' + #cols + ')
) p '
execute(#query)
DROP TABLE #finalData
Hope this will help you.
The output is as shown below
Test1 Test2 Test3
5 10 2
select pv.* from
(SELECT Name,Leave
FROM tblUser INNER JOIN tblLeaveMaster ON tblUser.EmployeeID=tblLeaveMaster.EmployeeID
)X
pivot
(max(leave) for name in ([Test1],[Test2],[Test3])) as pv
Note:- this work for me but how to use where condition base on dropdown list selected value.
eg: if wants to show only 2020 and not 2019.

Combining multiple tables in SQL

I need a result set of multiple tables combined.
I have a query with a from clause using a table for each country that are selected in the parameter.
Ex:
#prmCountry='AU,UK,US'
Now in the from clause the table name is as such that it has to run for each country separately:
from tbl_abc t1
left outer join tbl_country_(CountryName) t2
on.....
How to exactly do this?
As your question is not more clear, but you are looking in some dynamic SQL Query :
DECLARE #prmCountry VARCHAR(MAX)= 'AU,UK,US';
DECLARE #SQL NVARCHAR(MAX)= N'';
DECLARE #Query NVARCHAR(MAX);
SELECT #SQL+=N' left join table_'+CC.Country+' on table_'+CC.Country+'.<column> = t1.<column>'
FROM
(
SELECT split.a.value('.', 'NVARCHAR(MAX)') [Country]
FROM
(
SELECT CAST('<A>'+REPLACE(#prmCountry, ',', '</A><A>')+'</A>' AS XML) AS Country
) C
CROSS APPLY Country.nodes('/A') AS split(a)
) CC;
SET #Query = 'SELECT * FROM tbl_abc t1'+#SQL+';';
PRINT #Query;
--EXECUTE sp_executesql #query
SQL Query produce :
SELECT * FROM tbl_abc t1
left join table_AU on table_AU.<column> = t1.<column>
left join table_UK on table_UK.<column> = t1.<column>
left join table_US on table_US.<column> = t1.<column>;
In above, first Splited the #prmCountry values into rows form.
Create dynamic left join query with#prmCountry values
Use UNION ALL like this:
SELECT
tbl_abc t1
left outer join tbl_country_('AU') t2
on.....
UNION ALL
SELECT
tbl_abc t1
left outer join tbl_country_('US') t2
on.....
...and so on

How to sum values of multiple columns in SQL Server

SELECT
name
FROM
sys.all.column
WHERE object_id = (SELECT object_id
FROM sys.all_objects
WHERE name ='name of my table' and type = 'TT')
AND name NOT IN (list of columns that I don't need)
How do I sum all the values of the returned columns from the preceding SQL query?
Another option which does not require dynamic SQL, but only a CROSS APPLY or two
Just for fun, I add Min, Max, and Avg just to illustrate... Also added a PctOfTotal or Common-Size
Declare #YourTable table (ID int,CustName varchar(50),Sales_Jan int,Sales_Feb int,Sales_Mar int)
Insert into #YourTable values
(1,'John Smith',25,25,50),
(2,'Jane Doe' ,35,20,null)
Select A.*
,C.*
,PctOfTotal = Format(C.Total*1.0/Sum(C.Total) over (),'0.00%')
From #YourTable A
Cross Apply (Select XMLData=cast((Select A.* For XML RAW) as xml)) B
Cross Apply (
Select Total = Sum(Value)
,Min = Min(Value)
,Max = Max(Value)
,Avg = Avg(Value)
From (
Select Value = attr.value('.','int')
From B.XMLData.nodes('/row') as A(r)
Cross Apply A.r.nodes('./#*') AS B(attr)
Where attr.value('local-name(.)','varchar(100)') Like 'Sales_%'
--Or you can Exclude Specific Columns
--Where attr.value('local-name(.)','varchar(100)') not in ('ID','CustName')
) S
) C
Returns
If I understand correctly, you want to find out some columns from meta tables that you want to sum, and then sum those columns on the given table. You can use dynamic SQL to achieve this:
create table t(a integer, b integer, c integer);
insert into t values(1,2,3);
declare #tab varchar(100);
declare #sql varchar(max);
set #sql = '';
set #tab = 't';
select #sql = #sql + '+' + a.name from sys.all_columns a
inner join
sys.all_objects b
on a.object_id = b.object_id
where b.name = #tab
and a.name not in ('c');
set #sql = 'select ' + stuff(#sql, 1, 1, '') + ' from ' + #tab;
exec(#sql);
Produces:
3
select col1,col2,col3,col4,NVL(col1,0)+NVL(col2,0)+NVL(col3,0)+NVL(col4,0)
from
(select *
from sys.all.column
where object_id =(select object_id from sys.all.object where name ='name of my table')
and name not in (list of columns that I dont need).)
A | B | Total(col1+col2)
------+------+-------
1 | 2 | 3
---------------------
1 | | 1
Whatever columns you get, sum it and put them as seperate column in the result table.

SQL find the same column in different tables

I have 2 very large tables. I try to figure out what they have in common.
They do not have the same numbers of columns. I could go about to just look at each column name from each table and compare - but they both have hundreds of columns (I have to do it for many such tables).
I use MS Sql server.
There are no constrains and no foregin keys on any of them.
How do I go about doing that ?
Something like this:
select * AS "RES" from Table1 where RES IN (select * column from Table2)
Thanks in advance.
If you're looking for column names which are the same between two tables, this should work:
select name from syscolumns sc1 where id = object_id('table1') and exists(select 1 from syscolumns sc2 where sc2.name = sc1.name and sc2.id = object_id('table2'))
You could also make sure they're the same type by tossing in and sc1.xtype = sc2.xtype in the subquery.
If I understood correctly, you are trying to compare the data in the two tables and check what the data has in common.
Provided that you have the columns you want to use for comparison (Table1.YourColumn and Table2.OtherColumn, in the example), you can do this:
select YourColumn from Table1 t1
where exists (select OtherColumn
from Table2 t2
where t2.OtherColumn = t1.YourColumn)
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX), #Table1 AS NVARCHAR(MAX)='Table1' , #Table2 AS NVARCHAR(MAX)='Table2'
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(A.COLUMN_NAME)
from INFORMATION_SCHEMA.COLUMNS A
join INFORMATION_SCHEMA.COLUMNS B
on A.COLUMN_NAME = B.COLUMN_NAME
where A.TABLE_NAME = #Table1
and B.TABLE_NAME = #Table2 and A.COLUMN_NAME not in ('Doc','CreatedBy')
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT ' + #cols + '
from
(select A.COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS A
join INFORMATION_SCHEMA.COLUMNS B
on A.COLUMN_NAME = B.COLUMN_NAME
where A.TABLE_NAME = '''+#Table1+'''
and B.TABLE_NAME = '''+#Table2+'''
) x
pivot
(
Max(COLUMN_NAME)
for COLUMN_NAME in (' + #cols + ')
) p '
execute sp_executesql #query
Here is an SP to find common columns in two different tables..
Works in SQL Server
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE GetColumnsData(#T_NAME1 varchar,#T_NAME2 varchar)
AS
BEGIN
DECLARE #Co int;
SET #co = 0;
CREATE TABLE #TEMP_TABLE(C_NAME VARCHAR(50),D_TYPE VARCHAR(50),T_NAME VARCHAR(50));
INSERT INTO #TEMP_TABLE (C_NAME,D_TYPE,T_NAME)( SELECT COLUMN_NAME,DATA_TYPE,
TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = #T_NAME1 OR
TABLE_NAME= #T_NAME2);
SELECT #Co = COUNT(*) from #TEMP_TABLE t , #TEMP_TABLE t1 WHERE t1.C_NAME = t.C_NAME
and t.D_TYPE = t1.D_TYPE and t.T_NAME != t1.T_NAME
PRINT #co
END
Assuming your RDBMS supports digests, you could calculate the digest of each row and join on the digest. Something like:
SELECT T1.*
FROM
(SELECT *, MD5(col1, col2,...) as digest
FROM Table1) T1,
(SELECT *, MD5(col1, col2,...) as digest
FROM Table2) T2
WHERE T1.digest = T2.digest
I'm assuming that the two tables have the same columns and column types.

Help with TSQL join query

Based on below 2 tables
declare #t1 table
(
Id int,
Title varchar(100),
RelatedId int
)
insert into #t1 values(1,'A',2)
insert into #t1 values(1,'A',3)
declare #t2 table
(
Id int,
Title varchar(100)
)
insert into #t2 values
(2,'B'),
(3,'C')
I am trying to get the below output
Id Title RelatedItems
---------------------------------
1 A 2 (B), 3 (C)
I tried the following:
select t1.Id,t1.Title, cast(t2.Id as varchar) + ' (' + t2.Title + ')' from #t1 as t1
left outer join #t2 as t2
on t1.RelatedId=t2.Id
But that gives 2 different rows. I want just one row with the data combined in the third column (as shown above). Pls. suggest.
Use:
SELECT DISTINCT
b.id,
b.title,
STUFF((SELECT ','+ CAST(t2.id AS VARCHAR(100)) + ' ('+ t2.title +')'
FROM t2
JOIN t1 a ON a.relatedid = t2.id
WHERE a.id = b.id
FOR XML PATH('')), 1, 1, '')
FROM t1 b