I have 3 tables and I want to return result as one dynamic table, and use it with an ASP.NET GridView. However when I run my query I get a syntax error:
Declare #AghlamTitle_Topic nvarchar(max)
Declare #query nvarchar(max)
Select
#AghlamTitle_Topic =
stuff((select distinct ','+QuoteName([TopicTitle])
from Tbl_Topic
where Topic_PID = 29
for xml path('')), 1, 1, '')
Set #Query = ' Select *
From (Select
t2.Aghlam_Marasemat_PID,
View_Marasem_ALL.MarasemID ,
t2.[AghlamDateReg],
t1.[TopicTitle],
t2.AghlamCount
from
Tbl_Aghlam_Num t2 View_Marasem_ALL
inner join
Tbl_Topic t1
pivot (max([AghlamCount]) for [TopicTitle] in ( ' +#AghlamTitle_Topic + ' ) ) p
inner join t2 on View_Marasem_ALL.MarasemID = t2.Aghlam_Marasemat_PID'
exec sp_executeSql #query
Does someone have a solution?
Tbl_Aghlam_Num t2 View_Marasem_ALL
This is a syntax error. You have a Table name followed by the alias name t2 followed by View_Marasem_ALL, whatever that is.
If you need to also join to View_Marasem_ALL, then you need to add an additional JOIN clause.
Related
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.
I generate comma seperated string and add single quite to each numbers
Here is how i do it
DECLARE #IDs NVARCHAR(max)
SELECT #IDs = COALESCE(#IDs +',', '') + ''''
+ Cast([mynos] AS NVARCHAR(255)) + ''''
FROM mytable
WHERE id = 22
If i print variable #IDs then i get below output
'78888','3333','1222'
When i use same variable in this query then query doesnt return any value
SELECT *
FROM table1
WHERE ids IN ( #IDs )
How to fix this?
It doesn't work as your query is effectively doing this:
SELECT *
FROM TABLE
WHERE Ids IN ('''78888'',''3333',''1222''');
Which would also be equivalent to:
SELECT *
FROM TABLE
WHERE Ids = '''78888'',''3333',''1222''';
If you want to do the query as you have done, you'll need to split your delomited data out again. As you're using SQL Server 2012, you can't make use of STRING_SPLIT, so you'll need to a different one; such as Jeff Moden's DelimitedSplit8K. Then you can do:
SELECT *
FROM TABLE
WHERE IDs IN (SELECT items
FROM dbo.DelimitedSplit8K (#IDs,','));
However, why are you not simply doing...
SELECT *
FROM TABLE T
WHERE EXISTS (SELECT 1
FROM myTable mT
WHERE mT.Id = 22
AND mT.myNos = T.Ids);
You can use dynamic query #id is string variable not multi-value argument
DECLARE #IDs nVARCHAR(MAX)
SELECT #IDs = COALESCE(#IDs +',' ,'') + '''' + CAST([myNos] AS nVARCHAR(255)) + ''''
FROM myTable WHERE Id = 22
DECLARE #query nVARCHAR(MAX)
SET #query = "Select * from table1 where Ids in ("+#IDs+")"
EXECUTE sp_executesql #query
I tried below and it worked
select * from table1 where id in (select mynos from mytable where id = 22)
Thanks to #Larnu for giving me idea
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
I want to use stored procedure to fill my JqGrid. My stored procedure is below:
ALTER PROCEDURE [dbo].[SubJqGridObisDataSP]
as begin
DECLARE #header AS NVARCHAR(MAX),#MetID AS bigint
SELECT #header =
STUFF((SELECT ',' + QUOTENAME([ObisInfoTranslateT])
from MetContDB.dbo.tblMet AS met
join MetContDB.dbo.tblMod AS mod on mod.ModID= met.ModID_FK
join MetContDB.dbo.tblGroupData As Gro on Gro.MetID_FK= met.MetID
join MetContDB.dbo.tblObisData as obisdata on obisdata.GroupDataID_FK=Gro.GroupDataID
join MetContDB.dbo.tblObisInfo AS obisinfo on obisinfo.ObisInfoID=obisdata.ObisInfoID_FK
join (select max(GroupDataID) as maxgroupdata from MetContDB.dbo.tblGroupData where MetID_FK=#MetID) g on Gro.GroupDataID=g.maxgroupdata
where met.MetID=#MetID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
DECLARE #DynamicPIVOT AS NVARCHAR(MAX)
SELECT #DynamicPIVOT = 'SELECT ' + #header +
' FROM (
select
obisdata.ObisData,
obisinfo.[ObisInfoTranslateT]
from MetContDB.dbo.tblMet AS met
join MetContDB.dbo.tblMod AS mod on mod.ModID= met.ModID_FK
join MeterControlDB.dbo.tblGroupData As Gro on Gro.MetID_FK= met.MetID
join MetContDB.dbo.tblObisData as obisdata on obisdata.GroupDataID_FK=Gro.GroupDataID
join MetContDB.dbo.tblObisInfo AS obisinfo on obisinfo.ObisInfoID=obisdata.ObisInfoID_FK
join(select
max(GroupDataID) as maxgroupdata
from MeterControlDB.dbo.tblGroupData
where MetID_FK=#MetID) g on Gro.GroupDataID=g.maxgroupdata
where met.MetID=#MetID) Books
PIVOT (MAX(ObisData) FOR [ObisInfoTranslateT] IN (' + #header + ')) Result;'
EXEC (#DynamicPIVOT)
end
But when i use this SP in my controller, I get error : output of Stored procedure is int?????
My output stored procedure is some row. controller:
MetContDBEntities ctnx = new MetContDBEntities();
var obisDatas = ctnx.SubJqGridObisDataSP(id).ToList();
my code before query is:
select obisdata.ObisData,obisinfo.ObisInfoTranslateT
from MetContDB.dbo.tblMet AS met
join MetContDB.dbo.tblMod AS mod on mod.ModID= met.ModID_FK
join MetContDB.dbo.tblGroupData As Gro on Gro.MetID_FK= met.MetID
join MetContDB.dbo.tblObisData as obisdata on obisdata.GroupDataID_FK=Gro.GroupDataID
join MetContDB.dbo.tblObisInfo AS obisinfo on obisinfo.ObisInfoID=obisdata.ObisInfoID_FK
join(select
max(GroupDataID) as maxgroupdata
from MetContDB.dbo.tblGroupData
where MetID_FK=39) g on Gro.GroupDataID=g.maxgroupdata
where met.MetID=39
Output of this:
I want to show like this:
With first query I can change pic1 to pic2 .
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.