Using CSV string Values in 'IN' clause of Dynamic SQL - sql

I have a stored procedure which accepts csv string as the parameter , for eg. ('IN\libin.jose,IN\Pallabi.P'). Stored procedure contains some dynamic sql which make use of this parameter inside IN clause eg : (AND u1.UserName IN (' + #UserNames + ')). Since this is being inside dynamic sql ,The condition is not passing without appending extra single quotes to the CSV values eg ('''IN\libin.jose '' ,''IN\Pallabi.P''')
--exec [GetUwParameterDetails] 'IN\libin.jose,IN\Pallabi.P' , 'false'
ALTER PROCEDURE [dbo].[GetUwParameterDetails]
#UserNames nvarchar(max),
#IncludeInactiveusers bit
AS
BEGIN
declare #selectedUsers nvarchar(max)
--set #selectedUsers = '''IN\libin.jose '' ,''IN\Pallabi.P''';
set #selectedUsers = 'IN\libin.jose,IN\Pallabi.P';
declare #selectedPermissions nvarchar(max)
set #selectedPermissions = '''Underwrite'',''ManageUwTeamPipeline''';
DECLARE #parameterQuery1 AS NVARCHAR(MAX);
set #parameterQuery1 = '
;WITH cte_users
AS (
SELECT users.id
,users.UserName
,users.FirstName
,users.lastname
,users.Email
,users.E3UserName
,UserStatus.[Status]
,Widgets.[Description] DefaultWidget
FROM users
INNER JOIN userparametervalues upv ON users.id = upv.userid
INNER JOIN Parameters p on upv.ParameterId = p.id
AND p.Name = ''UwHierarchy''
INNER JOIN UserPermissions up ON users.id = up.userid
INNER JOIN [Permissions] ps on up.PermissionId = ps.Id
AND ps.IsActive = 1 AND ps.Name IN ('+ #selectedPermissions +')
INNER JOIN users AS u1 ON upv.value = u1.id
AND u1.UserName IN (' + #UserNames + ')
INNER JOIN UserStatus ON users.StatusId = UserStatus.Id
LEFT JOIN Widgets ON users.WidgetId = Widgets.Id )select * from cte_users ';
exec #parameterQuery1
END
How can I achieve this ?

Use this after BEGIN
set #UserNames =''''+replace(#usernames,',',''',''')+''''

Related

Replacing Is Null Or Exist Inner Query Logic to Reduce Stored Procedure Execution Time

