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 .
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 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.
I have a sql query that I need to put into a view. I have it working as a stored procedure but my requirement is for it to be a View. This means I cant declare dynamic SQL as I have done in my stored procedure.
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(t.Data_Term)
from [UD_FldValues] t
inner join Surgery p
on t.Ud_Form_Id = p.Ud_Form_Id where t.Data_term!=''
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
set #query = 'SELECT Tran_Id,Section_Id,SubSection_Id,R_Id,Hospital_Id,Surgeon_Id,Procedure_ICD,Procedure_Details,DtSurgery_TimeIn,DtSurgery_TimeOut,Intra_oper_compl_Id, p.Discharge_Date,Discharge_Status_Id,Entered_By,Entered_Date,p.Status,p.Ud_Form_Id,p.Complication_ICD,p.Complication_Name, Procedure_Name, ' + #cols + ' from
(
select t.Tran_Id
, t.[R_Id]
, p.Ud_Form_Id
,p.Procedure_Name
,p.Section_Id
,p.SubSection_Id
,p.Hospital_Id
,p.Surgeon_Id
,p.Procedure_ICD
,p.Procedure_Details
,p.DtSurgery_TimeIn
,p.DtSurgery_TimeOut
,p.Intra_oper_compl_Id
,p.Discharge_Date
,p.Discharge_Status_Id
,p.Entered_By,
p.Entered_Date
,p.Status
,p.Complication_ICD
,p.[Complication_Name]
, case when (t.Data_Type=''Text'') THEN t.Text_Value Else Convert(varchar(MAx),Num_Value) END as txtvl
,t.Data_term
from Surgery p
left outer join [UD_FldValues] t
on t.Ud_Form_Id = p.Ud_Form_Id and t.Tran_Id=p.Surgery_Id
left outer join UD_Formmap fm ON fm.Ud_Form_Id = p.Ud_Form_Id
where fm.module_id = 1
) x
pivot
(
min(txtvl)
for Data_Term in (' + #cols + ')
) p '
exec(#query)
Please help me find an alternate way, but not store procedures. I need it in view
for a view it needs to be a single select statement,
your #cols statement returns a list of columns, this is used twice within your main select statement. so replacing #cols in your main query with the query that populates this should work.
set #query and then exec(#query) isnt necessary either so you just have to tidy up and make sure the right number of brackets are in place.
and it should look something like this.
SELECT Tran_Id
,Section_Id
,SubSection_Id
,R_Id,Hospital_Id
,Surgeon_Id,Procedure_ICD
,Procedure_Details
,DtSurgery_TimeIn
,DtSurgery_TimeOut
,Intra_oper_compl_Id
,p.Discharge_Date
,Discharge_Status_Id
,Entered_By,Entered_Date
,p.Status,p.Ud_Form_Id
,p.Complication_ICD
,p.Complication_Name
,Procedure_Name,
(select STUFF((SELECT distinct ',' + QUOTENAME(t.Data_Term)
from [UD_FldValues] t
inner join Surgery p
on t.Ud_Form_Id = p.Ud_Form_Id where t.Data_term!=''
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');))
from
(
select t.Tran_Id
, t.[R_Id]
, p.Ud_Form_Id
,p.Procedure_Name
,p.Section_Id
,p.SubSection_Id
,p.Hospital_Id
,p.Surgeon_Id
,p.Procedure_ICD
,p.Procedure_Details
,p.DtSurgery_TimeIn
,p.DtSurgery_TimeOut
,p.Intra_oper_compl_Id
,p.Discharge_Date
,p.Discharge_Status_Id
,p.Entered_By,
p.Entered_Date
,p.Status
,p.Complication_ICD
,p.[Complication_Name]
, case when (t.Data_Type=''Text'') THEN t.Text_Value Else Convert(varchar(MAx),Num_Value) END as txtvl
,t.Data_term
from Surgery p
left outer join [UD_FldValues] t
on t.Ud_Form_Id = p.Ud_Form_Id and t.Tran_Id=p.Surgery_Id
left outer join UD_Formmap fm ON fm.Ud_Form_Id = p.Ud_Form_Id
where fm.module_id = 1
) x
pivot
(
min(txtvl)
for Data_Term in (
select STUFF((SELECT distinct ',' + QUOTENAME(t.Data_Term)
from [UD_FldValues] t
inner join Surgery p
on t.Ud_Form_Id = p.Ud_Form_Id where t.Data_term!=''
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');)
) p
I have created a stored procedure which returns result set. Now I need to call this stored procedure from Business Layer(.cs file) using Linq.
CREATE PROCEDURE GetApprovedContent
AS BEGIN
DECLARE #columns VARCHAR(1000)
DECLARE #query nVARCHAR(4000)
SELECT #columns = COALESCE(#columns + ',[' + Code + ']','[' + Code + ']')
FROM (
SELECT DISTINCT Code
FROM dbo.tblLanguages
) x
SET #query = '
SELECT *
FROM (
SELECT c.[id],c.[Content],t.[Tag], l.[Code],CASE WHEN r.[LanguageId] IS NULL THEN '''' ELSE ''YES'' END ''RequestLanguage''
FROM dbo.tblContents c CROSS JOIN dbo.tblLanguages l
LEFT OUTER JOIN dbo.tblRequestedLanguages r ON c.id= r.[ContentId] AND l.[id]=r.[LanguageId]
JOIN dbo.tblTags t ON c.[TagId]= t.[id]
WHERE [status] = (SELECT id FROM dbo.tblStatus WHERE [Status] =''Approved'')
) as s
PIVOT
(
MAX(RequestLanguage)
FOR [Code] IN ('+#columns+')
)AS piv'
EXECUTE(#query)
END
This procedure returns below Result-Set where number of column is not fixed
Id Content Tag Lang1 Lang2 Lang3 Lang_n
1 Ball Sport Y N Y N
2 Bat Sport N Y N Y
so how can I call this procedure using linq?
Leave the pivot off so you have a defined number of columns. Pivot the set in-memory after the query.
Example of in-memory pivot : https://stackoverflow.com/a/167937/8155
Also, don't use dynamic sql (since you're not pivoting in the database you don't need to).
I created a User-Defined Table Type:
CREATE TYPE dbo.ListTableType AS TABLE(
ITEM varchar(500) NULL
)
I leverage it in a function:
CREATE FUNCTION dbo.fn_list_to_string
(
#LIST dbo.ListTableType READONLY
)
RETURNS varchar(max)
AS
BEGIN
DECLARE #RESULT varchar(max)
SET #RESULT = ''
DECLARE #NL AS CHAR(2) = CHAR(13) + CHAR(10)
SELECT #RESULT = #RESULT + ITEM + #NL FROM #LIST
SET #RESULT = SUBSTRING(#RESULT, 1, LEN(#RESULT) - 1)
RETURN #RESULT
END
Finally, I try to use this function in a simple select:
SELECT
P.PROGRAM_ID,
PROGRAM_NAME,
PROGRAM_DESC,
P.STATUS_ID,
STATUS_DESC,
P.CONTACT_SID,
I.FIRST_NAME + ' ' + I.LAST_NAME as CONTACT_NAME,
P.CLARITY_ID,
dbo.fn_list_to_string(
( SELECT CONVERT(varchar,CLARITY_ID) as ITEM
FROM dbo.MUSEUM_PROGRAM_PROJECTS as A
JOIN dbo.MUSEUM_PROJECTS as B on B.PROJECT_ID = A.PROJECT_ID
WHERE PROGRAM_ID = P.PROGRAM_ID )
) as PROJECT_CLARITY_IDS
FROM dbo.MUSEUM_PROGRAMS as P
LEFT JOIN dbo.MUSEUM_PROGRAM_STATUS_TYPES as S on S.STATUS_ID = P.STATUS_ID
LEFT JOIN dbo.v_IDVAULT_ENRICHED_CURRENT_EMPLOYEES as I on I.[SID] = P.CONTACT_SID
But I get this error:
Operand type clash: varchar is incompatible with ListTableType
Any idea why? Also if there's another [more elegant] way to achieve what I'm trying to do I'm open to suggestions as well! Thanks in advance!
Here is a simple demonstration of the FOR XML PATH technique which does all of this with a very simple subquery and no table types or extremely inefficient multi-statement table-valued functions etc.
USE tempdb;
GO
CREATE TABLE dbo.P(Program_ID INT);
CREATE TABLE dbo.M(Clarity_ID INT, Program_ID INT);
INSERT dbo.P VALUES(1),(2),(3),(4);
INSERT dbo.M VALUES(1,1),(1,2),(2,3),(3,2),(1,4),(4,1);
SELECT
P.PROGRAM_ID,
PROJECT_CLARITY_IDS = STUFF((
SELECT CHAR(13)+CHAR(10)+CONVERT(VARCHAR(12),Clarity_ID)
FROM dbo.M WHERE Program_ID = p.Program_ID
FOR XML PATH(''), TYPE).value('.[1]','nvarchar(max)'),1,2,'')
FROM dbo.P AS p;
SQLfiddle demo
The output doesn't look right in SQLfiddle or in results to grid in Management Studio, because they strip out carriage returns/line feeds for display purposes, but you can replace CHAR(13)+CHAR(10) with two commas or semi-colons or something to verify that there are two characters there.
Using STUFF..FOR XML PATH construct for concatanation in combination with CTE will get the results you'd like. Something like this:
WITH CTE_PROJECT_CLARITIES AS
(
SELECT DISTINCT PROGRAM_ID
, STUFF((
SELECT CHAR(13) + CHAR(10) + CONVERT(varchar(11),CLARITY_ID)
FROM dbo.MUSEUM_PROGRAM_PROJECTS as A
JOIN dbo.MUSEUM_PROJECTS as B on B.PROJECT_ID = A.PROJECT_ID
WHERE A.PROGRAM_ID = X.PROGRAM_ID
FOR XML PATH ('')),1,2,'') AS PROJECT_CLARITY_IDS
FROM MUSEUM_PROGRAM_PROJECTS X
)
SELECT
P.PROGRAM_ID,
PROGRAM_NAME,
PROGRAM_DESC,
P.STATUS_ID,
STATUS_DESC,
P.CONTACT_SID,
I.FIRST_NAME + ' ' + I.LAST_NAME as CONTACT_NAME,
P.CLARITY_ID,
X.PROJECT_CLARITY_IDS
FROM dbo.MUSEUM_PROGRAMS as P
LEFT JOIN dbo.MUSEUM_PROGRAM_STATUS_TYPES as S on S.STATUS_ID = P.STATUS_ID
LEFT JOIN dbo.v_IDVAULT_ENRICHED_CURRENT_EMPLOYEES as I on I.[SID] = P.CONTACT_SID
LEFT JOIN CTE_PROJECT_CLARITIES X ON X.PROGRAM_ID = p.PROGRAM_ID
SQLFiddle DEMO (not sure if I got the columns right, but you'll get the idea)