How can I improve the performance of this select into query - sql-server

I would appreciate if someone advises on how to improve the performance of a stored procedure with the following query (the functions are very small and I don’t believe they are penalising the performance):
SELECT DISTINCT REPLACE(REPLACE(REPLACE(c.[description], ' Org',''), ' group',''),'Organization full name','Org')
AS OrgColumn1,
REPLACE(REPLACE(c.[description], ' Org',''), ' group','') + ' Organization' AS OrgColumn2,
CASE
WHEN dbo.fn_OrgGrantPageAccess(c.id,#contactId) = 1
AND (c.id <> 13 AND c.id <> 31)
THEN '<a href="OrgMainPage.aspx?id='+CAST((c.id) as varchar(15))+'">'+
replace(replace(c.[description], ' Org',''), ' group','') + ' Org</a>'
WHEN dbo.fn_OrgGrantPageAccess(c.id,#contactId) = 1
AND (c.id = 13 OR c.id = 31)
THEN '<a href="OrgMainPage.aspx?id='+CAST((c.id) as varchar(15))+'">'+
c.[description]+'</a>'
ELSE
replace(replace(c.[description], ' Org',''), ' group','') + ' Org'
END AS OrgColumn3,
c.id AS OrgColumn4,
dbo.fn_OrgGetColumn5(c.id) AS OrgColumn5,
dbo.fn_OrgGetColumn6(c.id) AS OrgColumn6,
dbo.fn_OrgGetColumn7(c.id) AS OrgColumn7,
dbo.fn_OrgGetColumn8(c.id) AS OrgColumn8,
dbo.fn_OrgGetColumn9(c.id) AS OrgColumn9,
dbo.fn_OrgGetColumn10(c.id) AS OrgColumn10
INTO #T
FROM table_c c
INNER JOIN table_s s
ON c.id =s.id
INNER JOIN table_t t
ON s.type_id = t.type_id
LEFT OUTER JOIN table_m m
ON c.id = m.OrgID
LEFT OUTER JOIN table_cal cal
ON m.meetingid = cal.calid
WHERE t.type_id = 3
AND active = 1
AND (c.org_1 = 1
OR c.org_1 = 3)
ORDER BY OrgColumn1

I suggest you to rewrite dbo.fn_OrgGetColumn function from scalar-valued to table-valued and then cross apply it to main result set.
If you can provide source code for dbo.fn_OrgGetColumn function I can help you with rewriting it to table-valued.
There you can find good explanation with examples: Boost Your T-SQL with the APPLY

Related

Join Results in duplication

I have two tables. I suppose to get the result into one row, but when i try with the below query it results duplication.
Query:
Select OrgaID, UnitID, LeaveTitle, NoOfFromService, NoOfToService,
EmpType.EmployeeTypeName, IsExpatriate,
(ALR.LeaveTypeShortName + '(' + convert(varchar,ALR.NoofDays) + ') | ' +
MLR.LeaveTypeShortName + '(' + convert(varchar,MLR.NoofDays) + ') | ')
Leaves
From LeaveCategory LvCat
Left Join (Select LeaveCategoryID, LeaveTypeShortName, NoofDays From
LeaveEntitledEntry Where LeaveTypeShortName = 'AL' ) ALR On
ALR.LeaveCategoryId = LvCat.Id
Left Join (Select LeaveCategoryID, LeaveTypeShortName, NoofDays From
LeaveEntitledEntry Where LeaveTypeShortName = 'MDL' ) MLR On
ALR.LeaveCategoryId = LvCat.Id
Where OrgaID = #OrgaID and LvCat.Status = 1
For Reference :
Table 1: (LeaveCategory)
Table 2: (LeaveEntitledEntry)
Result :
So how can i change my joins to achieve expected result. Any help appreciated. Thanks in advance
You can try using conditional aggregation to access the two types of leave data by using a join to a single subquery. The reason this trick might work is that allows us to generate a single record for each LeaveCategoryID, along with its NoofDays values for both the AL and MDL types. This means that we can do with just a single join, which should avoid the duplication problem you were having.
WITH cte AS (
SELECT
LeaveCategoryID,
MAX(CASE WHEN LeaveTypeShortName = 'AL' THEN NoofDays END) AS NoofDaysAL,
MAX(CASE WHEN LeaveTypeShortName = 'MDL' THEN NoofDays END) AS NoofDaysMDL
FROM LeaveEntitledEntry
GROUP BY LeaveCategoryID
)
SELECT
OrgaID,
UnitID,
LeaveTitle,
NoOfFromService,
NoOfToService,
EmpType.EmployeeTypeName,
IsExpatriate,
'AL(' + CONVERT(varchar, t.NoofDaysAL) + ') | ' +
'MDL(' + CONVERT(varchar, t. NoofDaysMDL) + ') | ') AS Leaves
FROM LeaveCategory LvCat
LEFT JOIN cte t
ON LvCat.Id = t.LeaveCategoryID
WHERE
OrgaID = #OrgaID AND
LvCat.Status = 1;

Sub query with multiple result

I'm working with Sql Server, I have written one query.when i'm executing that query getting following error.
Error:
"Msg 512, Level 16, State 1, Line 1
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression."
SELECT b.booking_id,b.booking_ref,b.destination,b.room_format,b.checkin,b.checkout,b.booking_status,b.currency,b.rooms,b.booking_date,
b.adults,b.childs,b.seniors,b.youth,b.child2,b.booking_type,
pb.amount_charged,pb.original_total_cost 'total_amount',b.special_request,b.cancelled_date,b.emergency_contact,b.emergency_email,
(SELECT TOP 2 CAST(isbreakfast AS VARCHAR(10)) + '_' + room_desc FROM tbl_hotel_room_booking WHERE pb.product_booking_id = product_booking_id) 'room_desc',
tba.traveller_address1,tba.traveller_address2,tba.traveller_city,
tba.traveller_state,tba.traveller_country,tba.traveller_zip_code,
th.transaction_amount,th.reversal_amount,th.branch_id,th.agent_id,th.transaction_type,
pb.product_booking_id,pb.product_status,pb.provider_confirmation_code,pb.booking_source,pb.product_name,pb.product_type,pb.product_id,
tft.ticket,
(SELECT TOP 1 as_of_date + '_' + hotel_penalty FROM tbl_hotel_room_cancellation WHERE booking_id='0BCE1ABC-EA42-4030-A9F1-CA8D176825C0') 'as_of_date',
tpd.adult_price,tpd.cost_currency,tpd.sell_currency,tpd.booking_fee,tpd.taxes,tpd.exchange_rate,tpd.subagency_markup_val,
tpd.charged_amount,tpd.child_price,tpd.senior_price,tpd.youth_price, tpd.actual_price,(ISNULL(tpd.markup_total,0) + ISNULL(tpd.subagency_markup_val,0)) 'markup_total', tpd.markup_total 'agency_markup'
FROM tbl_booking b
INNER JOIN tbl_product_booking pb ON b.booking_id = pb.booking_id
LEFT JOIN tbl_transaction_history th ON b.booking_ref = th.reference_number
LEFT JOIN tbl_traveller_billing_address tba ON b.booking_id = tba.booking_id
LEFT JOIN tbl_purchasedproduct_details tpd ON b.booking_id = tpd.booking_id
LEFT JOIN tbl_flight_tickets tft ON b.booking_id = tft.booking_id
WHERE b.booking_id = '0BCE1ABC-EA42-4030-A9F1-CA8D176825C0'
AND (th.transaction_type IS NULL OR LOWER(th.transaction_type) = 'booking' OR LOWER(th.transaction_type) = 'creditcardbooking' OR Lower(th.transaction_type) = 'manualbooking')
Finally i know why i'm getting this error..I'm trying to return multiple result from sub query..
(SELECT TOP 2 CAST(isbreakfast AS VARCHAR(10)) + '_' + room_desc FROM tbl_hotel_room_booking WHERE pb.product_booking_id = product_booking_id) 'room_desc',
can any one help how can i return multiple result here.
If you basically left join your query with that table and set filter for top 2 records i think you will get what you want.
SELECT
b.booking_id,
b.booking_ref,
b.destination,
b.room_format,
b.checkin,
b.checkout,
b.booking_status,
b.currency,
b.rooms,
b.booking_date,
b.adults,
b.childs,
b.seniors,
b.youth,
b.child2,
b.booking_type,
pb.amount_charged,
pb.original_total_cost 'total_amount',
b.special_request,
b.cancelled_date,
b.emergency_contact,
b.emergency_email,
CAST(brb.isbreakfast AS VARCHAR(10)) + '_' + brb.room_desc AS 'room_desc'
tba.traveller_address1,
tba.traveller_address2,
tba.traveller_city,
tba.traveller_state,
tba.traveller_country,
tba.traveller_zip_code,
th.transaction_amount,
th.reversal_amount,
th.branch_id,
th.agent_id,
th.transaction_type,
pb.product_booking_id,
pb.product_status,
pb.provider_confirmation_code,
pb.booking_source,
pb.product_name,
pb.product_type,
pb.product_id,
tft.ticket
(SELECT TOP 1 as_of_date + '_' + hotel_penalty FROM tbl_hotel_room_cancellation WHERE booking_id='0BCE1ABC-EA42-4030-A9F1-CA8D176825C0') 'as_of_date',
tpd.adult_price,tpd.cost_currency,tpd.sell_currency,tpd.booking_fee,tpd.taxes,tpd.exchange_rate,tpd.subagency_markup_val,
tpd.charged_amount,tpd.child_price,tpd.senior_price,tpd.youth_price, tpd.actual_price,(ISNULL(tpd.markup_total,0) + ISNULL(tpd.subagency_markup_val,0)) 'markup_total', tpd.markup_total 'agency_markup'
FROM tbl_booking b
INNER JOIN tbl_product_booking pb ON b.booking_id = pb.booking_id
LEFT JOIN tbl_hotel_room_booking brb ON pb.product_booking_id = brb.product_booking_id
LEFT JOIN tbl_transaction_history th ON b.booking_ref = th.reference_number
LEFT JOIN tbl_traveller_billing_address tba ON b.booking_id = tba.booking_id
LEFT JOIN tbl_purchasedproduct_details tpd ON b.booking_id = tpd.booking_id
LEFT JOIN tbl_flight_tickets tft ON b.booking_id = tft.booking_id
WHERE b.booking_id = '0BCE1ABC-EA42-4030-A9F1-CA8D176825C0'
AND brb.isbreakfast IN (Select Top 2 IsBreakfast
FROM tbl_hotel_room_booking)
AND (th.transaction_type IS NULL
OR LOWER(th.transaction_type) = 'booking'
OR LOWER(th.transaction_type) = 'creditcardbooking' OR Lower(th.transaction_type) = 'manualbooking')

SQL Stuff from Subquery

I have a query that returns a list of services and ContractorIDs. I need to stuff these services into a field to join them with another select statement by ContractorID, but I can't figure out how to do it.
The Select that lists the services is "
SELECT DISTINCT SM.ContractorID,
CASE WHEN S.bitRestrictedSelection = 1
THEN S.vchDescription + '*'
ELSE S.vchDescription
END AS vchDescription
FROM tblAscServiceRegionToOperator SRTO
INNER JOIN tblServiceMatrix SM
ON SRTO.OperatorID = 12624
AND SM.ServiceRegionID = SRTO.ServiceRegionID
AND SM.bitPrimaryService = 1
INNER JOIN tblServices S
ON S.ServiceID = SM.ServiceID
This produces the following:
In the example, for Contractor #16 He has 4 services I need to put them in one field called services by joining with another Select statement
I tried the following, but I get errors:
Select DISTINCT CompanyID, vchCompanyName as CompanyName,vchFIDNumber,vchPrimContactName, vchPrimContactEmail
,stuff((','
SELECT DISTINCT
SM.ContractorID,
CASE WHEN S.bitRestrictedSelection = 1
THEN S.vchDescription + '*'
ELSE S.vchDescription
END AS vchDescription
FROM tblAscServiceRegionToOperator SRTO
INNER JOIN tblServiceMatrix SM
ON SRTO.OperatorID = 12624
AND SM.ServiceRegionID = SRTO.ServiceRegionID
AND SM.bitPrimaryService = 1
INNER JOIN tblServices S
ON S.ServiceID = SM.ServiceID
FOR XML PATH('')
), 1, 1, '') as Services from tblCompany
Any assistance is greatly appreciated!!!
The following query would work:
SELECT SS.contractor Contractor,
STUFF((SELECT '; ' + US.vchdescription
FROM ServicesList US
WHERE US.contractor = SS.contractor
FOR XML PATH('')), 1, 1, '') [Services]
FROM ServicesList SS
GROUP BY SS.contractor
ORDER BY 1
I have created a table and inserted there two rows for contractor = 16, for you to get the idea.
You can use the suggestion given to you in the comments, to wrap the first select into a CTE and then perform the STUFF function on that CTE.
You can check a demo of this query here.

Intersect query with no duplicates

I have not used sql server in a large complex scale in years, and Looking for help on how to proper sintax intersect type query to joing these two data sets, and not create duplicate names. Some patients will have both an order and a clinical event entry and some will only have a clinical event.
Data Set 1
SELECT
distinct
ea.alias as FIN,
per.NAME_Last + ', ' + per.NAME_FIRST + ' ' + Isnull(per.NAME_MIDDLE, '') as PatientName,
oa.action_dt_tm as CirOrder,
od.ORIG_ORDER_DT_TM as DischOrder,
e.disch_dt_tm as ActualDisch,
prs.NAME_FULL_FORMATTED as OrderedBy,
from pathway py
join encounter e on e.CERNER_ENCOUNTER_ID = py.encntr_id
join encntr_alias ea on ea.CERNER_ENCNTR_ID = e.CERNER_ENCOUNTER_ID and ea.ENCNTR_ALIAS_TYPE_WCD = 1049
join person per on per.CERNER_PERSON_ID = e.cerner_PERSON_ID
join orders o on o.CERNER_ENCNTR_ID= e.CERNER_ENCOUNTER_ID and o.CATALOG_wCD = '82111' -- communication order
and o.pathway_catalog_id = '43809296' ---Circumcision Order
join order_action oa on oa.[CERNER_ORDER_ID] = o.CERNER_ORDER_ID and oa.ACTION_TYPE_WCD = '2494'--ordered
join orders od on od.CERNER_ENCNTR_ID= e.CERNER_ENCOUNTER_ID and od.CATALOG_WCD = '203520' --- Discharge Patient
join prsnl prs on prs.CERNER_PERSON_ID = oa.order_provider_id
where py.pathway_catalog_id = '43809296' and ---Circumcision Order
oa.action_dt_tm > '2016-01-01 00:00:00'
and oa.ACTION_DT_TM < '2016-01-19 23:59:59'
--use the report prompts as parameters for the action_dt_tm
Data Set 2
SELECT
distinct e.[CERNER_ENCOUNTER_ID],
ea.alias as FIN,
per.NAME_Last + ', ' + per.NAME_FIRST + ' ' + Isnull(per.NAME_MIDDLE, '') as PatientName,
ce.EVENT_END_DT_TM as CircTime,
od.ORIG_ORDER_DT_TM as DischOrder,
e.disch_dt_tm as ActualDisch,
'' OrderedBy, -- should be blank for this set
cv.DISPLAY
from encounter e
join clinical_event ce on e.CERNER_ENCOUNTER_ID = ce.CERNER_ENCNTR_ID
join encntr_alias ea on ea.CERNER_ENCNTR_ID = e.CERNER_ENCOUNTER_ID and ea.ENCNTR_ALIAS_TYPE_WCD = 1049
join person per on per.CERNER_PERSON_ID = e.cerner_PERSON_ID
join orders od on od.CERNER_ENCNTR_ID= e.CERNER_ENCOUNTER_ID and od.CATALOG_WCD = '203520' --- Discharge Patient
left outer join ENCNTR_LOC_HIST elh on elh.CERNER_ENCNTR_ID = e.CERNER_ENCOUNTER_ID
left outer join CODE_VALUE cv on cv.CODE_VALUE_WK = elh.LOC_NURSE_UNIT_WCD
where ce.event_wcd = '201148' ---Newborn Circumcision
and ce.[RESULT_VAL] = 'Newborn Circumcision'
and ce.EVENT_END_DT_TM > '2016-01-01 00:00:00'
and ce.event_end_dt_tm < '2016-01-19 23:59:59’
and ce.RESULT_STATUS_WCD = '25'
and elh.ACTIVE_STATUS_DT_TM < ce.event_end_dt_tm -- Circ time between the location's active time and end time.
and elh.END_EFFECTIVE_DT_TM > ce.[EVENT_END_DT_TM]
--use the report prompts as parameters for the ce.[EVENT_END_DT_TM]
The structure of an intersect query is as simple as:
select statement 1
intersect
select statement 2
intersect
select statement 3
...
This will return all columns that are in both select statements. The columns returned in the select statements must be of the same quantity and type (or at least be convertible to common type).
You can also do an intersect type of query just using inner joins to filter out records in the one query that are not in the other. So for a simple example let's say you have two tables of colors.
Select distinct ColorTable1.Color
from ColorTable1
join ColorTable2
on ColorTable1.Color = ColorTable2.Color
This will return all the distinct colors in ColorTable1 that are also in ColorTable2. Using joins to filter could help your query perform better, but it does take more thought.
Also see: Set Operators (Transact-SQL)

Can you concat with a space-space

I have looked at several of the concat questions and can't seem to make those solutions work for me.
case "tblContestant":
$sql = "SELECT e.id as Id,#n := #n + 1 n, replace(c.name, ',', ' ') as name, c.address, NULL, c.city, c.state, c.phonenumber, c.email, c.sanctionbody, concat(c.id,c.sanctionnumber) as sanctionnumber, mcrc.amount, c.zip, c.jrboater
FROM contestants c
LEFT JOIN main_contestant_register_class mcrc ON mcrc.contestant_id = c.id
LEFT JOIN events e ON e.id = mcrc.event_id, (SELECT #n := 0) m
WHERE e.id = $id";
The above gives me the result of combining c.id with c.sanctionnumber (142155) however I would like a space-space between c.id and c.sanctionnumber
(14 - 2155) or (14-2155) if spaces are not an option.
Thanks in advance!
case "tblContestant":
$sql = "SELECT e.id as Id,#n := #n + 1 n, replace(c.name, ',', ' ') as name, c.address, NULL, c.city, c.state, c.phonenumber, c.email, c.sanctionbody, concat(c.id,' - '+ c.sanctionnumber) as sanctionnumber, mcrc.amount, c.zip, c.jrboater
FROM contestants c
LEFT JOIN main_contestant_register_class mcrc ON mcrc.contestant_id = c.id
LEFT JOIN events e ON e.id = mcrc.event_id, (SELECT #n := 0) m
WHERE e.id = $id";
Avi thanks for your help the issue is resolved! I simply changed the + to a , and it is now giving me the desired results.
concat(c.id,' - '+ c.sanctionnumber) as sanctionnumber, gives me 142155
concat(c.id,' - ', c.sanctionnumber) as sanctionnumber, gives me 14 - 2155

Resources