My stored procedure is currently using Is Null Or Exist logic combined with an inner query to filter out the records. The stored procedure is converting multiple comma-separated input values to temp tables (in the production scenario, the input record count will be much higher). And the inner query is using these temp tables for filter conditions. Due to the concern over query execution time would like to change the existing inner-query with an alternate (like left join). But need to retain the same Is Null Or Exist logic. Any suggestions?
DECLARE #SelectedOfferes varchar(1000) = 'FLT10,SPL20'
DECLARE #SelectedBrandCode varchar(1000) = '208,406'
DECLARE #CategoryCode varchar(1000) = 'GMOVN2,CELSMR,LCDTV38IN'
CREATE TABLE #SelectedOfferes
(
DiscountCode VARCHAR(20)
)
CREATE TABLE #BrandCode
(
BrandCode VARCHAR(20)
)
CREATE TABLE #CategoryCode
(
CategoryCode VARCHAR(20)
)
IF #SelectedOfferes IS NOT NULL
BEGIN
INSERT INTO #SelectedOfferes
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedOfferes, ',')
END
IF #SelectedBrandCode IS NOT NULL
BEGIN
INSERT INTO #BrandCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedBrandCode, ',')
END
IF #CategoryCode IS NOT NULL
BEGIN
INSERT INTO #CategoryCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#CategoryCode, ',')
END
SELECT *
FROM Products P
INNER JOIN Discount D ON P.DiscountCode = D.DiscountCode
INNER JOIN AvailableBrand AB ON P.BrandCode = AB.BrandCode
INNER JOIN Category C ON P.CategoryCode = C.CategoryCode
WHERE (#SelectedOfferes IS NULL
OR (EXISTS (SELECT 1 FROM #SelectedOfferes OFR
WHERE OFR.DiscountCode = P.DiscountCode)))
AND (#SelectedBrandCode IS NULL
OR (EXISTS (SELECT 1 FROM #BrandCode BC
WHERE BC.BrandCode = P.BrandCode)))
AND (#CategoryCode IS NULL
OR (EXISTS (SELECT 1 FROM #CategoryCode CAT
WHERE CAT.CategoryCode = P.CategoryCode)))
Dynamic SQL version
I have some questions about your string split function, is it set-based or a looping query? If it's not set-based then you should probably replace it with Jeff Moden's DelimitedSplit8K available at http://www.sqlservercentral.com/articles/Tally+Table/72993/ .
The below example should work the same as what you supplied but should be faster since it removes the ORs and the correlated subqueries from the WHERE clause. I'm not a fan of using dynamic SQL but sometimes it is the best way to get the job done. Maybe someone else can come up with a non-dynamic solution that works as well or better.
DECLARE #SelectedOfferes varchar(1000) = 'FLT10,SPL20'
DECLARE #SelectedBrandCode varchar(1000) = '208,406'
DECLARE #CategoryCode varchar(1000) = 'GMOVN2,CELSMR,LCDTV38IN'
CREATE TABLE #SelectedOfferes
(
DiscountCode VARCHAR(20)
)
CREATE TABLE #BrandCode
(
BrandCode VARCHAR(20)
)
CREATE TABLE #CategoryCode
(
CategoryCode VARCHAR(20)
)
IF #SelectedOfferes IS NOT NULL
BEGIN
INSERT INTO #SelectedOfferes
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedOfferes, ',')
END
IF #SelectedBrandCode IS NOT NULL
BEGIN
INSERT INTO #BrandCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#SelectedBrandCode, ',')
END
IF #CategoryCode IS NOT NULL
BEGIN
INSERT INTO #CategoryCode
SELECT part
FROM dbo.[FormatTextByDelimiter] (#CategoryCode, ',')
END
DECLARE #SQL NVarchar(4000);
SET #SQL = N'SELECT *
FROM Products P
INNER JOIN Discount D ON P.DiscountCode = D.DiscountCode
INNER JOIN AvailableBrand AB ON P.BrandCode = AB.BrandCode
INNER JOIN Category C ON P.CategoryCode = C.CategoryCode'
IF #SelectedOfferes IS NOT NULL
SET #SQL = #SQL + N'
INNER JOIN #SelectedOfferes OFR ON OFR.DiscountCode = P.DiscountCode';
IF #SelectedBrandCode IS NOT NULL
SET #SQL = #SQL + N'
INNER JOIN #BrandCode BC ON BC.BrandCode = P.BrandCode';
IF #CategoryCode IS NOT NULL
SET #SQL = #SQL + N'
INNER JOIN #CategoryCode CAT ON CAT.CategoryCode = P.CategoryCode';
EXEC sys.sp_executesql #stmt = #SQL;
This method doesn't quite do what the OP wanted but is valid in many other cases
I have some questions about your string split function, is it set-based or a looping query? If it's not set-based then you should probably replace it with Jeff Moden's DelimitedSplit8K available at http://www.sqlservercentral.com/articles/Tally+Table/72993/ .
But either way the below change to your last query should help quite a bit. The IS NULL parts aren't needed since it is a LEFT JOIN and the table will be empty if the variable it is built with is NULL, so you get the same result with less work for the engine.
SELECT *
FROM Products P
INNER JOIN Discount D ON P.DiscountCode = D.DiscountCode
INNER JOIN AvailableBrand AB ON P.BrandCode = AB.BrandCode
INNER JOIN Category C ON P.CategoryCode = C.CategoryCode
LEFT JOIN #SelectedOfferes OFR ON OFR.DiscountCode = P.DiscountCode
LEFT JOIN #BrandCode BC ON BC.BrandCode = P.BrandCode
LEFT JOIN #CategoryCode CAT ON CAT.CategoryCode = P.CategoryCode

SQL EXEC PROCEDURE: "Must declare the scalar variable "#p1"

I am getting the following error when I try to execute the stored procedure below:
Must declare the scalar variable "#p1"
I don't understand why or how to fix, any help would be appreciated. thanKs
Stored procedure:
USE [SERVER_NAME]
GO
/****** Object: StoredProcedure [dbo].[APP_jdtest_shp_0] Script Date: 16/12/2019 11:13:01 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[jdtest_shp_0]
#p1 nvarchar(100),
#n nvarchar(100)
AS
EXEC('
CREATE VIEW dbo.[' + #n + '] AS
SELECT
RTRIM([F].[F_CODE]) As F_UID ,
RTRIM([TP].[F_TP_NAME]) As F_TP_UID ,
RTRIM([NS].[F_CODE]) AS F_CODE,
RTRIM([NS].[SOME_DATE]) AS SOME_DATE,
RTRIM([NS].[ANOTHER_DATE]) AS ANOTHER_DATE,
RTRIM([NS].[SPD]) AS SPD,
RTRIM([NS].[LK_DATE]) AS LK_DATE,
RTRIM([NS].[RC_DATE]) AS RC_DATE,
RTRIM([NS].[RD_DATE]) AS RD_DATE,
RTRIM([NS].[OLD_UID]) AS OLD_UID,
RTRIM([NS].[VN]) AS VN,
RTRIM([NS].[R_I]) AS R_I,
RTRIM([NS].[WTU_UID]) AS WTU_UID,
RTRIM([NS].[D_LT]) AS D_LT,
RTRIM([PLT_UD].[PLT]) As L_A_PLT_UD_UID ,
RTRIM([RT].[RT_NAME]) As RT_UID ,
RTRIM([SS].[S_S_NAME]) As S_S_UID ,
RTRIM([NS].[S_DATE]) AS S_DATE,
RTRIM([SUR].[S_SUR_NAME]) As S_SUR_UID ,
RTRIM([NS].[S_TOL]) AS S_TOL,
RTRIM([LKP_AUTH].[AUTH_NAME]) As AUTH_UID ,
[NS].[S_G] AS S_G,
RTRIM([NS].[NS_UID]) AS NS_UID,
RTRIM([NSG_C].[C_NAME]) As C_UID ,
RTRIM([NS].[CLT]) AS CLT,
RTRIM([NS].[ONR_UID]) AS ONR_UID,
RTRIM([NC].[S_CLF_NAME]) As S_CLF_UID ,
RTRIM([NS].[XP]) AS XP,
RTRIM([NS].[CSTART_X]) AS CSTART_X,
RTRIM([NS].[CSTART_Y]) AS CSTART_Y,
RTRIM([NS].[CEND_X]) AS CEND_X,
RTRIM([NS].[CEND_Y]) AS CEND_Y
FROM NS
LEFT OUTER JOIN F ON NS.F_UID = F.F_UID
LEFT OUTER JOIN FT ON NS.F_TP_UID = FT.FT_UID
LEFT OUTER JOIN PLT_UD ON NS.L_A_PLT_UD_UID = SEC_PLT_UD.PLT_UD_UID
LEFT OUTER JOIN RT ON NS.RT_UID = RT.RT_UID
LEFT OUTER JOIN STT ON NS.S_S_UID = SS.S_S_UID
LEFT OUTER JOIN SUR ON NS.S_SUR_UID = SUR.S_SUR_UID
LEFT OUTER JOIN AUTH ON NS.AUTH_UID = AUTH.AUTH_UID
LEFT OUTER JOIN C ON NS.C_UID = C.C_UID
LEFT OUTER JOIN NSC ON NS.S_CLF_UID = NSC.S_CLF_UID
WHERE
([NS].[SHAPE_GEOMETRY].STIntersects(Geometry::STGeomFromText(' + '#p1' + ', 0).MakeValid())>0) AND
([NS].[S_G].STGeometryTP() = ''POINT'') '
)
EDIT: using sql server 2014. This is not my code, I am trying to fix a bug in someone else's code.
UPDATE: updated the 'execute command' section to show how the procedure is being executed
You need to use sp_executesql instead of EXEC() if you want to use parameters in your dynamic statement:
CREATE PROCEDURE [dbo].[123456]
#p1 nvarchar(100),
#n nvarchar(100)
AS
BEGIN
DECLARE #stm nvarchar(max)
DECLARE #err int
SET #stm =
N'CREATE VIEW dbo.' + QUOTENAME(#n) + N' AS ' +
N'SELECT
RTRIM([FEATURE].[FEATURE_CODE]) As FEATURE_UID ,
RTRIM([FEATURE_TYPE].[FEATURE_TYPE_NAME]) As FEATURE_TYPE_UID ,
RTRIM([NSG_STREETS].[FEATURE_CODE]) AS FEATURE_CODE,
RTRIM([NSG_STREETS].[START_DATE]) AS START_DATE,
RTRIM([NSG_STREETS].[END_DATE]) AS END_DATE,
RTRIM([NSG_STREETS].[SUSPEND_ACTIVITIES]) AS SUSPEND_ACTIVITIES,
RTRIM([NSG_STREETS].[RECORD_ENTRY_DATE]) AS RECORD_ENTRY_DATE,
RTRIM([NSG_STREETS].[RECORD_CHANGE_DATE]) AS RECORD_CHANGE_DATE,
RTRIM([NSG_STREETS].[RECORD_DELETE_DATE]) AS RECORD_DELETE_DATE,
RTRIM([NSG_STREETS].[OLD_SYSTEM_UID]) AS OLD_SYSTEM_UID,
RTRIM([NSG_STREETS].[VERSION_NUMBER]) AS VERSION_NUMBER,
RTRIM([NSG_STREETS].[RECORD_IDENTIFIER]) AS RECORD_IDENTIFIER,
RTRIM([NSG_STREETS].[WARD_UID]) AS WARD_UID,
RTRIM([NSG_STREETS].[DIGITAL_LENGTH]) AS DIGITAL_LENGTH,
RTRIM([SEC_USER].[USER_NAME]) As LAST_EDIT_USER_UID ,
RTRIM([LKP_RECORD_TYPE].[RECORD_TYPE_NAME]) As RECORD_TYPE_UID ,
RTRIM([LKP_STREET_STATE].[STREET_STATE_NAME]) As STREET_STATE_UID ,
RTRIM([NSG_STREETS].[STATE_DATE]) AS STATE_DATE,
RTRIM([LKP_STREET_SURFACE].[STREET_SURFACE_NAME]) As STREET_SURFACE_UID ,
RTRIM([NSG_STREETS].[STREET_TOLERANCE]) AS STREET_TOLERANCE,
RTRIM([LKP_AUTHORITY].[AUTHORITY_NAME]) As AUTHORITY_UID ,
[NSG_STREETS].[SHAPE_GEOGRAPHY] AS SHAPE_GEOGRAPHY,
RTRIM([NSG_STREETS].[NSG_STREETS_UID]) AS NSG_STREETS_UID,
RTRIM([NSG_COUNTY].[COUNTY_NAME]) As COUNTY_UID ,
RTRIM([NSG_STREETS].[CLASS_UID]) AS CLASS_UID,
RTRIM([NSG_STREETS].[OWNER_UID]) AS OWNER_UID,
RTRIM([NSG_STREET_CLASSIFICATION].[STREET_CLASSIFICATION_NAME]) As STREET_CLASSIFICATION_UID ,
RTRIM([NSG_STREETS].[EXPORT]) AS EXPORT,
RTRIM([NSG_STREETS].[CSTART_X]) AS CSTART_X,
RTRIM([NSG_STREETS].[CSTART_Y]) AS CSTART_Y,
RTRIM([NSG_STREETS].[CEND_X]) AS CEND_X,
RTRIM([NSG_STREETS].[CEND_Y]) AS CEND_Y FROM NSG_STREETS
LEFT OUTER JOIN FEATURE ON NSG_STREETS.FEATURE_UID = FEATURE.FEATURE_UID
LEFT OUTER JOIN FEATURE_TYPE ON NSG_STREETS.FEATURE_TYPE_UID = FEATURE_TYPE.FEATURE_TYPE_UID
LEFT OUTER JOIN SEC_USER ON NSG_STREETS.LAST_EDIT_USER_UID = SEC_USER.USER_UID
LEFT OUTER JOIN LKP_RECORD_TYPE ON NSG_STREETS.RECORD_TYPE_UID = LKP_RECORD_TYPE.RECORD_TYPE_UID
LEFT OUTER JOIN LKP_STREET_STATE ON NSG_STREETS.STREET_STATE_UID = LKP_STREET_STATE.STREET_STATE_UID
LEFT OUTER JOIN LKP_STREET_SURFACE ON NSG_STREETS.STREET_SURFACE_UID = LKP_STREET_SURFACE.STREET_SURFACE_UID
LEFT OUTER JOIN LKP_AUTHORITY ON NSG_STREETS.AUTHORITY_UID = LKP_AUTHORITY.AUTHORITY_UID
LEFT OUTER JOIN NSG_COUNTY ON NSG_STREETS.COUNTY_UID = NSG_COUNTY.COUNTY_UID
LEFT OUTER JOIN NSG_STREET_CLASSIFICATION ON NSG_STREETS.STREET_CLASSIFICATION_UID = NSG_STREET_CLASSIFICATION.STREET_CLASSIFICATION_UID
WHERE
([NSG_STREETS].[SHAPE_GEOMETRY].STIntersects(Geometry::STGeomFromText(#p1, 0).MakeValid())>0) AND
([NSG_STREETS].[SHAPE_GEOGRAPHY].STGeometryType() = ''POINT'') '
EXEC #err = sp_executesql #stm, N'#p1 nvarchar(100)', #p1
IF #err <> 0 BEGIN
PRINT 'Error'
RETURN #err
END
END

Convert all rows into different in sql server

I have a stored procedure that is showing a list of doctors and their details based on the sub-department they belong to. Below is the stored proc:
CREATE PROCEDURE SP_BILL_FOOTER_DOCTOR
#subDepartmentId int
AS
BEGIN
SELECT HETC_MST_EMPLOYEE.EMPLOYEE_NAME,
HETC_PAR_EMPLOYEE_TYPE.EMPLOYEE_TYPE_NAME,
HETC_MST_DOCTOR_SPECIALITY.DOCTOR_SPECIALITY_DESCRIPTION,
HETC_MST_SUB_DEPARTMENT.SUB_DEPARTMENT_NAME,
HETC_MST_EMPLOYEE.DOCTOR_SIGNATURE,
CASE WHEN HETC_MST_EMPLOYEE.DOCTOR_SIGNATURE = ''
THEN ''
ELSE ISNULL(SIGNATURE_PATH.DOCUMENT_PATH,'')+ HETC_MST_EMPLOYEE.DOCTOR_SIGNATURE
END AS DOCTOR_SIGNATURE_PIC
FROM HETC_MST_EMPLOYEE
INNER JOIN HETC_PAR_EMPLOYEE_TYPE
ON HETC_PAR_EMPLOYEE_TYPE.EMPLOYEE_TYPE_ID = HETC_MST_EMPLOYEE.EMPLOYEE_TYPE_ID
INNER JOIN HETC_MST_DOCTOR_SPECIALITY
ON HETC_MST_DOCTOR_SPECIALITY.DOCTOR_SPECIALITY_ID = HETC_MST_EMPLOYEE.DOCTOR_SPECIALITY_ID
INNER JOIN HETC_MST_DOCTOR_DEPARTMENT
ON HETC_MST_DOCTOR_DEPARTMENT.EMPLOYEE_ID = HETC_MST_EMPLOYEE.EMPLOYEE_ID
INNER JOIN HETC_MST_SUB_DEPARTMENT
ON HETC_MST_SUB_DEPARTMENT.SUB_DEPARTMENT_ID = HETC_MST_DOCTOR_DEPARTMENT.SUB_DEPARTMENT_ID
LEFT JOIN (SELECT DOCUMENT_PATH
FROM HETC_MST_DOCUMENT_PATH
INNER JOIN HETC_MST_TYPE_OF_ATTACHMENT
ON HETC_MST_DOCUMENT_PATH.TYPE_OF_DOCUMENT_ID = HETC_MST_TYPE_OF_ATTACHMENT.TYPE_OF_DOCUMENT_ID
WHERE HETC_MST_TYPE_OF_ATTACHMENT.TYPE_OF_DOCUMENT_CODE='DSI') AS DOC_SIGNATURE_PIC
ON 1=1
WHERE HETC_MST_SUB_DEPARTMENT.SUB_DEPARTMENT_ID = #subDepartmentId
END
Below is the link of the output that follows when procedure executes :
I want to know is it possible to convert the rows in different column. Like the output has 6 columns and 2 rows, I want all the data in 1 row with 12 columns. Below is the sample output:
It would be of great help if somebody could guide me on how to do it. I have understood that by using Pivot in Sql, I can achieve this, but none I have found to my specific case.
Please have a look at updated code below:
select *, row_number() over(order by employee_name) rownum into #a from (
SELECT HETC_MST_EMPLOYEE.EMPLOYEE_NAME,
HETC_PAR_EMPLOYEE_TYPE.EMPLOYEE_TYPE_NAME,
HETC_MST_DOCTOR_SPECIALITY.DOCTOR_SPECIALITY_DESCRIPTION,
HETC_MST_SUB_DEPARTMENT.SUB_DEPARTMENT_NAME,
HETC_MST_EMPLOYEE.DOCTOR_SIGNATURE,
CASE WHEN HETC_MST_EMPLOYEE.DOCTOR_SIGNATURE = ''
THEN ''
ELSE ISNULL(SIGNATURE_PATH.DOCUMENT_PATH,'')+ HETC_MST_EMPLOYEE.DOCTOR_SIGNATURE
END AS DOCTOR_SIGNATURE_PIC
FROM HETC_MST_EMPLOYEE
INNER JOIN HETC_PAR_EMPLOYEE_TYPE
ON HETC_PAR_EMPLOYEE_TYPE.EMPLOYEE_TYPE_ID = HETC_MST_EMPLOYEE.EMPLOYEE_TYPE_ID
INNER JOIN HETC_MST_DOCTOR_SPECIALITY
ON HETC_MST_DOCTOR_SPECIALITY.DOCTOR_SPECIALITY_ID = HETC_MST_EMPLOYEE.DOCTOR_SPECIALITY_ID
INNER JOIN HETC_MST_DOCTOR_DEPARTMENT
ON HETC_MST_DOCTOR_DEPARTMENT.EMPLOYEE_ID = HETC_MST_EMPLOYEE.EMPLOYEE_ID
INNER JOIN HETC_MST_SUB_DEPARTMENT
ON HETC_MST_SUB_DEPARTMENT.SUB_DEPARTMENT_ID = HETC_MST_DOCTOR_DEPARTMENT.SUB_DEPARTMENT_ID
LEFT JOIN (SELECT DOCUMENT_PATH
FROM HETC_MST_DOCUMENT_PATH
INNER JOIN HETC_MST_TYPE_OF_ATTACHMENT
ON HETC_MST_DOCUMENT_PATH.TYPE_OF_DOCUMENT_ID = HETC_MST_TYPE_OF_ATTACHMENT.TYPE_OF_DOCUMENT_ID
WHERE HETC_MST_TYPE_OF_ATTACHMENT.TYPE_OF_DOCUMENT_CODE='DSI') AS DOC_SIGNATURE_PIC
ON 1=1
WHERE HETC_MST_SUB_DEPARTMENT.SUB_DEPARTMENT_ID = #subDepartmentId )a
declare #iterator int=1
declare #string varchar(max)= ''
declare #string2 varchar(max)= ''
declare #string3 varchar(max)= ''
declare #string4 varchar(max)= ''
declare #exec varchar(max)
while #iterator<=(select max(rownum) from #a)
begin
select #string2=
'['+cast(#iterator as varchar(max))+'].'+ 'EMPLOYEE_NAME'+
',['+cast(#iterator as varchar(max))+'].'+'EMPLOYEE_TYPE_NAME' +
',['+cast(#iterator as varchar(max))+'].'+'DOCTOR_SPECIALITY_DESCRIPTION' +
',['+cast(#iterator as varchar(max))+'].'+'SUB_DEPARTMENT_NAME' +
',['+cast(#iterator as varchar(max))+'].'+'DOCTOR_SIGNATURE'+
',['+cast(#iterator as varchar(max))+'].'+'DOCTOR_SIGNATURE_PIC'
from #a where rownum=#iterator
select #string= #string+#string2
select #string4=
case when #string4='' then
#string4+'['+cast(#iterator as varchar(max))+'].rownum='+cast(#iterator as varchar(max)) else
#string4+' and ['+cast(#iterator as varchar(max))+'].rownum='+cast(#iterator as varchar(max)) end
select #string3= case when #iterator>1 then #string3+' cross join #a ['+ cast(#iterator as varchar(max))+']' else '' end
set #iterator=#iterator+1
end
select #exec = 'select distinct'+ left(#string, len(#string)-1) +' from #a [1] '+#string3+ ' where '+ #string4
exec(''+#exec+'')
This isn't really an answer but a demonstration of how much using aliases can improve the legibility of your queries. Believe it or not this EXACTLY the same thing you posted. I just used aliases so you can read this instead of looking at a wall of text. The only actual change was to use a cross join instead of a left join on 1 = 1.
SELECT e.EMPLOYEE_NAME,
et.EMPLOYEE_TYPE_NAME,
s.DOCTOR_SPECIALITY_DESCRIPTION,
sd.SUB_DEPARTMENT_NAME,
e.DOCTOR_SIGNATURE,
CASE WHEN e.DOCTOR_SIGNATURE = ''
THEN ''
ELSE ISNULL(SIGNATURE_PATH.DOCUMENT_PATH, '') + e.DOCTOR_SIGNATURE
END AS DOCTOR_SIGNATURE_PIC
FROM HETC_MST_EMPLOYEE e
INNER JOIN HETC_PAR_EMPLOYEE_TYPE et ON et.EMPLOYEE_TYPE_ID = e.EMPLOYEE_TYPE_ID
INNER JOIN HETC_MST_DOCTOR_SPECIALITY s ON s.DOCTOR_SPECIALITY_ID = e.DOCTOR_SPECIALITY_ID
INNER JOIN HETC_MST_DOCTOR_DEPARTMENT dd ON dd.EMPLOYEE_ID = e.EMPLOYEE_ID
INNER JOIN HETC_MST_SUB_DEPARTMENT sd ON sd.SUB_DEPARTMENT_ID = dd.SUB_DEPARTMENT_ID
cross join
(
SELECT DOCUMENT_PATH
FROM HETC_MST_DOCUMENT_PATH p
INNER JOIN HETC_MST_TYPE_OF_ATTACHMENT a ON p.TYPE_OF_DOCUMENT_ID = a.TYPE_OF_DOCUMENT_ID
WHERE a.TYPE_OF_DOCUMENT_CODE='DSI'
) AS DOC_SIGNATURE_PIC
WHERE sd.SUB_DEPARTMENT_ID = #subDepartmentId
For the question at hand it is hard to tell what you are really wanting here. Maybe some conditional aggregation in combination with ROW_NUMBER. Or a PIVOT. You would need to post more details for this. Here is a great place to start. http://spaghettidba.com/2015/04/24/how-to-post-a-t-sql-question-on-a-public-forum/

Combining Three Selects into One

I've been trying to consolidate these three SQL functions into one.
Functions
Function 1
`ALTER FUNCTION [dbo].[Fn_Get_User] (#_CompanyKey INT)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #UserIDs AS VARCHAR(8000);
SET #UserIDs = '';
SELECT #UserIDs = #UserIDs + ', ' + x.User_ID
FROM
(SELECT DISTINCT UPPER(p.User_ID) as User_ID
FROM [dbo].[Program] AS p WITH (NOLOCK)
WHERE p.CompanyKey = #_CompanyKey
UNION
SELECT DISTINCT UPPER(ps.User_ID) as User_ID
FROM [dbo].[Program] AS p WITH (NOLOCK)
LEFT OUTER JOIN [dbo].[Program_Scenario] AS ps WITH (NOLOCK)
ON p.ProgramKey = ps.ProgramKey
WHERE p.CompanyKey = #_CompanyKey
AND ps.User_ID IS NOT NULL) x
RETURN Substring(#UserIDs, 3, 8000);
END`
Function 2
`ALTER FUNCTION [dbo].[Fn_Get_Source] (#_CompanyKey INT)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #System_IDs AS VARCHAR(8000);
SET #System_IDs = '';
SELECT #System_IDs = #System_IDs + ', ' + Original_Source_System_ID
FROM (
SELECT DISTINCT p.Original_Source_System_ID
FROM [dbo].[Program] AS p WITH (NOLOCK)
WHERE p.CompanyKey = #_CompanyKey
) a
RETURN Substring(#System_IDs, 3, 8000);
END`
Function 3
`ALTER FUNCTION [dbo].[Fn_Get_ContractNbr] (#_CompanyKey INT)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #ContractNums AS VARCHAR(8000);
SET #ContractNums = '';
SELECT #ContractNums = #ContractNums + ', ' + bi.Contract_Nbr + '-' +
ISNULL(CAST(bi.Year_Nbr AS varchar(8)),'') + '-' +
ISNULL(CAST(bi.Layer_Nbr AS varchar(8)),'')
FROM [dbo].[Program] AS p WITH (NOLOCK)
INNER JOIN [dbo].[Program_Scenario] AS ps WITH (NOLOCK) ON p.ProgramKey = ps.ProgramKey
INNER JOIN [dbo].[Layer] AS l WITH (NOLOCK) ON ps.ProgramScenarioKey = l.ProgramScenarioKey
INNER JOIN [dbo].[Bound_Information] AS bi WITH (NOLOCK) ON l.LayerKey = bi.LayerKey
AND ISNULL(bi.Contract_Nbr,'') <> '' --IS NOT NULL
WHERE p.CompanyKey = #_CompanyKey
RETURN Substring(#ContractNums, 3, 8000);
END`
My attempted Solution
`SET STATISTICS TIME ON
SELECT DISTINCT UPPER((p.User_ID) +', '+ ps.User_ID) as UserID,
bi.Contract_Nbr as ContractNumber,
p.Original_Source_System_ID as SourceSysID,
ISNULL(CAST(bi.Year_Nbr AS varchar(8)),'') as UW_Year,
ISNULL(CAST(bi.Layer_Nbr AS varchar(8)),'') as LayerNumber,
p.CompanyKey,
ps.ProgramKey,
c.Company_Name
FROM
[dbo].[Program] AS p WITH (NOLOCK)
INNER JOIN [dbo].[Program_Scenario] AS ps WITH (NOLOCK)
ON p.ProgramKey = ps.ProgramKey
INNER JOIN [dbo].[Layer] AS l WITH (NOLOCK) ON ps.ProgramScenarioKey = l.ProgramScenarioKey
INNER JOIN [dbo].[Bound_Information] AS bi WITH (NOLOCK) ON l.LayerKey = bi.LayerKey
INNER JOIN [dbo].[Company] AS c with (NOLOCK) ON p.CompanyKey = c.CompanyKey
AND ISNULL(bi.Contract_Nbr,'') <>''
AND ps.User_ID IS NOT NULL
WHERE p.CompanyKey between 2 and 100000
ORDER BY ProgramKey`
My data-set is 20k+ rows so I'm unable to share it here, but where I'm struggling is my function is not returning the same amount of rows as the above three functions. Might there be anything anyone sees to possibly solve this issue? (24755 rows vs. 24052 rows respectively)

SELECT case using a variable which can be set based on a parameter

I'd like to select a particular value from a table while using an information from another database that is set based on a current database's value.
So a select case to find the operator code and set the DB path.. then use the same path and collate the result.
DECLARE #DB varchar (1000)
CASE
WHEN #Operator= 1 THEN SET #DB = '{SERVERNAME\ENTITY\DBNAME}'
WHEN #Operator= 2 THEN SET #DB = '{SERVERNAME2\ENTITY2\DBNAME2}'
WHEN #Operator= 3 THEN SET #DB = '{SERVERNAME3\ENTITY3\DBNAME3}'
Select transItem_item collate SQL_Latin1General_CI_AS
FROM Group_Transactions
INNER JOIN #DB.Table_Trans
ON (transItem.item_id collate SQL_Latin1General_CI-AS = Table_Trans.item_id)
Where ---Condition
Control flow method (likely to be the most efficient):
IF #Operator = 1
BEGIN
SELECT stuff
FROM Group_Transactions
INNER
JOIN "Server1\Instance1".Database1.Schema.Table_Trans
ON Group_Transactions... = Table_Trans...
WHERE things...
;
END
ELSE IF #Operator = 2
BEGIN
SELECT stuff
FROM Group_Transactions
INNER
JOIN "Server2\Instance2".Database2.Schema.Table_Trans
ON Group_Transactions... = Table_Trans...
WHERE things...
;
END
ELSE IF #Operator = 3
BEGIN
SELECT stuff
FROM Group_Transactions
INNER
JOIN "Server3\Instance3".Database3.Schema.Table_Trans
ON Group_Transactions... = Table_Trans...
WHERE things...
;
END
;
Single [conditional] query method:
SELECT Group_Transactions.stuff
, trans1.other_thing As other_thing1
, trans2.other_thing As other_thing2
, trans3.other_thing As other_thing3
, Coalesce(trans1.other_thing, trans2.other_thing, trans3.other_thing) As other_thing
FROM Group_Transactions
LEFT
JOIN "Server1\Instance1".Database1.Schema.Table_Trans As trans1
ON trans1... = Group_Transactions...
AND trans1.things...
AND #Operator = 1
LEFT
JOIN "Server2\Instance2".Database2.Schema.Table_Trans As trans2
ON trans2... = Group_Transactions...
AND trans2.things...
AND #Operator = 2
LEFT
JOIN "Server3\Instance3".Database3.Schema.Table_Trans As trans3
ON trans3... = Group_Transactions...
AND trans3.things...
AND #Operator = 3
;
If this is TSQL (I am guessing from your colation names) then you are best trying out OPENQUERY to run your join against another database server. If you are querying a database on the same server you could build your query up as a parameter and then run it using EXEC.
Gvee's Control Flow method may be a verbose, but it would work. You might want to create a look up table like my #tbl_Databases if you have a bunch of databases. Here's a dynamic SQL solution:
DECLARE #Operator INT = 1,
#DB VARCHAR(1000);
DECLARE #tbl_Databases TABLE (ID INT IDENTITY(1,1),DB VARCHAR(1000))
INSERT INTO #tbl_Databases(DB)
VALUES ('{SERVERNAME\ENTITY\DBNAME}'),('{SERVERNAME2\ENTITY2\DBNAME2}'),('{SERVERNAME3\ENTITY3\DBNAME3}');
SELECT #DB = DB
FROM #tbl_Databases
WHERE ID = #Operator
SELECT #DB
SELECT
(
'SELECT transItem_item COLLATE SQL_Latin1General_CI_AS
FROM Group_Transactions
INNER JOIN ' + #DB + '.dbo.Table_Trans
ON (transItem.item_id collate SQL_Latin1General_CI-AS = Table_Trans.item_id)
Where 1 = 1'
)