Stuff function for multiple columns in SQL Server - sql-server

I have some queries to stuff a specific column.
Query 1:
with cte as
(
select distinct
w.Work_WorkID, k.Name as "Secretariat_Attendees"
from
d, m, s, w, a, k
where
d.DataID = m.Map_MapObjID
and m.Map_MapID = s.SubWork_MapID
and s.SubWork_WorkID = w.Work_WorkID
and w.Work_WorkID = a.WF_ID
and d.DataID = 35269818
and a.WF_AttrID = 17
and k.ID = a.WF_ValInt
)
select distinct
t2.Work_WorkID,
stuff((select N' ; ' + Secretariat_Attendees
from (select Work_WorkID, Secretariat_Attendees
from cte t1
where t1.Work_WorkID = t2.Work_WorkID) AS t
for xml path('')), 1, 2, '') + N'' Secretariat_Attendees
from cte t2;
Query 1 output:
Work_WorkID Secretariat_Attendees
----------------------------------------------------
35273587 Admin CEO Office ; BD_TestUser ; Diana
35277687 10023165 ; 10036755 ; 10075193
Query 2:
with cte as (
select Distinct w.Work_WorkID,k.Name as "Committee_Attendees" from d, m, s, w, a, k
where d.DataID=m.Map_MapObjID and m.Map_MapID=s.SubWork_MapID and s.SubWork_WorkID=w.Work_WorkID
and w.Work_WorkID=a.WF_ID and d.DataID=35269818 and a.WF_AttrID=5 and k.ID=a.WF_ValInt
)
select distinct t2.Work_WorkID,
stuff((select N' ; ' + Committee_Attendees
from (select Work_WorkID, Committee_Attendees
from cte t1 where t1.Work_WorkID = t2.Work_WorkID) AS t
for xml path('')
), 1, 2, '') + N'' Committee_Attendees from cte t2;
Query 2 Output:
Work_WorkID Committee_Attendees
35273587 Deva ; User 1
35277687 User3 ; User 4
How do I combine both these query into one to get the below desired output based on Work_WorkID?
Work_WorkID Secretariat_Attendees Committee_Attendees
35273587 Admin CEO Office ; BD_TestUser ; Diana Deva ; User 1
35277687 10023165 ; 10036755 ; 10075193 User3 ; User 4

The only difference between the two queries looks like WF_AttrID column. I moved this predicate to the sub queries. you can try this. And I also changed your table joins syntax to JOIN
with cte as
(
select distinct
w.Work_WorkID, k.Name as "Attendees", a.WF_AttrID
from
DTree d
INNER JOIN WMap m ON d.DataID = m.Map_MapObjID
INNER JOIN WSubWork s ON m.Map_MapID = s.SubWork_MapID
INNER JOIN WWork w ON s.SubWork_WorkID = w.Work_WorkID
INNER JOIN WFAttrData a ON w.Work_WorkID = a.WF_ID
INNER JOIN KUAF k ON k.ID = a.WF_ValInt
where
d.DataID = 35269818
and a.WF_AttrID IN( 5 ,17 )
)
select distinct
t2.Work_WorkID,
stuff((select N' ; ' + Secretariat_Attendees
from (select Work_WorkID, t1.Attendees AS Secretariat_Attendees
from cte t1
where t1.Work_WorkID = t2.Work_WorkID AND t1.WF_AttrID = 17) AS t
for xml path('')), 1, 2, '') + N'' Secretariat_Attendees,
stuff((select N' ; ' + Committee_Attendees
from (select Work_WorkID, t1.Attendees AS Committee_Attendees
from cte t1 where t1.Work_WorkID = t2.Work_WorkID AND t1.WF_AttrID = 5) AS t
for xml path('')
), 1, 2, '') + N'' Committee_Attendees
from cte t2;

This seems to be a simple join. If your difficulty stems from combining them into a single query, all you have to do is replace the second query's cte name to cte2, put the ctes together in the beginning, and use both queries as derived tables:
with cte as(
....first query cte....
)
,cte2 as(
....second query cte
)
select *
from
(
....query 1.....
)t1
inner join
(
......query 2 but "cte2" instead of "cte"....
)t2 on t1.Work_WorkID=t2.Work_WorkID
This is a fast, unoptimized answer. I get the feeling the ctes and the queries have common, optimizable parts. Also, please stop using the onld join notation (from table1,table2,table3.....) and start using join, you can find reasons all over the internet.

Related

SQL Server - Invalid column name

