Error while using t sql pivot table in SSRS - sql

I have a sql code that runs perfectly on SQL SERVER, it runs fine when I run it in SSRS, but when I substitute my constant value with a variable, it does not return any values.
This is the code I am using.
------LISTADO DE calificaciones de ESTUDIANTES
DECLARE #PivotColumnHeaders VARCHAR(MAX)
SELECT #PivotColumnHeaders =
COALESCE(
#PivotColumnHeaders + ',[' + cast(Codigo as varchar) + ']',
'[' + cast(Codigo as varchar)+ ']'
)
FROM RubroCalificaciones
inner join RubrosMetodosEvaluacion on RubroCalificaciones.IdRubro = RubrosMetodosEvaluacion.IdRubro
inner join MetodosEvaluacion on RubrosMetodosEvaluacion.IdMetodoEvaluacion = MetodosEvaluacion.IdMetodoEvaluacion
inner join AsignacionesMetodosEvaluacion on AsignacionesMetodosEvaluacion.IdMetodoEvaluacion = MetodosEvaluacion.IdMetodoEvaluacion
where AsignacionesMetodosEvaluacion.IdGrupo = #IdGrupo--293856
DECLARE #PivotTableSQL NVARCHAR(MAX)
SET #PivotTableSQL = N'
SELECT *
FROM (
select Estudiantes.Matricula, Personas.Nombres, Personas.Apellido1, personas.Apellido2,
RubroCalificaciones.Codigo, CalificacionesDetalle.PuntosAsignados
from Matriculas
inner join Personas on Matriculas.IdPersona = Personas.IdPersona
inner join Estudiantes on Matriculas.IdPersona = Estudiantes.IdPersona
inner join AsignacionesMetodosEvaluacion on Matriculas.IdGrupo = AsignacionesMetodosEvaluacion.IdGrupo
inner join MetodosEvaluacion on AsignacionesMetodosEvaluacion.IdMetodoEvaluacion = MetodosEvaluacion.IdMetodoEvaluacion
inner join RubrosMetodosEvaluacion on MetodosEvaluacion.IdMetodoEvaluacion = RubrosMetodosEvaluacion.IdMetodoEvaluacion
inner join RubroCalificaciones on RubroCalificaciones.IdRubro = RubrosMetodosEvaluacion.IdRubro
left outer join CalificacionesDetalle on CalificacionesDetalle.IdRubro = RubrosMetodosEvaluacion.IdRubro and
CalificacionesDetalle.IdMetodoEvaluacion = RubrosMetodosEvaluacion.IdMetodoEvaluacion
and CalificacionesDetalle.IdMatricula = Matriculas.IdMatricula
where Matriculas.IdGrupo = #IdGrupo--293856
) AS PivotData
PIVOT (
max(PuntosAsignados)
FOR Codigo IN (
' + #PivotColumnHeaders + '
)
) AS PivotTable
'
EXECUTE(#PivotTableSQL)

You need to pass your variable into the dynamic SQL. Also, I rewrote the COALESCE , you only need the column once.
CREATE PROC NameThisProcedure
#IdGrupo int
AS
------LISTADO DE calificaciones de ESTUDIANTES
DECLARE #PivotColumnHeaders VARCHAR(MAX)
SELECT #PivotColumnHeaders =
COALESCE(
#PivotColumnHeaders + ',', '') + '[' + cast(Codigo as varchar)+ ']'
FROM RubroCalificaciones
inner join RubrosMetodosEvaluacion on RubroCalificaciones.IdRubro = RubrosMetodosEvaluacion.IdRubro
inner join MetodosEvaluacion on RubrosMetodosEvaluacion.IdMetodoEvaluacion = MetodosEvaluacion.IdMetodoEvaluacion
inner join AsignacionesMetodosEvaluacion on AsignacionesMetodosEvaluacion.IdMetodoEvaluacion = MetodosEvaluacion.IdMetodoEvaluacion
where AsignacionesMetodosEvaluacion.IdGrupo = #IdGrupo--293856
DECLARE #PivotTableSQL NVARCHAR(MAX)
SET #PivotTableSQL = N'
SELECT *
FROM (
select Estudiantes.Matricula, Personas.Nombres, Personas.Apellido1, personas.Apellido2,
RubroCalificaciones.Codigo, CalificacionesDetalle.PuntosAsignados
from Matriculas
inner join Personas on Matriculas.IdPersona = Personas.IdPersona
inner join Estudiantes on Matriculas.IdPersona = Estudiantes.IdPersona
inner join AsignacionesMetodosEvaluacion on Matriculas.IdGrupo = AsignacionesMetodosEvaluacion.IdGrupo
inner join MetodosEvaluacion on AsignacionesMetodosEvaluacion.IdMetodoEvaluacion = MetodosEvaluacion.IdMetodoEvaluacion
inner join RubrosMetodosEvaluacion on MetodosEvaluacion.IdMetodoEvaluacion = RubrosMetodosEvaluacion.IdMetodoEvaluacion
inner join RubroCalificaciones on RubroCalificaciones.IdRubro = RubrosMetodosEvaluacion.IdRubro
left outer join CalificacionesDetalle on CalificacionesDetalle.IdRubro = RubrosMetodosEvaluacion.IdRubro and
CalificacionesDetalle.IdMetodoEvaluacion = RubrosMetodosEvaluacion.IdMetodoEvaluacion
and CalificacionesDetalle.IdMatricula = Matriculas.IdMatricula
where Matriculas.IdGrupo = #IdGrupo--293856
) AS PivotData
PIVOT (
max(PuntosAsignados)
FOR Codigo IN (
' + #PivotColumnHeaders + '
)
) AS PivotTable
'
EXECUTE sp_executeSQL #PivotTableSQL, N'#IdGrupo int', #IdGrupo
GO

Related

Query tuning in SQL Server

My query is taking too much time to execute. I am using five views in left join, and I am trying to optimize the query. I am trying to remove some subquery into left join in from clause. Is it the right method to optimize because already five left joins there are? Please suggest.
How can I optimize and rewrite?
Orginal query
SELECT DISTINCT
TP.F_PRODUCT AS ID,
TP.F_PRODUCT_NAME AS [NAME],
(SELECT MS.F_MSDSTYPE_DESC FROM T_MSDSTYPES MS WHERE MS.F_MSDSTYPE = TP.F_SUBFORMAT AND MS.F_FORMAT = TP.F_FORMAT) AS SFMT,
(SELECT TL.F_LANGUAGE_NAME FROM T_LANGUAGES TL WHERE TL.F_LANGUAGE = TP.F_LANGUAGE) AS LANG,
TP.F_LANGUAGE AS LANGCODE,
TP.F_SUBFORMAT AS SFMTCODE,
TP.F_PLANT AS PLANTCODE,
TP.F_FORMAT AS FMTCODE,
CONVERT(VARCHAR,TP.F_DATE_REVISED,120) AS RDATE,
CASE
WHEN NOT(REPLACE(LTRIM(RTRIM(REPLACE(TP.F_CAS_NUMBERS,'¿',' '))),' ','; ') IS NULL OR REPLACE(LTRIM(RTRIM(REPLACE(TP.F_CAS_NUMBERS,'¿',' '))),' ','; ') = '') THEN REPLACE(LTRIM(RTRIM(REPLACE(TP.F_CAS_NUMBERS,'¿',' '))),' ','; ') ELSE REPLACE(LTRIM(RTRIM(REPLACE(CASN.F_DATA,'¿',' '))),' ','; ')
END AS CASNUM ,
TP.F_CUSTOM1 AS cus1,
TP.F_CUSTOM2 AS cus2,
(SELECT TC.F_COUNTRY_NAME FROM T_COUNTRIES TC WHERE TC.F_COUNTRY_CODE = TP.F_CUSTOM5) AS cus5,
MAN.F_PHRASE AS MANU,
CASE
WHEN NOT(TP.F_CUSTOM3 IS NULL OR TP.F_CUSTOM3 = '') THEN TP.F_CUSTOM3 ELSE ''
END + ' ' +
CASE
WHEN NOT(SYN.F_DATA IS NULL OR SYN.F_DATA = '') THEN SYN.F_DATA ELSE ''
END AS SYN,
IC.F_DATA AS ICO,
'SDS - ' + (SELECT TL.F_LANGUAGE_NAME FROM T_LANGUAGES TL WHERE TL.F_LANGUAGE = TP.F_LANGUAGE) + ' - PDF' AS DOC,
'' AS COVER,
CAST(TP.F_GUID AS VARCHAR(36)) + '_PDF' AS [GUID],
'PDF' AS SDS
FROM
T_PDF_MSDS TP
LEFT JOIN
T_MSDSTYPES MS ON MS.F_MSDSTYPE = TP.F_SUBFORMAT
AND MS.F_FORMAT = TP.F_FORMAT
LEFT JOIN
T_LANGUAGES TL ON TL.F_LANGUAGE = TP.F_LANGUAGE
LEFT JOIN
V_PROD_ALIAS_SYN SYN ON TP.F_PRODUCT = SYN.F_PRODUCT
LEFT JOIN
V_PROD_ALIAS_SITE SIT ON TP.F_PRODUCT = SIT.F_PRODUCT
LEFT JOIN
V_PROD_ALIAS_ICO IC ON TP.F_PRODUCT = IC.F_PRODUCT
LEFT JOIN
V_PROD_ALIAS_MANU MAN ON TP.F_PRODUCT = MAN.F_PRODUCT
LEFT JOIN
V_PROD_ALIAS_CASN CASN ON TP.F_PRODUCT = CASN.F_PRODUCT
WHERE
(TP.F_CUSTOM5 IS NULL OR TP.F_CUSTOM5 = '')
AND (TP.F_SUBFORMAT IN (SELECT ITEM FROM SPLIT_NEW('EGHS,VCH,VJP,EGHS,VFR,VDE,VIR,AGHS,VUS,VCA,VCH,VJP',',')))
AND (TP.F_DATE_REVISED BETWEEN '2018-07-16 15:04:31' AND '2018-07-18 21:51:45')
AND TP.F_AUTHORIZED IN (1,3)
i removed the sub query(SFMT,LANG COLUMN NAMES) by using left join like this.
SELECT DISTINCT TP.F_PRODUCT AS ID,
TP.F_PRODUCT_NAME AS [NAME],
MS.F_MSDSTYPE_DESC AS SFMT,
TL.F_LANGUAGE_NAME AS LANG,
TP.F_LANGUAGE AS LANGCODE,
TP.F_SUBFORMAT AS SFMTCODE,
TP.F_PLANT AS PLANTCODE,
TP.F_FORMAT AS FMTCODE,
CONVERT(VARCHAR,TP.F_DATE_REVISED,120) AS RDATE,
CASE
WHEN NOT(REPLACE(LTRIM(RTRIM(REPLACE(TP.F_CAS_NUMBERS,'¿',' '))),' ','; ') IS NULL OR REPLACE(LTRIM(RTRIM(REPLACE(TP.F_CAS_NUMBERS,'¿',' '))),' ','; ') = '') THEN REPLACE(LTRIM(RTRIM(REPLACE(TP.F_CAS_NUMBERS,'¿',' '))),' ','; ') ELSE REPLACE(LTRIM(RTRIM(REPLACE(CASN.F_DATA,'¿',' '))),' ','; ')
END AS CASNUM ,
TP.F_CUSTOM1 AS cus1,
TP.F_CUSTOM2 AS cus2,
(SELECT TC.F_COUNTRY_NAME FROM T_COUNTRIES TC WHERE TC.F_COUNTRY_CODE = TP.F_CUSTOM5) AS cus5,
MAN.F_PHRASE AS MANU,
CASE
WHEN NOT(TP.F_CUSTOM3 IS NULL OR TP.F_CUSTOM3 = '') THEN TP.F_CUSTOM3 ELSE ''
END + ' ' +
CASE
WHEN NOT(SYN.F_DATA IS NULL OR SYN.F_DATA = '') THEN SYN.F_DATA ELSE ''
END AS SYN,
IC.F_DATA AS ICO,
'SDS - ' + (SELECT TL.F_LANGUAGE_NAME FROM T_LANGUAGES TL WHERE TL.F_LANGUAGE = TP.F_LANGUAGE) + ' - PDF' AS DOC,
'' AS COVER,
CAST(TP.F_GUID AS VARCHAR(36)) + '_PDF' AS [GUID],
'PDF' AS SDS
FROM T_PDF_MSDS TP
LEFT JOIN T_MSDSTYPES MS ON
MS.F_MSDSTYPE = TP.F_SUBFORMAT
AND MS.F_FORMAT = TP.F_FORMAT
LEFT JOIN T_LANGUAGES TL ON
TL.F_LANGUAGE = TP.F_LANGUAGE
LEFT JOIN V_PROD_ALIAS_SYN SYN
ON TP.F_PRODUCT = SYN.F_PRODUCT
LEFT JOIN V_PROD_ALIAS_SITE SIT
ON TP.F_PRODUCT = SIT.F_PRODUCT
LEFT JOIN V_PROD_ALIAS_ICO IC
ON TP.F_PRODUCT = IC.F_PRODUCT
LEFT JOIN V_PROD_ALIAS_MANU MAN
ON TP.F_PRODUCT = MAN.F_PRODUCT
LEFT JOIN V_PROD_ALIAS_CASN CASN
ON TP.F_PRODUCT = CASN.F_PRODUCT WHERE (TP.F_CUSTOM5 IS NULL OR TP.F_CUSTOM5 = '') AND (TP.F_SUBFORMAT IN (SELECT ITEM FROM SPLIT_NEW('EGHS,VCH,VJP,EGHS,VFR,VDE,VIR,AGHS,VUS,VCA,VCH,VJP',','))) AND (TP.F_DATE_REVISED BETWEEN '2018-07-16 15:04:31' AND '2018-07-18 21:51:45') AND TP.F_AUTHORIZED IN (1,3)
will it improve performance?

Get specific columns from xml path

I have this query here:
SELECT
T.AKSIONERET,
sd.Identification_No, sd.Date_Of_Incorp,
sd.Ownership_Desc, sd.Ownership_Code,
sd.Subject_Name_Code, sd.Subject_Name,
sd.Subject_Type_Code,
LEFT(sd.Object_Desc, 3999) AS Object_Desc,
sd.Subject_Status_Name, sd.Subject_Name,
nr2.NACE_Code, nr2.NACE_PARENT, nr2.Description,
sd.Subject_Type_Name, sd.Subject_Status_Name,
sd.Subject_Type_Name, f.Place_Of_Registration, sd.Object_Desc
FROM
NRC_Subject_DEF AS sd
LEFT JOIN
NRC_Nace_REV2 AS nr2 ON nr2.Subject_DEF_Code = sd.Subject_DEF_Code
LEFT JOIN
NRC_ForeignCompany AS f ON sd.ForeignCompany_Code = f.ForeignCompany_Code
LEFT JOIN
(SELECT
SDP.Subject_DEF_Code,
(SELECT
SDP1.Subject_DEF_Code, P.First_Name + ' ' + P.Last_Name + '-' + P.Citizenship_Desc AS FullAksionerCitizenship
FROM
NRC_PeopleAddress P
INNER JOIN
NRC_SubjectDefPeople SDP1 ON SDP1.People_Code = P.People_Code
WHERE
SDP1.Subject_DEF_Code = SDP.Subject_DEF_Code
GROUP BY
SDP1.Subject_DEF_Code, P.First_Name + ' ' + P.Last_Name + '-' + P.Citizenship_Desc
FOR XML PATH('')) AS AKSIONERET
FROM
NRC_SubjectDefPeople SDP
WHERE
SDP.Groyp_Type IN (1,2)
GROUP BY
SDP.Subject_DEF_Code) AS T ON T.Subject_DEF_Code = SD.SUBJECT_DEF_CODE
I need to retrieve, instead of T.AKSIONERET the FullAksionerCitizenship which I get from the for xml path.
I know I have to do some other SELECT but I kept getting errors, syntax errors.
Could someone help?
Thanks in advance
I'm quite sure, that there could be a better design and I'm not able to run this against test data off course, but this could work:
SELECT
T.AKSIONERET,
T2.FullAksionerCitizenship,
sd.Identification_No, sd.Date_Of_Incorp,
sd.Ownership_Desc, sd.Ownership_Code,
sd.Subject_Name_Code, sd.Subject_Name,
sd.Subject_Type_Code,
LEFT(sd.Object_Desc, 3999) AS Object_Desc,
sd.Subject_Status_Name, sd.Subject_Name,
nr2.NACE_Code, nr2.NACE_PARENT, nr2.Description,
sd.Subject_Type_Name, sd.Subject_Status_Name,
sd.Subject_Type_Name, f.Place_Of_Registration, sd.Object_Desc
FROM
NRC_Subject_DEF AS sd
LEFT JOIN
NRC_Nace_REV2 AS nr2 ON nr2.Subject_DEF_Code = sd.Subject_DEF_Code
LEFT JOIN
NRC_ForeignCompany AS f ON sd.ForeignCompany_Code = f.ForeignCompany_Code
LEFT JOIN
(SELECT
SDP.Subject_DEF_Code,
(SELECT
SDP1.Subject_DEF_Code, P.First_Name + ' ' + P.Last_Name + '-' + P.Citizenship_Desc AS FullAksionerCitizenship
FROM
NRC_PeopleAddress P
INNER JOIN
NRC_SubjectDefPeople SDP1 ON SDP1.People_Code = P.People_Code
WHERE
SDP1.Subject_DEF_Code = SDP.Subject_DEF_Code
GROUP BY
SDP1.Subject_DEF_Code, P.First_Name + ' ' + P.Last_Name + '-' + P.Citizenship_Desc
FOR XML PATH('')) AS AKSIONERET
FROM
NRC_SubjectDefPeople SDP
WHERE
SDP.Groyp_Type IN (1,2)
GROUP BY
SDP.Subject_DEF_Code) AS T ON T.Subject_DEF_Code = SD.SUBJECT_DEF_CODE
--here starts the new block (difficult for me without knowing your db...)
LEFT JOIN
(SELECT
(SELECT
SDP1.Subject_DEF_Code, P.First_Name + ' ' + P.Last_Name + '-' + P.Citizenship_Desc AS FullAksionerCitizenship
FROM
NRC_PeopleAddress P
INNER JOIN
NRC_SubjectDefPeople SDP1 ON SDP1.People_Code = P.People_Code
WHERE
SDP1.Subject_DEF_Code = SDP.Subject_DEF_Code
GROUP BY
SDP1.Subject_DEF_Code, P.First_Name + ' ' + P.Last_Name + '-' + P.Citizenship_Desc
) AS FullAksionerCitizenship
FROM
NRC_SubjectDefPeople SDP
WHERE
SDP.Groyp_Type IN (1,2)
GROUP BY
SDP.Subject_DEF_Code) AS T2 ON T2.Subject_DEF_Code = SD.SUBJECT_DEF_CODE

Store procedure for a select statement which should take input

Can anyone please help me with the store procedure for the following
select statement which should take an input of completeddatekey which
is at the bottom of the select statement
CompletedDateKey is filled with a key in this code but I need a store procedure that should take an input of completeddatekey
SELECT FactId
,UserType
,wr.WorkRequestId
,wr.XerisUserKey
,xu.CsuserUserID UserId
,u.fname UserFName
,u.lname UserLName
,b.PatientId
,p.firstname PatFName
,p.lastname PatLName
,GroupId
,HospiceGroupKey GroupKey
,WR.ContactKey
,C.ContactId
,C.FirstName
,C.LastName
,Convert(datetime,
(Convert(varchar, SD.Date,101) + ' ' + ST.TimeOfDay )) Start_dtm
,Convert(datetime,
(Convert(varchar, CD.Date,101) + ' ' + CT.TimeOfDay )) End_dtm
,DATEDIFF(s,
Convert(datetime,
(Convert(varchar, SD.Date,101) + ' ' + ST.TimeOfDay)),
Convert(datetime,
(Convert(varchar, CD.Date,101) + ' ' + CT.TimeOfDay ))) WRDuration
,(Convert(Decimal(18,3), DATEDIFF(s,Convert(datetime,(Convert(varchar, SD.Date,101) + ' ' + ST.TimeOfDay )), Convert(datetime,(Convert(varchar, CD.Date,101) + ' ' + CT.TimeOfDay ))))) * (Convert(Decimal(18,3),LineItemCount)/Convert(Decimal(18,3),PatientBucketItemCount)) Duration
,CallBackNumber
,WorkRequestType
,B.LineItemCount
,ArchiveLocation
,Processed
,ArchiveQueueType
,TQA
,Exclude
,CallId
FROM bi.dbo.FactWorkRequestTouches (NOlock) WR
INNER JOIN bi.dbo.BridgePatientWorkRequest B ON B.WorkRequestId = WR.WorkRequestId
INNER JOIN bi.dbo.dimPatient (NOlock) P ON B.PatientId = P.CphPatientID
INNER JOIN bi.dbo.DimXerisUsers (NOlock) XU ON WR.XerisUserKey = XU.XerisUserKey
INNER JOIN cdc.dbo.csuser (NOlock) U ON XU.CsuserUserID = u.user_id
INNER JOIN bi.dbo.DimTimeOfDay (NOlock) ST ON WR.StartTimeOfDayKey = ST.TimeKey
INNER JOIN bi.dbo.DimTimeOfDay (NOlock) CT ON WR.CompletedTimeOfDayKey = CT.TimeKey
INNER JOIN bi.dbo.DimDate (NOlock) SD ON WR.StartDateKey = SD.DateKey
INNER JOIN bi.dbo.DimDate (NOlock) CD ON WR.CompletedDateKey = CD.DateKey
LEFT OUTER JOIN bi.dbo.DimContact (Nolock) C ON WR.ContactKey = C.ContactKey
left outer join ssdba.excelleRx_WebFOCUS.dbo.DimHospiceHiearchy as h with (nolock) on b.groupid = h.group_id
WHERE CompletedDateKey = '20140131'
AND ArchiveQueueType = 0
AND PatientBucketItemCount <> 0
AND Exclude = 0
AND P.ENDDate is Null
Its really simple. Just create procedure like below
create procedure MyProc(
#CompletedDateKey varchar(20) )
as
Begin
SELECT FactId
,UserType
,wr.WorkRequestId
,wr.XerisUserKey
,xu.CsuserUserID UserId
,u.fname UserFName
,u.lname UserLName
,b.PatientId
,p.firstname PatFName
,p.lastname PatLName
,GroupId
,HospiceGroupKey GroupKey
,WR.ContactKey
,C.ContactId
,C.FirstName
,C.LastName
,Convert(datetime,
(Convert(varchar, SD.Date,101) + ' ' + ST.TimeOfDay )) Start_dtm
,Convert(datetime,
(Convert(varchar, CD.Date,101) + ' ' + CT.TimeOfDay )) End_dtm
,DATEDIFF(s,
Convert(datetime,
(Convert(varchar, SD.Date,101) + ' ' + ST.TimeOfDay)),
Convert(datetime,
(Convert(varchar, CD.Date,101) + ' ' + CT.TimeOfDay ))) WRDuration
,(Convert(Decimal(18,3), DATEDIFF(s,Convert(datetime,(Convert(varchar, SD.Date,101) + ' ' + ST.TimeOfDay )), Convert(datetime,(Convert(varchar, CD.Date,101) + ' ' + CT.TimeOfDay ))))) * (Convert(Decimal(18,3),LineItemCount)/Convert(Decimal(18,3),PatientBucketItemCount)) Duration
,CallBackNumber
,WorkRequestType
,B.LineItemCount
,ArchiveLocation
,Processed
,ArchiveQueueType
,TQA
,Exclude
,CallId
FROM bi.dbo.FactWorkRequestTouches (NOlock) WR
INNER JOIN bi.dbo.BridgePatientWorkRequest B ON B.WorkRequestId = WR.WorkRequestId
INNER JOIN bi.dbo.dimPatient (NOlock) P ON B.PatientId = P.CphPatientID
INNER JOIN bi.dbo.DimXerisUsers (NOlock) XU ON WR.XerisUserKey = XU.XerisUserKey
INNER JOIN cdc.dbo.csuser (NOlock) U ON XU.CsuserUserID = u.user_id
INNER JOIN bi.dbo.DimTimeOfDay (NOlock) ST ON WR.StartTimeOfDayKey = ST.TimeKey
INNER JOIN bi.dbo.DimTimeOfDay (NOlock) CT ON WR.CompletedTimeOfDayKey = CT.TimeKey
INNER JOIN bi.dbo.DimDate (NOlock) SD ON WR.StartDateKey = SD.DateKey
INNER JOIN bi.dbo.DimDate (NOlock) CD ON WR.CompletedDateKey = CD.DateKey
LEFT OUTER JOIN bi.dbo.DimContact (Nolock) C ON WR.ContactKey = C.ContactKey
left outer join ssdba.excelleRx_WebFOCUS.dbo.DimHospiceHiearchy as h with (nolock) on b.groupid = h.group_id
WHERE CompletedDateKey = #CompletedDateKey
AND ArchiveQueueType = 0
AND PatientBucketItemCount <> 0
AND Exclude = 0
AND P.ENDDate is Null
End
Execute it like
Execute MyProc '20140131'

Column 'QM_Analysis.DefectLocation' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

i'm trying to create this stored procedure, the problem is that when I put count() on the SELECT list it returns the error: "Column 'QM_Analysis.DefectLocation' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."
I've already tried many things but still returns the same error.
Someone have some tip ?
Thanks in advance
USE [JEMS]
GO
/****** Object: StoredProcedure [dbo].[up_RE_Rpt_Defect_new] Script Date: 01/08/2013 11:35:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
/*
[up_RE_Rpt_Defect_new]
#Factory ="",
#Customer_ID ='25',
#Manuf_Area = null,--'136',
#Route =null,--361,
#Step = null,--1848,
#DateFrom ='2012-10-25 00:00:00.000',
#DateTo ='2012-10-25 09:00:00.000',
#hrFrom = '06:00',
#hrTo = '14:00',
#language = 9,
#family = null
*/
ALTER PROCEDURE [dbo].[up_RE_Rpt_Defect_new]
-- Plant> Customer> Manufacturing Area> Route> Step> DateFrom> DateTo> TopNvalues;
#Factory as varchar(20)= null,
#Customer_ID as varchar(50)= null,
#Manuf_Area as varchar(50)= null,
#Route as varchar(400) = null,
#Step as varchar(400)= null,
#DateFrom as datetime= null,
#DateTo datetime = null,
#hrFrom as varchar(5) = null,
#hrTo as varchar(5) = null,
#TopN as varchar(20)= null,
#language as int = null,
#family as varchar(5) = null
AS
--declare #Factory as varchar(20),
--#Customer_ID as varchar(20),
--#Manuf_Area as varchar(20),
--#Route as varchar(50) ,
--#Step as varchar(20),
--#DateFrom as smalldatetime,
--#DateFrom2 as smalldatetime,
--#hrFrom as varchar(5) ,
--#hrTo as varchar(5) ,
--#DateTo smalldatetime ,
--#DateTo2 varchar(20) ,
--#TopN as varchar(20)
--SET #Customer_ID = 25
--SET #Factory = 7
--SET #Manuf_Area = 136
--SET #DateFrom = '2012-10-23 05:00:00.000' -- CONVERT(varchar(12),#DateFrom,103)
--SET #DateTo = '2012-10-23 09:00:00.000'
--SET #hrFrom = '08:00'
--SET #hrTo = '09:00'
--SET #language = 9
IF #Factory = ""
BEGIN SET #Factory = null
END
IF #Manuf_Area= ""
BEGIN SET #Manuf_Area = null
END
IF #Route = ""
BEGIN SET #Route = null
END
IF #Step = ""
BEGIN SET #Step = null
END
IF #family = ""
BEGIN SET #family = null
END
DECLARE #Select as varchar(7000)
DECLARE #Where as varchar(7000)
SET #Select =
'SELECT TOP 10
COUNT(qman.DefectLocation) as cont,
qman.DefectLocation
FROM QM_Analysis qman WITH(NOLOCK)
INNER JOIN QM_TestData td WITH(NOLOCK) on qman.Wip_ID = td.Wip_ID AND qman.Process_ID = td.Process_ID
INNER JOIN QM_Fixture qf WITH(NOLOCK) on td.Fixture_ID = qf.Fixture_ID
INNER JOIN QM_Defects def WITH(NOLOCK) on qman.Defect_ID = def.Defect_ID
INNER JOIN CR_Text defText WITH(NOLOCK) on def.Defect = defText.Text_ID
INNER JOIN CT_FeederTrayTrack ftt WITH(NOLOCK) on qman.FeederTrayTrack_ID = ftt.FeederTrayTrack_ID
INNER JOIN QM_DataAnalysis da WITH(NOLOCK) on qman.Analysis_ID = da.Analysis_ID
INNER JOIN CR_Text ansText1 WITH(NOLOCK) on ansText1.Language_ID = 0 AND da.AnalysisStatus = ansText1.Translation
INNER JOIN QM_AnalysisStatus ans WITH(NOLOCK) on ansText1.Text_ID = ans.AnalysisStatus
INNER JOIN CR_Text ansText2 WITH(NOLOCK) on ans.Descr = ansText2.Text_ID AND ansText2.Language_ID = defText.Language_ID
INNER JOIN WP_Wip w WITH(NOLOCK) on td.Wip_ID = w.Wip_ID
INNER JOIN CR_Materials m WITH(NOLOCK) on qman.Material_ID = m.Material_ID
INNER JOIN CR_Assemblies a WITH(NOLOCK) on td.Assembly_ID = a.Assembly_ID
INNER JOIN CR_Families fam WITH(NOLOCK) on a.Family_ID = fam.Family_ID
INNER JOIN CR_Text famText WITH(NOLOCK) on fam.Family = famText.Text_ID AND famText.Language_ID = defText.Language_ID
INNER JOIN CR_Customers c WITH(NOLOCK) on a.Customer_ID = c.Customer_ID
INNER JOIN CR_Text cText WITH(NOLOCK) on c.Customer = cText.Text_ID AND cText.Language_ID = defText.Language_ID
INNER JOIN CR_Text dText WITH(NOLOCK) on c.Division = dText.Text_ID AND dText.Language_ID = defText.Language_ID
INNER JOIN CR_Text eText WITH(NOLOCK) on qf.Fixture = eText.Text_ID AND eText.Language_ID = defText.Language_ID
LEFT JOIN CT_EquipmentSETup es WITH(NOLOCK) on qman.EquipmentOrRouteStep_ID = es.EquipmentSETup_ID AND qman.IsEquipment = 1
LEFT JOIN CR_Equipment_V e WITH(NOLOCK) on es.Equipment_ID = e.Equipment_ID
LEFT JOIN CR_FMRS4_V fmrs1 WITH(NOLOCK) on es.RouteStep_ID = fmrs1.RouteStep_ID AND fmrs1.Language_ID = defText.Language_ID
LEFT JOIN CT_RouteStepSETup rss WITH(NOLOCK) on qman.EquipmentOrRouteStep_ID = rss.RouteStepSETup_ID AND qman.IsEquipment = 0
LEFT JOIN CR_FMRS4_V fmrs2 WITH(NOLOCK) on rss.RouteStep_ID = fmrs2.RouteStep_ID AND fmrs2.Language_ID = defText.Language_ID
LEFT JOIN CR_Equipment_V e3 WITH(NOLOCK) on td.Equipment_ID = e3.Equipment_ID
INNER JOIN CR_FMRS4_V fmrs3 WITH(NOLOCK) on td.RouteStep_ID = fmrs3.RouteStep_ID AND fmrs3.Language_ID = defText.Language_ID
--- separeted
JOIN CR_FMRS4_V fmrs4 WITH(NOLOCK) on qman.RouteStep_ID = fmrs4.RouteStep_ID AND fmrs4.Language_ID = defText.Language_ID
INNER JOIN SC_Users ut WITH(NOLOCK) on td.OperatorID_ID = ut.UserID_ID
INNER JOIN SC_Users ua WITH(NOLOCK) on qman.AnalysisBy_ID = ua.UserID_ID
LEFT JOIN QM_DataRec dr WITH(NOLOCK) on da.Data_ID = dr.Data_ID AND da.Wip_ID = dr.Wip_ID AND da.Process_ID = dr.Process_ID'
SET #Where = ' WHERE ' +
'C.Customer_ID = ' + CONVERT(varchar(8),#Customer_ID ) +
' AND defText.Language_ID = ' + CAST(#language as varchar(3)) +
' AND da.AssociatedDefectFlag = '+'''F''' + -- AND a.Assembly_ID = '10587' --P266-8446100
' AND a.Active=1 AND def.defect_ID = 126 '
IF #Factory IS NOT NULL
BEGIN
SET #Where = #Where + ' AND (fmrs2.Factory_ID = ' + CAST(#Factory as varchar(10)) + ' or fmrs4.Factory_ID = ' +
CAST(#Factory as varchar(2)) + ')' -- AND fmrs3.Factory_ID = #Factory AND fmrs4.Factory_ID = #Factory
END
IF #Manuf_Area IS NOT NULL
BEGIN
SET #Where = #Where + ' AND fmrs3.FactoryMA_ID = ' + CAST(#Manuf_Area as varchar(5))
END
IF #family IS NOT NULL
BEGIN
SET #Where = #Where + ' AND fam.Family_ID = ' + CAST(#family AS VARCHAR(5))
END
IF #Route IS NOT NULL
BEGIN
SET #Where = #Where + ' AND fmrs3.FactoryMARoute_ID in(' + CAST(#Route as varchar(10)) + ') ' +
' AND fmrs4.FactoryMARoute_ID in(' + CAST(#Route as varchar(10)) + ') '
END
IF #Step IS NOT NULL
BEGIN
SET #Where = #Where + ' AND (fmrs3.RouteStep_ID in(' + CAST(#Step as varchar(50)) + ') or fmrs4.RouteStep_ID in (' +
CAST(#Step as varchar(50)) + '))'
END
SET #Where = #Where + 'AND CONVERT(varchar(5),td.LastUpdated,114) between ''' + #hrFrom + ''' AND ''' + #hrTo + '''' +
'AND td.LastUpdated between ''' + CONVERT(varchar(12),#DateFrom,111) + ' ' + #hrFrom + ':00.000' + ''' AND ''' +
CONVERT(varchar(12),#DateTo,111) + ' ' + #hrTo + ':00.000'''
SET #Where = #Where + 'GROUP BY qman.DefectLocation ORDER BY count(qman.DefectLocation) DESC'
PRINT (#select + #Where)
EXEC (#select + #Where)

Alternative TSQL

This query works well as you can see I have to put split between between #SearchCriteria and the rest of the query due to it's varchar. If I forced, the syntax works well BUT it return nothing when you query possible because extra '
Can you help?
ALTER PROCEDURE [dbo].[sp_rte_GetRateList]
(
#TenantID INT,
#CustomerID BIGINT = -1,
#SearchCriteria VARCHAR(64) = '',
#SortBy VARCHAR(16) = '',
#SortType VARCHAR(16) = '',
#Debug BIT = 0
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql nvarchar(4000),
#paramlist nvarchar(4000)
IF (#SearchCriteria = '')
BEGIN
SELECT #sql = 'SELECT r.TenantID, r.RateID, r.RateGUID, r.RateCode, r.RateName, r.RateDescription, r.ValidityUTCDate, r.CreatedUTCTimeStamp,
r.CreatedIP, r.CreatedBy, r.LastModifiedUTCTimeStamp, r.LastModifiedIP, r.LastModifiedBy, r.IsActive,
c.CustomerID, c.CustomerName, rt.RateTypeID, rt.RateTypeName, s.SupplierID, s.SupplierName, r.FixedLineAmount, r.MobileAmount, r.DataAmount, r.OtherAmount,
(r.FixedLineAmount + r.MobileAmount + r.DataAmount + r.OtherAmount) AS TotalAmount,
r.CreatedUTCTimeSTamp,
STUFF((SELECT '', '' + ct.CustomerTypeName
FROM glb_CustomerTypes ct JOIN glb_CustomerCustomerTypes cct ON cct.CustomerTypeID = ct.CustomerTypeID
WHERE cct.CustomerID = C.CustomerID
GROUP BY ct.CustomerTypeName FOR XML PATH('''')), 1, 2, '''') AS CustomerTypeName
FROM dbo.rte_Rates r
INNER JOIN dbo.rte_RateTypes rt ON r.RateTypeID = rt.RateTypeID
INNER JOIN dbo.glb_Suppliers s ON r.SupplierID = s.SupplierID
INNER JOIN dbo.glb_Customers c ON r.CustomerID = c.CustomerID
INNER JOIN dbo.glb_Addresses a ON c.CustomerID = a.CustomerID
INNER JOIN dbo.glb_AddressTypes at ON a.AddressTypeID = at.AddressTypeID
WHERE at.AddressTypeCode = ''GLB_ADT_PHYSCLDDRS'' AND
r.TenantID = #xTenantID AND
rt.TenantID = #xTenantID AND
s.TenantID = #xTenantID AND
r.IsActive = 1 AND
rt.IsActive = 1 AND
c.IsActive = 1 AND
c.CustomerID = #xCustomerID '
END
ELSE
BEGIN
SELECT #sql = 'SELECT r.TenantID, r.RateID, r.RateGUID, r.RateCode, r.RateName, r.RateDescription, r.ValidityUTCDate, r.CreatedUTCTimeStamp,
r.CreatedIP, r.CreatedBy, r.LastModifiedUTCTimeStamp, r.LastModifiedIP, r.LastModifiedBy, r.IsActive,
c.CustomerID, c.CustomerName, rt.RateTypeID, rt.RateTypeName, s.SupplierID, s.SupplierName, r.FixedLineAmount, r.MobileAmount, r.DataAmount, r.OtherAmount,
(r.FixedLineAmount + r.MobileAmount + r.DataAmount + r.OtherAmount) AS TotalAmount,
r.CreatedUTCTimeSTamp,
STUFF((SELECT '', '' + ct.CustomerTypeName
FROM glb_CustomerTypes ct JOIN glb_CustomerCustomerTypes cct ON cct.CustomerTypeID = ct.CustomerTypeID
WHERE cct.CustomerID = C.CustomerID
GROUP BY ct.CustomerTypeName FOR XML PATH('''')), 1, 2, '''') AS CustomerTypeName
FROM dbo.rte_Rates r
INNER JOIN dbo.rte_RateTypes rt ON r.RateTypeID = rt.RateTypeID
INNER JOIN dbo.glb_Suppliers s ON r.SupplierID = s.SupplierID
INNER JOIN dbo.glb_Customers c ON r.CustomerID = c.CustomerID
INNER JOIN dbo.glb_Addresses a ON c.CustomerID = a.CustomerID
INNER JOIN dbo.glb_AddressTypes at ON a.AddressTypeID = at.AddressTypeID
WHERE at.AddressTypeCode = ''GLB_ADT_PHYSCLDDRS'' AND
r.TenantID = #xTenantID AND
rt.TenantID = #xTenantID AND
s.TenantID = #xTenantID AND
r.IsActive = 1 AND
rt.IsActive = 1 AND
c.IsActive = 1 AND
c.CustomerID = #xCustomerID AND
(r.RateCode LIKE ''%' + #SearchCriteria + '%'' OR
r.RateName LIKE ''%' + #SearchCriteria + '%'' OR
rt.RateTypeName LIKE ''%' + #SearchCriteria + '%'' OR
r.RateDescription LIKE ''%' + #SearchCriteria + '%'' OR
s.SupplierCode LIKE ''%' + #SearchCriteria + '%'' OR
s.SupplierName LIKE ''%' + #SearchCriteria + '%'' OR
c.CustomerCode LIKE ''%' + #SearchCriteria + '%'' OR
c.CustomerName LIKE ''%' + #SearchCriteria + '%'' OR
c.CustomerDescription LIKE ''%' + #SearchCriteria + '%'' ) '
END
SELECT #sql = #sql + 'ORDER BY ' + #SortBy + ' ' + #SortType
IF (#Debug = 1) PRINT #sql
SELECT #paramlist = '#xTenantID INT, #xCustomerID BIGINT'
EXEC sp_executesql #sql, #paramlist, #TenantID, #CustomerID
END
You could just double any quotes in #SearchCriteria, but that won't protect you against all forms of SQL injection - which you can only do by getting away from dynamic SQL.
I'm not 100% sure you need dynamic SQL for this particular problem in the first place.
I think you'd be better off initializing the #SearchCriteria to NULL:
ALTER PROCEDURE [dbo].[sp_rte_GetRateList]
( ...
#SearchCriteria VARCHAR(64), --inits as NULL
....
)
IF #SearchCriteria IS NOT NULL
BEGIN
SET #SearchCriteria = REPLACE(#SearchCriteria, '''', '''''')
...
END
ELSE
...
I get why you setup the dynamic SQL the way you did - I noticed the paramlist doesn't have #SearchCriteria in it, so you don't have to define the param instances of #SearchCriteria. Might consider full text searches when you have 2+ columns from the same table - likely faster, and less complicated SQL.