Please help, I have a problematic query to display the column OrderNo2.
the following is the query:
SELECT
V.id, V.TypeApv, V.CreateDate,
P.Requestor, VE.VendorName, V.InvoiceNo, V.Hawb,
PA.PaymentFor, V.Amount, V.Curr, V.DueDate, V.Remarks, V.OrderNo,
(SELECT
STUFF((SELECT DISTINCT ', ' + CASE WHEN [e-SAM Case]='Subsequent' OR [e-SAM Case]='DDT' AND [Local SAP PO] LIKE '5%' OR [e-SAM Case]='FBS 4'
THEN PoNo ELSE [Local SAP PO] END
FROM v_copo VC
WHERE VC.AWB1 = V.Hawb
FOR XML PATH('')), 1, 1, '')) AS OrderNo2,
(SELECT ISNULL(OrderNo2, V.OrderNo)) AS OrderNoFinal
FROM
APV_AF V
LEFT JOIN
APV_Person P ON P.id = V.Requestor
LEFT JOIN
APV_Vendor VE ON VE.IDVendor = V.VendorName
LEFT JOIN
APV_Payment PA ON PA.IDPayment = V.PaymentFor
ORDER BY
V.CreateDate DESC
You cannot reference an alias in the same scope where it was defined (apart from the order by clause). Typical work arounds include a subquery or CTE.
In SQL Server though, a simple option is a lateral join:
SELECT
V.id, V.TypeApv, V.CreateDate,
P.Requestor, VE.VendorName, V.InvoiceNo, V.Hawb,
PA.PaymentFor, V.Amount, V.Curr, V.DueDate, V.Remarks, V.OrderNo,
X.OrderNo2,
ISNULL(X.OrderNo2, V.OrderNo) AS OrderNoFinal
FROM APV_AF V
LEFT JOIN APV_Person P ON P.id = V.Requestor
LEFT JOIN APV_Vendor VE ON VE.IDVendor = V.VendorName
LEFT JOIN APV_Payment PA ON PA.IDPayment = V.PaymentFor
OUTER APPLY (
SELECT
STUFF((SELECT DISTINCT ', ' + CASE WHEN [e-SAM Case]='Subsequent' OR [e-SAM Case]='DDT' AND [Local SAP PO] LIKE '5%' OR [e-SAM Case]='FBS 4'
THEN PoNo ELSE [Local SAP PO] END
FROM v_copo VC
WHERE VC.AWB1 = V.Hawb
FOR XML PATH('')), 1, 1, '') AS OrderNo2
) X
ORDER BY V.CreateDate DESC

how to add subjects in same days column not multiple

I have the records below. I want to show subjects when Monday in column all subjects appear on Monday with start time and end time. How do I do this?
SELECT t.teacher_name, tci.class_name, tsb.Subject_Name, tdn.DaysName,
tss.subject_start, tss.subject_end
FROM tblsubjectSchedule tss
INNER JOIN tblsubjects tsb ON tss.subject_id = tsb.Idx
INNER JOIN tblclassinfo tci ON tss.class_id = tci.Idx
INNER JOIN tbldaysnames tdn ON tss.days_id = tdn.Idx
INNER JOIN tblteacher t ON tss.techer_id = t.Idx
WHERE tss.class_id = 2 AND t.school_id = 1
Your attachment is not completely clear. Are you going to ignore teacher_name on result?
In your screenshot you haven't included 'samad teacheer' on Monday results. You want the query only for Monday date?
If you only focus on class and days and date, I got below. please refer the attachment.Let me know if it works for you and accept my answer.
SELECT t1.class_name,t1.daysname,
subject_name =REPLACE( (SELECT (subject_name+'-start:'+CONVERT(VARCHAR, subject_start, 120)+'-End:'+CONVERT(VARCHAR, subject_end, 120)) AS [data()]
FROM [practice].[dbo].[test] t2
WHERE t2.daysname = t1.daysname
ORDER BY subject_name
FOR XML PATH('')
), ' ', ';')
FROM [practice].[dbo].[test] t1
GROUP BY daysname,class_name ;
You could also add teacher name to the schedule column: see the attachment
SELECT t1.class_name,t1.daysname,
schedule =REPLACE( (SELECT (teacher_name+'-'+subject_name+'-start:'+CONVERT(VARCHAR, subject_start, 120)+'-End:'+CONVERT(VARCHAR, subject_end, 120)) AS [data()]
FROM [practice].[dbo].[test] t2
WHERE t2.daysname = t1.daysname
ORDER BY subject_name
FOR XML PATH('')
), ' ', ';')
FROM [practice].[dbo].[test] t1
GROUP BY daysname,class_name ;
Here is the query only for the 'Monday'
SELECT t1.class_name,t1.daysname,
schedule =REPLACE( (SELECT (teacher_name+'-'+subject_name+'-start:'+CONVERT(VARCHAR, subject_start, 120)+'-End:'+CONVERT(VARCHAR, subject_end, 120)) AS [data()]
FROM [practice].[dbo].[test] t2
WHERE t2.daysname = t1.daysname
ORDER BY subject_name
FOR XML PATH('')
), ' ', ';')
FROM [practice].[dbo].[test] t1 where daysname='Monday'
GROUP BY daysname,class_name ;

Stored procedure part optimization

I have a stored procedure
CREATE PROCEDURE [dbo].[MyProcedure]
-- Add the parameters for the stored procedure here
#xml XML
AS
BEGIN
SET FMTONLY OFF
declare #idoc INT; -- table(CentreId bigint, LanguageId int)
EXEC sp_xml_preparedocument #idoc OUTPUT, #xml
--declare #LangCentre table (CentreId bigint, LanguageId int)
CREATE TABLE #LangCentre
(
CentreId bigint,
LanguageId INT
)
INSERT into #LangCentre (CentreId, LanguageId)(
SELECT * from OPENXML (#idoc, '/T/R', 2) WITH (CentreId BIGINT 'C', LanguageId int 'L'))
CREATE TABLE #LangCentreCTranslation
(
CentreId BIGINT,
LanguageId INT,
CentreTranslationId BIGINT
)
INSERT into #LangCentreCTranslation (CentreId, LanguageId, CentreTranslationId)(
SELECT
lc.CentreId,
lc.LanguageId,
CASE WHEN ct.id IS NULL THEN ct2.id ELSE ct.id END AS CentreTranslationId
FROM #LangCentre lc
LEFT JOIN dbo.CentreTranslation ct ON ct.centre_id = lc.CentreId AND ct.language_id = lc.LanguageId
LEFT JOIN dbo.CentreTranslation ct2 ON ct2.centre_id = lc.CentreId and ct2.language_id = 1
)
SELECT
lcct.CentreTranslationId,
lcct.LanguageId,
lcct.CentreId AS CentreID ,
ptBusinessCentre.about AS BusinessCentreDescription,
ptBusinessCentre.meta_title AS BusinessCentreMetaTitle,
ptBusinessCentre.meta_keywords AS BusinessCentreMetaKeywords,
ptBusinessCentre.meta_description AS BusinessCentreMetaDescription,
ptOffice.about AS OfficeDescription,
ptOffice.meta_title AS OfficeMetaTitle,
ptOffice.meta_keywords AS OfficeMetaKeywords,
ptOffice.meta_description AS OfficeMetaDescription,
ptVirtualOffice.about AS VirtualOfficeDescription,
ptVirtualOffice.meta_title AS VirtualOfficeMetaTitle,
ptVirtualOffice.meta_keywords AS VirtualOfficeMetaKeywords,
ptVirtualOffice.meta_description AS VirtualOfficeMetaDescription,
ptMeetingRoom.about AS MeetingRoomDescription,
ptMeetingRoom.meta_title AS MeetingRoomMetaTitle,
ptMeetingRoom.meta_keywords AS MeetingRoomMetaKeywords,
ptMeetingRoom.meta_description AS MeetingRoomMetaDescription,
ptBusinessLounge.about AS BusinessLoungeDescription,
ptBusinessLounge.meta_title AS BusinessLoungeMetaTitle,
ptBusinessLounge.meta_keywords AS BusinessLoungeMetaKeywords,
ptBusinessLounge.meta_description AS BusinessLoungeMetaDescription,
ptDayOffice.about AS DayOfficeDescription,
ptDayOffice.meta_title AS DayOfficeMetaTitle,
ptDayOffice.meta_keywords AS DayOfficeMetaKeywords,
ptDayOffice.meta_description AS DayOfficeMetaDescription,
ptVideoConferencing.about AS VideoConferencingDescription,
ptVideoConferencing.meta_title AS VideoConferencingMetaTitle,
ptVideoConferencing.meta_keywords AS VideoConferencingMetaKeywords,
ptVideoConferencing.meta_description AS VideoConferencingMetaDescription,
ptManagedOfficeSolutions.about AS ManagedOfficeSolutionsDescription,
ptManagedOfficeSolutions.meta_title AS ManagedOfficeSolutionsMetaTitle,
ptManagedOfficeSolutions.meta_keywords AS ManagedOfficeSolutionsMetaKeywords,
ptManagedOfficeSolutions.meta_description AS ManagedOfficeSolutionsMetaDescription,
ptTelecommunications.about AS TelecommunicationsDescription,
ptTelecommunications.meta_title AS TelecommunicationsMetaTitle,
ptTelecommunications.meta_keywords AS TelecommunicationsMetaKeywords,
ptTelecommunications.meta_description AS TelecommunicationsMetaDescription,
--
ctContact.manager AS CentreManager,
ctContact.area_director AS AreaDirector,
ctContact.rmm AS RMM,
ctContact.operations_director AS OperationsDirector,
ctContact.financial_controller AS FinancialController,
ctContact.sales_fax_line AS SalesFaxLine,
ctContact.agents_hotline AS AgentsHotline,
ctContact.emergency_phone AS EmergencyPhone,
ctContact.emergency_pager AS EmergencyPager,
ctContact.receptionist_phone AS ReceptionistPhone,
ctContact.rsc_speed_dials AS RscSpeedDials,
ctContact.toll_free AS TollFree,
ctContact.voicemail_server AS VoicemailServer,
ctContact.additional_phone AS AdditionalPhone,
ctContact.additional_fax AS AdditionalFax,
ctContact.centre_manager_email as CentreManagerEmail,
ctContact.area_director_address as AreaDirectorEmail,
ctRooms.number_of_offices AS NumberOfOffices,
ctRooms.number_of_meeting_rooms AS NumberOfMeetingRooms,
ctRooms.number_of_training_rooms AS NumberOfTrainingRooms,
ctRooms.number_of_conference_rooms AS NumberOfConferenceRooms,
ctRooms.number_of_workstations AS NumberOfWorkstations,
ctRooms.number_of_floors AS NumberOfFloors,
ctRooms.number_of_parking_spaces AS NumberOfParkingSpaces,
ctRooms.parking_costs AS ParkingCosts,
ctRooms.floor_area AS FloorArea,
ctRooms.floorplan AS Floorplan,
ctOpeningHours.monday_opening AS MondayOpening,
ctOpeningHours.monday_closing AS MondayClosing,
ctOpeningHours.tuesday_opening AS TuesdayOpening,
ctOpeningHours.tuesday_closing AS TuesdayClosing,
ctOpeningHours.wednesday_opening AS WednesdayOpening,
ctOpeningHours.wednesday_closing AS WednesdayClosing,
ctOpeningHours.thursday_opening AS ThursdayOpening,
ctOpeningHours.thursday_closing AS ThursdayClosing,
ctOpeningHours.friday_opening AS FridayOpening,
ctOpeningHours.friday_closing AS FridayClosing,
ctOpeningHours.saturday_opening AS SaturdayOpening,
ctOpeningHours.saturday_closing AS SaturdayClosing,
ctOpeningHours.sunday_opening AS SundayOpening,
ctOpeningHours.sunday_closing AS SundayClosing,
ctOpeningHours.timezone_id AS TimezoneId,
ctLounge.opening_times_text AS OpeningTimesText,
ctLounge.number_of_armchairs AS NumberOfArmchairs,
ctLounge.number_of_seats_in_library as NumberOfSeatsInLibrary,
ctLounge.number_of_bar_stools as NumberOfBarStools,
ctLounge.number_of_other_seats as NumberOfOtherSeats,
ctLounge.number_of_thinkpods AS NumberOfThinkpods,
ctLounge.number_of_mac_pc_bars AS NumberOfMacPcBars,
ctLounge.number_of_flatscreen_tvs AS NumberOfFlatScreenTvs,
ctLounge.number_of_newspapers AS NumberOfNewspapers,
--
ctLounge.lounge_type as LoungeType,
ctLounge.alternative_to_businesslounge as AlternativeToBL,
ctLounge.last_refubrishment_date as LastRefurbishmentDate,
ctLounge.lounge_location_in_centre as LocationInCentre,
ctLounge.lounge_visible_from_outside as VisibleFromOutside,
ctLounge.signage_to_advertise as SignageOutsideToAdvertise,
ctLounge.reason_for_no_advertisment as ReasonForNoAdvertisement,
ctLounge.type_of_access_control as TypeOfAccessControl,
ctLounge.monday_opening as LoungeMondayOpening,
ctLounge.monday_closing as LoungeMondayClosing,
ctLounge.tuesday_opening as LoungeTuesdayOpening,
ctLounge.tuesday_closing as LoungeTuesdayClosing,
ctLounge.wednesday_opening as LoungeWednesdayOpening,
ctLounge.wednesday_closing as LoungeWednesdayClosing,
ctLounge.thursday_opening as LoungeThursdayOpening,
ctLounge.thursday_closing as LoungeThursdayClosing,
ctLounge.friday_opening as LoungeFridayOpening,
ctLounge.friday_closing as LoungeFridayClosing,
ctLounge.saturday_opening as LoungeSaturdayOpening,
ctLounge.saturday_closing as LoungeSaturdayClosing,
ctLounge.sunday_opening as LoungeSundayOpening,
ctLounge.sunday_closing as LoungeSundayClosing,
ctLounge.type_of_location as TypeOfLocation,
ctLounge.parking_facilities as ParkingFacilities,
ctLounge.have_to_pass_through_security as HaveToPassThroughSecurity,
ctLounge.is_advanced_security_notification_requiered as IsAdvancedSecurityNotificationRequiered,
ctLounge.business_lounge_floor as BusinessLoungeFloor,
ctLounge.type_of_room as TypeOfRoom,
ctLounge.suitable_for_disabled as SuitableForDisabled,
ctLounge.does_directly_receive_light as DoesDirectlyReceiveLight,
ctLounge.airconditioning as Airconditioning,
ctLounge.is_wifi_available as IsWifiAvailable,
ctLounge.is_ethernet_available as IsEthernetAvailable,
ctLounge.number_of_computers as NumberOfComputers,
ctLounge.other_internet_access as OtherInternetAccess,
ctLounge.are_beverages_available as AreBeveragesAvailable,
ctLounge.type_of_coffee_available as TypeOfCoffeeAvailable,
ctLounge.copy_fax_print_facilities as CopyFaxPrintFacilities,
ctLounge.business_support as BusinessSupport,
ctLounge.mobile_charging_points as MobileChargingPoints,
ctLounge.newspapers_and_magazines as NewspapersAndMagazines,
ctLounge.bathroom_facilities_available as BathroomFacilitiesAvailable,
ctLounge.showers_available as ShowersAvailable,
(case
when ctLounge.grade=1 then 'Grade A'
when ctLounge.grade=2 then 'Grade B'
when ctLounge.grade=3 then 'Grade C'
when ctLounge.grade=4 then 'Ungraded'
else 'No Value' end) as Grade,
--
ctOtherInfo.bank_name AS BankName,
ctOtherInfo.bank_address AS BankAddress,
ctOtherInfo.bank_account_number AS BankAccountNumber,
ctOtherInfo.bank_sort_code AS BankSortCode,
ctOtherInfo.bank_swift_code AS BankSwiftCode,
ctOtherInfo.vc_equipment AS VcEquipment,
ctOtherInfo.vc_equipment_working AS VcEquipmentWorking,
ctOtherInfo.isdn AS ISDN,
ctOtherInfo.vc_contact AS VcContact,
ctOtherInfo.vc_phone AS VcPhone,
ctOtherInfo.equipment_make AS EquipmentMake,
ctOtherInfo.speed AS Speed,
ctOtherInfo.additional_charges AS AdditionalCharges,
ctOtherInfo.room_capacity AS RoomCapacity,
ctOtherInfo.out_of_hours_vc_contact AS OutOfHoursVcContact,
ctOtherInfo.vc_room_names AS VcRoomNames,
ctOtherInfo.maximum_bandwidth AS MaximumBandwidth,
ctOtherInfo.floodgate_installed AS FloodgateInstalled,
ctOtherInfo.encryption AS Encryption,
ctOtherInfo.underfloor_cat5_cabling AS UnderfloorCat5Cabling,
ctOtherInfo.lockable_comms_rack_space AS LockableCommsRackSpace,
isNULL(ct.name, cn.name) as CentreName,
ct.name as TranslatedName,
ct.address_line_1 as Address1,
ct.address_line_2 as Address2,
ct.address_line_3 as Address3,
ct.city as Town,
ct.postcode as PostalCode,
ct.country as Country,
ct.county as State,
cn.number as Number,
cn.url as Url,
cn.virtual_tour_url as VirtualTourUrl,
(CASE WHEN status.cnt>0 THEN 1 ELSE 0 END) AS ShowCentre,
cnInactivityReason.[description] as ReasonForNotShowing,
cn.alternate_name as AlternateName,
cn.date_opened as OpeningDate,
cn.closed as Closed,
cn.date_closed as DateClosed,
cn.phone as Phone,
cn.fax as Fax,
cn.email as Email,
cn.position.Lat as Latitude,
cn.position.Long as Longtitude,
images.cnt as ImagesCount,
cn.area as Area,
cn.sales_cluster as SalesCluster,
cn.is_additionl_security_check_required as AdditionalSecurityCheck,
ct.country as TranslatedCountry,
cn.virtual_tour as VirtualTour,
ct.about as OriginalDescription,
ct.directions as directions,
cn.centre_profile_id as CentreProfileId,
ct.amenities as AmenitiesFreeText,
STUFF((SELECT ',' + convert(VARCHAR(10), feature_id) FROM dbo.CentreFeature cf LEFT JOIN #LangCentreCTranslation lcct ON cf.Centre_Id = lcct.Centreid ORDER BY feature_id FOR XML PATH('')), 1, 1, '') as FeatureIds,
STUFF((SELECT ',' + convert(VARCHAR(10), brand_id) FROM dbo.CentreBrand cf LEFT JOIN #LangCentreCTranslation lcct ON cf.Centre_Id = lcct.Centreid ORDER BY brand_id FOR XML PATH('')), 1, 1, '') as BrandIds
FROM #LangCentreCTranslation lcct
INNER JOIN dbo.Centre cn on lcct.CentreId = cn.id
LEFT JOIN dbo.CentreTranslation ct ON lcct.CentreTranslationId = ct.id
LEFT JOIN dbo.ProductTranslation ptBusinessCentre ON lcct.CentreTranslationId = ptBusinessCentre.centre_translation_id AND ptBusinessCentre.product_id = 1
LEFT JOIN dbo.ProductTranslation ptOffice ON lcct.CentreTranslationId = ptOffice.centre_translation_id AND ptOffice.product_id = 2
LEFT JOIN dbo.ProductTranslation ptVirtualOffice ON lcct.CentreTranslationId = ptVirtualOffice.centre_translation_id AND ptVirtualOffice.product_id = 3
LEFT JOIN dbo.ProductTranslation ptMeetingRoom ON lcct.CentreTranslationId = ptMeetingRoom.centre_translation_id AND ptMeetingRoom.product_id = 4
LEFT JOIN dbo.ProductTranslation ptBusinessLounge ON lcct.CentreTranslationId = ptBusinessLounge.centre_translation_id AND ptBusinessLounge.product_id = 5
LEFT JOIN dbo.ProductTranslation ptDayOffice ON lcct.CentreTranslationId = ptDayOffice.centre_translation_id AND ptDayOffice.product_id = 6
LEFT JOIN dbo.ProductTranslation ptVideoConferencing ON lcct.CentreTranslationId = ptVideoConferencing.centre_translation_id AND ptVideoConferencing.product_id = 11
LEFT JOIN dbo.ProductTranslation ptTelecommunications ON lcct.CentreTranslationId = ptTelecommunications.centre_translation_id AND ptTelecommunications.product_id = 12
LEFT JOIN dbo.ProductTranslation ptManagedOfficeSolutions ON lcct.CentreTranslationId = ptManagedOfficeSolutions.centre_translation_id AND ptManagedOfficeSolutions.product_id = 14
LEFT JOIN dbo.CentreContact ctContact ON lcct.CentreId = ctContact.centre_id
LEFT JOIN dbo.CentreRooms ctRooms ON lcct.CentreId = ctRooms.centre_id
LEFT JOIN dbo.CentreOpeningHours ctOpeningHours ON lcct.CentreId = ctOpeningHours.centre_id
LEFT JOIN dbo.CentreLounge ctLounge ON lcct.CentreId = ctLounge.centre_id
LEFT JOIN dbo.CentreOtherInfo ctOtherInfo ON lcct.CentreId = ctOtherInfo.centre_id
LEFT JOIN (SELECT centre_id, COUNT (*) as cnt from dbo.CentreStatus GROUP BY centre_id) status ON status.centre_id=lcct.CentreId
LEFT JOIN dbo.CentreInactivityReason cnInactivityReason ON cn.inactivity_reason = cnInactivityReason.id
LEFT JOIN (SELECT centre_id, COUNT (*) as cnt from dbo.Image2Centre GROUP BY centre_id) images ON images.centre_id=lcct.CentreId
ORDER BY isNULL(ct.name, cn.name)
DROP TABLE #LangCentreCTranslation
DROP TABLE #LangCentre
EXEC sp_xml_removedocument #idoc
-- Insert statements for procedure here
END
The SP processes approximately 2700 records. The problem in this SP is that if I don't disable
STUFF((SELECT ',' + convert(VARCHAR(10), feature_id) FROM dbo.CentreFeature cf LEFT JOIN #LangCentreCTranslation lcct ON cf.Centre_Id = lcct.Centreid ORDER BY feature_id FOR XML PATH('')), 1, 1, '') as FeatureIds,
STUFF((SELECT ',' + convert(VARCHAR(10), brand_id) FROM dbo.CentreBrand cf LEFT JOIN #LangCentreCTranslation lcct ON cf.Centre_Id = lcct.Centreid ORDER BY brand_id FOR XML PATH('')), 1, 1, '') as BrandIds
this SP will execute in ~13 minutes, but with the above lines commented\removed it will execute in ~30s, how can I optimize these particular parts of SP to increase their performance. I can provide tables structure\execution plan if needed (don't know how to attach files though). Any help is appreciated.
If you look at the following 2 lines, you will notice that they are independent of the parent query.
STUFF((SELECT ',' + convert(VARCHAR(10), feature_id)
FROM dbo.CentreFeature cf
LEFT JOIN #LangCentreCTranslation lcct
ON cf.Centre_Id = lcct.Centreid ORDER BY feature_id FOR XML PATH('')), 1, 1, '') as FeatureIds,
and
STUFF((SELECT ',' + convert(VARCHAR(10), brand_id)
FROM dbo.CentreBrand cf
LEFT JOIN #LangCentreCTranslation lcct
ON cf.Centre_Id = lcct.Centreid ORDER BY brand_id FOR XML PATH('')), 1, 1, '') as BrandIds
These queries do no not refer any column from the parent query. If this is what you want, you can create two variables and assign values from these queries and use the variables in the final SELECT.
I assume you are trying to accomplish something like this.
STUFF((SELECT ',' + convert(VARCHAR(10), feature_id)
FROM dbo.CentreFeature cf
WHERE cf.Centre_Id = lcct.Centreid ORDER BY feature_id FOR XML PATH('')), 1, 1, '') as FeatureIds,
and
STUFF((SELECT ',' + convert(VARCHAR(10), brand_id)
FROM dbo.CentreBrand cf
WHERE cf.Centre_Id = lcct.Centreid ORDER BY brand_id FOR XML PATH('')), 1, 1, '') as BrandIds
Notice that I have removed the JOIN and added a WHERE clause to refer the value of lcct.Centreid from the parent query and made this sub-query a co-related sub-query.
You can also optionally do this when you insert data into#LangCentreCTranslation
INSERT into #LangCentreCTranslation (CentreId, LanguageId, CentreTranslationId,BrandIds,FeatureIds)(
SELECT
lc.CentreId,
lc.LanguageId,
CASE WHEN ct.id IS NULL THEN ct2.id ELSE ct.id END AS CentreTranslationId,
STUFF((SELECT ',' + convert(VARCHAR(10), brand_id) FROM dbo.CentreBrand cf WHERE cf.Centre_Id = lc.Centreid ORDER BY brand_id FOR XML PATH('')), 1, 1, '') as BrandIds,
STUFF((SELECT ',' + convert(VARCHAR(10), feature_id) FROM dbo.CentreFeature cf WHERE cf.Centre_Id = lc.Centreid ORDER BY feature_id FOR XML PATH('')), 1, 1, '') as FeatureIds
FROM #LangCentre lc
LEFT JOIN dbo.CentreTranslation ct ON ct.centre_id = lc.CentreId AND ct.language_id = lc.LanguageId
LEFT JOIN dbo.CentreTranslation ct2 ON ct2.centre_id = lc.CentreId and ct2.language_id = 1
)

SQL Pivot dynamic query error

I tried to convert rows values into columns...Below is my query...
Select * from (SELECT *
FROM ( SELECT PROJ.PROJ_ID,
PROJ.PROJ_NM AS [Project Name],
PROJ.PROJ_DS AS [Project Description],
convert(varchar(10), PROJ.PROJ_ACTL_LNCH_DT, 110) [Actual Completed Date],
PROJ.PROJ_SMRY_DS AS [Project Summary],
dbo.udf_BankContacts(PROJ.PROJ_ID) AS [BankContact],
convert(varchar(10), PROJ.PROJ_EST_LNCH_DT, 110) AS [Estimated Launch Date],
PROJ.ENTER_DT AS [Begin Date],
PROJ_STA.PROJ_STA_DS AS [Project Status],
SFTW_DEV_MTHD.SFTW_DEV_MTHD_NM AS [Software Development Method],
PROJ_PHASE.PROJ_PHASE_DS AS [Phase],
PROJ_CTGY.PROJ_CTGY_DS AS [Project Category],
(CASE WHEN PROJ.ARCH_IN='0' THEN 'N' ELSE 'C' END) AS [Archive],
PROJ.PHASE_CMNT_TX AS [Phase Comment],
PROD_TYPE_DS
FROM dbo.Project PROJ
left join dbo.PROJ_PROD PP on PROJ.PROJ_ID = PP.PROJ_ID
left join dbo.PROD_TYPE PT on PP.PROD_TYPE_ID = PT.PROD_TYPE_ID
LEFT JOIN DBO.PROJ_STA ON PROJ.PROJ_STA_ID = PROJ_STA.PROJ_STA_ID
left join dbo.SFTW_DEV_MTHD on PROJ.SFTW_DEV_MTHD_ID = SFTW_DEV_MTHD.SFTW_DEV_MTHD_ID
left join dbo.PROJ_PHASE on PROJ.PROJ_PHASE_ID = PROJ_PHASE.PROJ_PHASE_ID
left join dbo.PROJ_CTGY on PROJ.PROJ_CTGY_ID = PROJ_CTGY.PROJ_CTGY_ID
) data
PIVOT
( MAX(PROD_TYPE_DS)
FOR PROD_TYPE_DS IN ([PT1],[PT2])
) pvt2
where PROJ_ID is not null) AS ProdType
LEFT JOIN (SELECT *
FROM
(
select PROJ_ID,
PROJ_APRV_TYPE_DS = case
when col ='PROJ_APRV_TYPE_DS'
then PROJ_APRV_TYPE_DS
else PROJ_APRV_TYPE_DS+col end,
value
from
(
SELECT PROJ.PROJ_ID,
PAT.PROJ_APRV_TYPE_DS PROJ_APRV_TYPE_DS,
convert(varchar(10), PATS.APRV_EXPT_BY_DT, 120) APRV_EXPT_BY_DT,
convert(varchar(10), PATS.APRV_CMPL_DT, 120) APRV_CMPL_DT
FROM dbo.Project PROJ
left join [dbo].[PROJ_APRV_TYPE_STA] PATS
on PROJ.PROJ_ID = PATS.PROJ_ID
left join [dbo].[PROJ_APRV_STA] PAS
on PATS.PROJ_APRV_STA_ID = PAS.PROJ_APRV_STA_ID
right outer join dbo.PROJ_APRV_TYPE PAT
on PATS.PROJ_APRV_TYPE_ID = PAT.PROJ_APRV_TYPE_ID
) s
cross apply
(
select 'PROJ_APRV_TYPE_DS', PROJ_APRV_TYPE_DS union all
select ' Expected Date', APRV_EXPT_BY_DT union all
select ' Completed Date', APRV_CMPL_DT
) c (col, value)
) data
PIVOT
(
MAX(value)
FOR PROJ_APRV_TYPE_DS IN ([RMC Approval],[RMC Approval Expected Date],[RMC Approval Completed Date],[BOD Approval],[BOD Approval Expected Date],[BOD Approval Completed Date])
) pvt1 where PROJ_ID is not null ) AS Approval ON ProdType.PROJ_ID = Approval.PROJ_ID
LEFT JOIN (SELECT *
FROM ( SELECT PROJ.PROJ_ID,
ORG_SHRT_NM
FROM dbo.Project PROJ
left join dbo.PROJ_LGL_ENT_IMPCT PLEI on PROJ.PROJ_ID = PLEI.PROJ_ID
right outer join dbo.LGL_ENT LE on PLEI.LGL_ENT_ID = LE.LGL_ENT_ID
) data
PIVOT
( MAX(ORG_SHRT_NM)
FOR ORG_SHRT_NM IN ([AECB],[FSB],[TRS])
) pvt3
where PROJ_ID is not null) AS LegalEntity ON ProdType.PROJ_ID = LegalEntity.PROJ_ID LEFT JOIN
(;with cte as
(
SELECT PCGU.PROJ_ID,
name = u.USER_LST_NM + ', '+ u.USER_FIRST_NM,
CTC_GRP_DS
FROM dbo.[user] u
left join dbo.PROJ_CTC_GRP_USER PCGU
on u.USER_ID = PCGU.USER_ID
left join dbo.CTC_GRP CG
on PCGU.CTC_GRP_ID = CG.CTC_GRP_ID
)
select *
from
(
select c1.proj_id,
c1.CTC_GRP_DS,
STUFF(
(SELECT ', ' + c2.name
FROM cte c2
where c1.proj_id = c2.proj_id
and c1.CTC_GRP_DS = c2.CTC_GRP_DS
FOR XML PATH (''))
, 1, 1, '') AS name
from cte c1
) d
pivot
(
max(name)
for CTC_GRP_DS in ([Bank Contact],[Dept2])
) piv
where PROJ_ID is not null)
AS Dept ON ProdType.PROJ_ID = Dept.PROJ_ID
I am getting error
Msg 102, Level 15, State 1, Line 84
Incorrect syntax near ';'.
Msg 102, Level 15, State 1, Line 115
Incorrect syntax near ')'.
I am totally confused what i am missing it. I recently started pivot & dynamic query concepts...Please guide on it...
Your error is here.
(;with cte as
(
SELECT PCGU.PROJ_ID,
name = u.USER_LST_NM + ', '+ u.USER_FIRST_NM,
CTC_GRP_DS
FROM dbo.[user] u
left join dbo.PROJ_CTC_GRP_USER PCGU
on u.USER_ID = PCGU.USER_ID
left join dbo.CTC_GRP CG
on PCGU.CTC_GRP_ID = CG.CTC_GRP_ID
)
select *
from
(
select c1.proj_id,
c1.CTC_GRP_DS,
STUFF(
(SELECT ', ' + c2.name
FROM cte c2
where c1.proj_id = c2.proj_id
and c1.CTC_GRP_DS = c2.CTC_GRP_DS
FOR XML PATH (''))
, 1, 1, '') AS name
from cte c1
) d
You cannot have a CTE in sub selects like that.
You could try to put the CTE at the very top, or create a temp table for the select.
The error is with your CTE. You can't stick a CTE inside a query like that
(;with cte as

SQL- Subquery with aggregate functions (SQL Server)

My set up is as thus: I have three tables-
Students (StudentID, FirstName, LastName etc.),
StudentSemesters(StudentID,SemID etc.), and
Semesters(SemID, Year)
My requirement is to, get the details for each student but only for their last semester. Logically this implies the semester with the highest year number. I cannot seem to get the Query right. For simplicity 'Year' is just an integer (e.g. 2000, 1998). Below is the current query that I have been stuck at for some time:
SELECT dbo.Student.LastName + ' , ' + dbo.Student.FirstName AS Student, dbo.Student.Defence1Date, dbo.Student.Defence2Date, COUNT(StudentSemesters_1.SemID)
AS SemesterCount, dbo.Student.EntrySemester + ' - ' +
(SELECT dbo.StudentSemesters.SemID
FROM dbo.StudentSemesters INNER JOIN
dbo.ListSemesters ON dbo.StudentSemesters.SemID = dbo.ListSemesters.SemID
WHERE (dbo.Student.StudentCode = dbo.StudentSemesters.StudentCode)
GROUP BY dbo.StudentSemesters.SemID, dbo.ListSemesters.Year
HAVING (dbo.ListSemesters.Year = MAX(dbo.ListSemesters.Year))) AS Expr1
FROM dbo.Student INNER JOIN
dbo.StudentSemesters AS StudentSemesters_1 ON dbo.Student.StudentCode = StudentSemesters_1.StudentCode
GROUP BY dbo.Student.LastName, dbo.Student.FirstName, dbo.Student.Defence1Date, dbo.Student.Defence2Date, dbo.Student.EntrySemester,
dbo.Student.StudentCode
You can do this to get the details for only the last semester for each student:
SELECT
s.LastName + ' , ' + s.FirstName AS Student,
s.Defence1Date,
s.EntrySemester + ' - ' + s1.SemId AS Expr1
FROM dbo.Student AS s
INNER JOIN dbo.StudentSemesters AS S1 ON s.StudentCode = S1.StudentCode
INNER JOIN dbo.ListSemesters AS lm ON lm.SemID = s1.SemId
INNER JOIN
(
SELECT SemId, MAX(Year) AS MaxYear
FROM dbo.StudentSemesters
GROUP BY SemId
) AS s2 ON s2.semId = lm.SemId AND ls.Year = s2.MaxYear;
However, if you're using SQL Server 2005+, you can use the window function to do so:
WITH CTE
AS
(
SELECT
s.LastName + ' , ' + s.FirstName AS Student,
s.Defence1Date,
s.EntrySemester + ' - ' + s1.SemId AS Expr1,
ROW_NUMBER() OVER(PARTITION BY s1.SemId
ORDER BY Year DESC) AS RowNumber
FROM dbo.Student AS s
INNER JOIN dbo.StudentSemesters AS S1 ON s.StudentCode = S1.StudentCode
INNER JOIN dbo.ListSemesters AS lm ON lm.SemID = s1.SemId
)
SELECT
Student,
Defence1Date,
Expr1,
FROM CTE
WHERE RN = 1;
But this won't get the SemesterCount, but you might be able to make it like this (this is just a guess):
SELECT
s.LastName + ' , ' + s.FirstName AS Student,
s.Defence1Date,
s1.SemCount,
s.EntrySemester + ' - ' + s1.SemId AS Expr1
FROM dbo.Student AS s
INNER JOIN
(
SELECT StudentCode, COUNT(SemId) AS SemCount
FROM dbo.StudentSemesters
GROUP BY StudentCode
) AS S1 ON s.StudentCode = S1.StudentCode
INNER JOIN dbo.ListSemesters AS lm ON lm.SemID = s1.SemId
INNER JOIN
(
SELECT SemId, MAX(Year) AS MaxYear
FROM dbo.StudentSemesters
GROUP BY SemId
) AS s2 ON s2.semId = lm.SemId AND ls.Year = s2.MaxYear;

Resources