Order By Case multiple fields - sql

The code below (and numerous codes like it) continues to return blanks.
Basically, if LaborCode = '01 - SC' then it should sort by JobSite, LaborCode, and Schedule (the exact date)
If it's NOT 01 - SC, it should sort by JobSite, LaborCode, and DayNo (the day of the week)
Select Distinct Agreements.AgrmntID, Agreements.Description, Agreements.Status,
JobSites.SiteName, JobSites.Address2, JobSites.City, Customers.CustName,
Customers.CompanyName, LaborCodeTypes.RepairCode As LaborCode, Schedule = Case
LaborCodeTypes.RepairCode
When '01 - SC' Then Left(Convert(varchar,AgreementSchedules.SchedDate,110),
10) Else DateName(dw, AgreementSchedules.SchedDate)
End, Employees1.EmpName As Vendor, Employees.EmpName As [Area Manager],
DatePart(dw, AgreementSchedules.SchedDate) As DayNo
From Agreements Inner Join
Customers On Agreements.CustID = Customers.CustID Inner Join
AgreementSchedules On Agreements.AgrmntID = AgreementSchedules.AgrmntID
Inner Join
JobSites On Agreements.CustSiteID = JobSites.CustSiteID Left Outer Join
LaborCodeTypes On AgreementSchedules.RepairID = LaborCodeTypes.RepairID
Left Outer Join
Employees On AgreementSchedules.FormanEmpID = Employees.EmployeeID Left Join
WorkOrderSchedules On WorkOrderSchedules.ScheduleID =
AgreementSchedules.ScheduleID And AgreementSchedules.ScheduleID =
WorkOrderSchedules.ScheduleID Left Join
WorkOrderScheduleTechs On WorkOrderSchedules.ScheduleID =
WorkOrderScheduleTechs.ScheduleID Left Join
Employees Employees1 On WorkOrderScheduleTechs.EmployeeID =
Employees1.EmployeeID
Where Agreements.Status = 2 And LaborCodeTypes.RepairCode <> 'Vendor Bill' And
Month(AgreementSchedules.SchedDate) = Month(GetDate())
Order By Case
When [LaborCodeTypes.RepairCode] In ('01 - SC') Then JobSites.SiteName +
LaborCodeTypes.RepairCode + Schedule
Else JobSites.SiteName + LaborCodeTypes.RepairCode + DayNo End
Thank you for your help!!

Try this:
ORDER BY JobSites.SiteName,
LaborCodeTypes.RepairCode,
CASE WHEN LaborCodeTypes.RepairCode IN ('01 - SC') THEN Schedule ELSE DayNo END

Okay, in SQL Server:
CREATE PROCEDURE dbo.Agreements_GetList
AS
BEGIN
SET NOCOUNT ON;
SELECT DISTINCT
a.AgrmntID,
a.Description,
a.Status,
js.SiteName,
js.Address2,
js.City,
c.CustName,
c.CompanyName,
LaborCode = lct.RepairCode,
Schedule = CASE lct.RepairCode
WHEN '01 - SC' THEN CONVERT(CHAR(10), aSch.SchedDate, 110)
--------------------^^^ much better than LEFT and not specifying length
ELSE DATENAME(WEEKDAY, aSch.SchedDate) END,
Vendor = e2.EmpName,
[Area Manager] = e1.EmpName,
DayNo = CONVERT(CHAR(1), DATEPART(WEEKDAY, aSch.SchedDate))
--------^^^ this convert is important
FROM dbo.Agreements AS a
INNER JOIN dbo.Customers AS c
ON a.CustID = c.CustID
INNER JOIN dbo.AgreementSchedules AS aSch
ON a.AgrmntID = aSch.AgrmntID
INNER JOIN dbo.JobSites AS js
ON a.CustSiteID = js.CustSiteID
LEFT OUTER JOIN dbo.LaborCodeTypes AS lct
ON aSch.RepairID = lct.RepairID
LEFT OUTER JOIN dbo.Employees AS e1
ON aSch.FormanEmpID = e1.EmployeeID
LEFT OUTER JOIN dbo.WorkOrderSchedules AS w
ON w.ScheduleID = aSch.ScheduleID
LEFT OUTER JOIN dbo.WorkOrderScheduleTechs AS wt
ON w.ScheduleID = wt.ScheduleID
LEFT OUTER JOIN dbo.Employees AS e2
ON wt.EmployeeID = e2.EmployeeID
WHERE
a.Status = 2
AND lct.RepairCode <> 'Vendor Bill'
AND aSch.SchedDate >= DATEADD(MONTH, 0, DATEDIFF(MONTH, 0, GETDATE()))
AND aSch.SchedDate < DATEADD(MONTH, 1, DATEDIFF(MONTH, 0, GETDATE()))
ORDER BY
js.SiteName,
lct.RepairCode,
CASE WHEN lct.RepairCode = '01 - SC'
THEN js.SiteName ELSE DayNo END;
END
GO
Now I have absolutely no knowledge of your application, so you will have to figure out how to call a stored procedure from it instead of embedding SQL.

Related

IF, then, else in SQL query to combine multiple columns

I currently have an SQL query that is used to create a matter report for our firms. The problem with it at the moment is that it creates six columns for client/party details which could be reduced to three columns to minimise confusion for the secretaries that will review before the report is used in marketing.
There's three client types - individual, joint party or organisation.
The six columns in the report are ClientFirstName, ClientLastName, ClientEmail (which are all populated if the ClientType is Individual) and PartyFirstName, PartyLastName, PartyEmail (which are all populated if the ClientType is Joint Part or Organisation - sometimes multiple results for each party member).
Here's the query:
SELECT DISTINCT
-- setup columns
[cases].[reference] as MatterNumber,
[dd_entity_d2].[type] as ClientType,
[dd_client].[clientname] as MatterName,
etClient.FirstName as ClientFirstName,
etClient.LastName as ClientLastName,
[dd_entity_d2].[email] as ClientEmail,
[dd_entity_d4].[firstname] as PartyFirstName,
[dd_entity_d4].[lastname] as PartyLastName,
[dd_entity_d4].[email] as PartyEmail,
etActing.[PreferredName] ActingPerson,
[cases].[category] as MatterType,
mt.CreatedOn as MatterOpened,
case mt.[Status]
when 0 then 'In Progress'
When 1 then 'On Hold'
when 2 then 'Completed'
when 3 then 'Not Proceeding'
else 'Unknown' end as MatterStatus
-- mt.LastUpdatedOn as LastModified,
-- end columns
-- setup data
FROM PracticeEvolve_doc.dbo.[cases]
INNER JOIN PracticeEvolve_c1.dbo.DocumaticsMap dm on dm.DocumaticsID = [cases].ID and dm.Entitytype = 'Matter'
INNER JOIN PracticeEvolve_c1.dbo.[Matter] mt on mt.Matterid = dm.ClickOneID
INNER JOIN PracticeEvolve_c1.dbo.[Client] cl on mt.ClientID = cl.ClientID
INNER JOIN PracticeEvolve_c1.dbo.[Entity] etClient on cl.EntityID = etClient.EntityID
LEFT JOIN PracticeEvolve_c1.dbo.EmployeeMatter emActing on emActing.MatterID = mt.MatterID and emActing.AssociationTypeID = 15
LEFT JOIN PracticeEvolve_c1.dbo.Employee eActing on eActing.EmployeeID = emActing.EmployeeID
LEFT JOIN PracticeEvolve_c1.dbo.Entity etActing on etActing.EntityID = eActing.EntityID
LEFT JOIN PracticeEvolve_doc.dbo.[dd_client] ON [dd_client].[id]=[cases].[clientid]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_entity_d2] ON [dd_manytomanydd_entity_d2].[fkid] = [dd_client].[fk_entities]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_entity] as [dd_entity_d2] ON [dd_entity_d2].[id] = [dd_manytomanydd_entity_d2].[pkid]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_party_d3] ON [dd_manytomanydd_party_d3].[fkid] = [dd_entity_d2].[fk_parties]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_party] as [dd_party_d3] ON [dd_party_d3].[id] = [dd_manytomanydd_party_d3].[pkid]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_entity_d4] ON [dd_manytomanydd_entity_d4].[fkid] = [dd_party_d3].[fk_entity]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_entity] as [dd_entity_d4] ON [dd_entity_d4].[id] = [dd_manytomanydd_entity_d4].[pkid]
-- end data
-- setup filters
WHERE [cases].[deleted]=0
AND DATEPART(m, mt.CreatedOn) = DATEPART(m, DATEADD(m, -1, getdate()))
AND DATEPART(yyyy, mt.CreatedOn) = DATEPART(yyyy, DATEADD(m, -1, getdate()))
-- AND mt.CreatedOn >= '2017-05-16'
-- AND [dd_entity_d2].[type] = 'Individual'
-- AND mt.LastUpdatedOn >= '2017-04-02'
-- AND mt.[status] = 0
-- end filters and query
What I'd like to do is have it just use the columns FirstName, LastName and Email so that it is populated with the individual's details if the ClientType is individual, or populated with the joint party's/organisation's details if the ClientType is something other than Individual.
Is this possible?
(as a bit of a disclaimer - I'm a novice with database queries, so may not know how to implement a specific statement or string)
You can use Case Statement. I assumed Client type is stored as text but you can change 'individual' to appropriate value.
SELECT DISTINCT
-- setup columns
[cases].[reference] as MatterNumber,
[dd_entity_d2].[type] as ClientType,
[dd_client].[clientname] as MatterName,
CASE WHEN [dd_entity_d2].[type] ='Individual' THEN etClient.FirstName ELSE [dd_entity_d4].[firstname] END AS FirstName,
CASE WHEN [dd_entity_d2].[type] ='Individual' THEN etClient.LastName ELSE [dd_entity_d4].[lastname] END AS LastName,
CASE WHEN [dd_entity_d2].[type] ='Individual' THEN [dd_entity_d2].[email] ELSE [dd_entity_d4].[email] END AS Email,
etActing.[PreferredName] ActingPerson,
[cases].[category] as MatterType,
mt.CreatedOn as MatterOpened,
case mt.[Status]
when 0 then 'In Progress'
When 1 then 'On Hold'
when 2 then 'Completed'
when 3 then 'Not Proceeding'
else 'Unknown' end as MatterStatus
-- mt.LastUpdatedOn as LastModified,
-- end columns
-- setup data
FROM PracticeEvolve_doc.dbo.[cases]
INNER JOIN PracticeEvolve_c1.dbo.DocumaticsMap dm on dm.DocumaticsID = [cases].ID and dm.Entitytype = 'Matter'
INNER JOIN PracticeEvolve_c1.dbo.[Matter] mt on mt.Matterid = dm.ClickOneID
INNER JOIN PracticeEvolve_c1.dbo.[Client] cl on mt.ClientID = cl.ClientID
INNER JOIN PracticeEvolve_c1.dbo.[Entity] etClient on cl.EntityID = etClient.EntityID
LEFT JOIN PracticeEvolve_c1.dbo.EmployeeMatter emActing on emActing.MatterID = mt.MatterID and emActing.AssociationTypeID = 15
LEFT JOIN PracticeEvolve_c1.dbo.Employee eActing on eActing.EmployeeID = emActing.EmployeeID
LEFT JOIN PracticeEvolve_c1.dbo.Entity etActing on etActing.EntityID = eActing.EntityID
LEFT JOIN PracticeEvolve_doc.dbo.[dd_client] ON [dd_client].[id]=[cases].[clientid]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_entity_d2] ON [dd_manytomanydd_entity_d2].[fkid] = [dd_client].[fk_entities]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_entity] as [dd_entity_d2] ON [dd_entity_d2].[id] = [dd_manytomanydd_entity_d2].[pkid]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_party_d3] ON [dd_manytomanydd_party_d3].[fkid] = [dd_entity_d2].[fk_parties]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_party] as [dd_party_d3] ON [dd_party_d3].[id] = [dd_manytomanydd_party_d3].[pkid]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_manytomany] AS [dd_manytomanydd_entity_d4] ON [dd_manytomanydd_entity_d4].[fkid] = [dd_party_d3].[fk_entity]
LEFT JOIN PracticeEvolve_doc.dbo.[dd_entity] as [dd_entity_d4] ON [dd_entity_d4].[id] = [dd_manytomanydd_entity_d4].[pkid]
-- end data
-- setup filters
WHERE [cases].[deleted]=0
AND DATEPART(m, mt.CreatedOn) = DATEPART(m, DATEADD(m, -1, getdate()))
AND DATEPART(yyyy, mt.CreatedOn) = DATEPART(yyyy, DATEADD(m, -1, getdate()))
-- AND mt.CreatedOn >= '2017-05-16'
-- AND [dd_entity_d2].[type] = 'Individual'
-- AND mt.LastUpdatedOn >= '2017-04-02'
-- AND mt.[status] = 0
-- end filters and query

SUM RESULTS OF CASE STATEMENTS

I've this query working fine. I need to have the sum of the column "piedini". Can you help me to undestand how to do? I obtain X row for each "Lunghezza" (lenght) that the query find. I'm not interested to this field but only to the sum o column "piedini" created from the CASE SUM.
SELECT
EXTRAMAG.PRS_LUNGHEZZA,SUM(RIGHEDOCUMENTI.QTAGEST) AS TAVOLI, CASE WHEN EXTRAMAG.PRS_LUNGHEZZA < '2000' THEN SUM(RIGHEDOCUMENTI.QTAGEST)*4 ELSE SUM(RIGHEDOCUMENTI.QTAGEST)*6 END AS PIEDINI
FROM dbo.TESTEDOCUMENTI
INNER JOIN dbo.ANAGRAFICACF
ON CODCLIFOR=CODCONTO
INNER JOIN dbo.RIGHEDOCUMENTI
ON PROGRESSIVO=IDTESTA AND TOTNETTORIGA <>'0' AND RIGHEDOCUMENTI.DESCRIZIONEART LIKE '%TAVOL%'
INNER JOIN dbo.EXTRAMAG
ON RIGHEDOCUMENTI.CODART=EXTRAMAG.CODART
LEFT JOIN .dbo.ANAGRAFICAAGENTI
ON CODAGENTE=CODAGENTE1
LEFT JOIN dbo.TABPAGAMENTI
ON CODPAGAMENTO = CODICE
WHERE dbo.TESTEDOCUMENTI.DOCCHIUSO = '0' AND dbo.TESTEDOCUMENTI.BLOCCATO = '0' AND dbo.TESTEDOCUMENTI.TIPODOC = 'ORC' AND TESTEDOCUMENTI.DATACONSEGNA BETWEEN DATEADD(DAY, -60, GETDATE()) AND GETDATE()
GROUP BY EXTRAMAG.PRS_LUNGHEZZA
Try the below :
select sum(PIEDINI) from (
SELECT XTRAMAG.PRS_LUNGHEZZA,SUM(RIGHEDOCUMENTI.QTAGEST) AS TAVOLI, CASE WHEN EXTRAMAG.PRS_LUNGHEZZA < '2000' THEN SUM(RIGHEDOCUMENTI.QTAGEST)*4 ELSE SUM(RIGHEDOCUMENTI.QTAGEST)*6 END AS PIEDINI
FROM dbo.TESTEDOCUMENTI
INNER JOIN dbo.ANAGRAFICACF
ON CODCLIFOR=CODCONTO
INNER JOIN dbo.RIGHEDOCUMENTI
ON PROGRESSIVO=IDTESTA AND TOTNETTORIGA <>'0' AND RIGHEDOCUMENTI.DESCRIZIONEART LIKE '%TAVOL%'
INNER JOIN dbo.EXTRAMAG
ON RIGHEDOCUMENTI.CODART=EXTRAMAG.CODART
LEFT JOIN .dbo.ANAGRAFICAAGENTI
ON CODAGENTE=CODAGENTE1
LEFT JOIN dbo.TABPAGAMENTI
ON CODPAGAMENTO = CODICE
WHERE dbo.TESTEDOCUMENTI.DOCCHIUSO = '0' AND dbo.TESTEDOCUMENTI.BLOCCATO = '0' AND dbo.TESTEDOCUMENTI.TIPODOC = 'ORC' AND TESTEDOCUMENTI.DATACONSEGNA BETWEEN DATEADD(DAY, -60, GETDATE()) AND GETDATE()
GROUP BY EXTRAMAG.PRS_LUNGHEZZA
)t

Only one expression can be specified in the select list when the subquery is introduced

I have this stored procedure...
SELECT
LTRIM(RTRIM([OF].OF_DISPLAYNAME)) AS [Officer_Name],
LTRIM(RTRIM([OF].OF_PIN)) AS Officer_Pin,
LTRIM(RTRIM([TO].TO_ACTIVITY)) AS Template_Site,
AC.AC_NAME AS Site_Name,
ZN.ZN_MANAGER AS Site_Manager,
AR.AR_DESCRIPTION AS Scheduler,
CONVERT(VARCHAR(10), #WeekCommencing, 6) AS [Week_Commencing],
CONVERT(VARCHAR(10), [OF].OF_DOL, 6) AS Leave_Date,
CAST((SELECT
(ISNULL(SUM(RO.RO_SHIFT_LENGTH - RO_BREAK_LENGTH), 0.0)/60.0)
FROM
RoleCall.dbo.ROSTER AS RO WITH(NOLOCK)
WHERE
RO.RO_OFFICER = [OF].OF_PIN
AND RO.RO_SHIFT_START BETWEEN #WeekCommencing AND #WeekEnding
AND RO.RO_STATUS IN ('COMP', 'CONF', 'TODO')
) AS DECIMAL(11,2)) AS HoursSum,
RSWH.dbo.RSWHF_GetMarker([OF].OF_PIN, #WeekCommencing, #WeekEnding) AS Marker,
CONVERT(VARCHAR(10), (SELECT MAX(RO.RO_SHIFT_START)
FROM RoleCall.dbo.ROSTER AS RO WITH(NOLOCK)
WHERE RO.RO_OFFICER = [OF].OF_PIN
AND RO.RO_SHIFT_START < GETDATE()
AND RO.RO_STATUS IN ('COMP', 'CONF', 'TODO')
), 6) AS Last_Worked_Shift,
CONVERT(VARCHAR(10), (SELECT TOP 1
HC.Effective_Date
FROM HR.dbo.HRST_Contract AS HC WITH(NOLOCK)
WHERE
HC.Of_Pin = [OF].OF_PIN
AND HC.SD_Contract = 1
ORDER BY
Effective_Date DESC
), 6) AS Contract_Sent_Date,
CONVERT(VARCHAR(10),
(
SELECT TOP 1
RO.RO_SHIFT_START
FROM
Rolecall.dbo.Roster AS RO WITH(NOLOCK)
WHERE
RO.RO_Activity = 'ENDASSIG'
AND RO.RO_STATUS <> 'CANC'
AND RO.RO_OFFICER =[OF].OF_PIN
AND RO.RO_SHIFT_START < #WeekEnding
ORDER BY
RO.RO_SHIFT_START DESC
), 6) AS Ass_End_Date,
ISNULL(CreatedBy, '') AS Checked_By,
---ISSUE IS OCCURRING HERE----
(
SELECT
SUM(a.[Value*NumofActivity]) + max(b.NumOfHoursWorkedInTheLast12Weeks) AS [TotalHoursWorkedInTheLast12Weeks],Markers
FROM
(
SELECT
RO_OFFICER [RO_OFFICER],RO_ACTIVITY , COUNT(RO_ACTIVITY)*Value as [Value*NumofActivity]
FROM
RoleCall.dbo.ROSTER as ro inner join [RSWH].DBO.[RSWHT_Hours_Assigned_To_Markers_LookUp] AS MR on RO_ACTIVITY = MR.MARKER
WHERE
ro_officer = [OF].OF_PIN
AND RO_STATUS = 'INFO'
AND RO_SHIFT_START between DATEADD(week, -12, GETDATE()) AND GETDATE()
GROUP BY
RO_OFFICER,RO_ACTIVITY,Value) a
JOIN
(
SELECT
RO_OFFICER [RO_OFFICER] ,(ISNULL(SUM(RO_SHIFT_LENGTH - RO_BREAK_LENGTH), 0.0)/60.0)as [NumOfHoursWorkedInTheLast12Weeks],RSWH.dbo.RSWHF_GetMarker(RO_OFFICER, DATEADD(week, -12, GETDATE()), GETDATE()) AS Markers
FROM
ROLECALL.DBO.ROSTER as ro inner join [RSWH].DBO.[RSWHT_Hours_Assigned_To_Markers_LookUp] AS MR on RO_ACTIVITY = MR.MARKER
WHERE
RO_SHIFT_START >= DATEADD(week, -12, GETDATE()) AND RO_SHIFT_START <= GETDATE()
AND RO.RO_STATUS = 'INFO'
AND RO_OFFICER = [OF].OF_PIN
GROUP BY
RO_OFFICER
) b on a.RO_OFFICER = b.RO_OFFICER
GROUP BY A.RO_OFFICER,b.NumOfHoursWorkedInTheLast12Weeks,Markers)
FROM
RoleCall.dbo.OFFICER AS [OF] WITH (NOLOCK)
LEFT JOIN RoleCall.dbo.TEMPLATE AS [TO] WITH (NOLOCK) ON [TO].TO_PIN = [OF].OF_PIN AND [TO].TO_TYPE COLLATE Latin1_General_CS_AS = 'M'
LEFT JOIN RoleCall.dbo.ACTIVITY AS AC WITH (NOLOCK) ON AC.AC_PIN = [TO].TO_ACTIVITY
LEFT JOIN RoleCall.dbo.ZONE AS ZN WITH (NOLOCK) ON ZN.ZN_ZONE = AC.AC_ZONE
LEFT JOIN RoleCall.dbo.AREA AS AR WITH (NOLOCK) ON AR.AR_AREA = AC.AC_AREA
LEFT JOIN Appollo.ACMS.dbo.ACSMT_Checked_Officer AS CO WITH (NOLOCK) ON CO.OfficerPin = [OF].OF_PIN AND WeekCommencing BETWEEN #WeekCommencing AND #WeekEnding
WHERE
[OF].OF_PAYROLL_NO IN ('W', 'S')
AND [OF].OF_SKILLS = #Of_Skills --
AND (#Of_Skills = 'R' OR AC.AC_PARENT IN ('9947', '9133'))
AND ([OF].OF_DOL IS NULL OR [OF].OF_DOL > #WeekCommencing)
AND [OF].OF_RANK <> 'PT'
AND [OF].OF_RANK <> 'LW'
AND EXISTS (
SELECT
TOP 1 Of_Pin
FROM
HR.dbo.HRST_Contract AS HC WITH(NOLOCK)
WHERE
Of_Pin = [OF].OF_PIN
AND ISNULL(SD_Contract, 0) = 1
)
AND (
SELECT
ISNULL(SUM(RO.RO_SHIFT_LENGTH - RO_BREAK_LENGTH), 0.0)
FROM
RoleCall.dbo.ROSTER AS RO WITH(NOLOCK)
WHERE
RO.RO_OFFICER = [OF].OF_PIN
AND RO.RO_SHIFT_START BETWEEN #WeekCommencing AND #WeekEnding
AND (RO.RO_STATUS IN ('COMP', 'CONF', 'TODO') OR (RO_Activity ='LEAVE' AND RO_STATUS <> 'CANC'))
) < 420.0
AND (ISNULL(CreatedBy, '') = '' OR #UncheckedOfficersOnly = 0)
ORDER BY
Officer_Name,
Officer_Pin
The issue is I need to return the three columns which I'm trying to sum. I haven't got much experience in SQL and I was wondering if anyone has any suggestions or pointers for this to be done.
Thank you

Group data by month

I want to group by results of sales by YEAR-MONTH. My current query which does the results looks like :
SELECT Cast(Year(s.datekey) AS VARCHAR(4)) + '-'
+ Cast(Month(s.datekey) AS VARCHAR(2)) AS Mjesec,
e.employeekey,
Sum(s.totalcost) AS SalesAmount
FROM factsales s
INNER JOIN dimstore st
ON s.storekey = st.storekey
INNER JOIN dimemployee e
ON e.employeekey = st.storemanager
WHERE s.datekey BETWEEN '2007-01-01' AND '2007-01-05'
GROUP BY e.employeekey,
Cast(Year(s.datekey) AS VARCHAR(4)) + '-'
+ Cast(Month(s.datekey) AS VARCHAR(2))
ORDER BY employeekey
I am wondering if there are any other better and more elegant way to achieve same results? Perhaps, more friendly format for DateTime in c#?
Much more efficient to strip time by using date math than converting to a string. Also much more efficient to leave the particular string formatting to the end (or better yet, doing it in C# using Format()).
;WITH c AS
(
SELECT m = DATEADD(MONTH, DATEDIFF(MONTH, 0, s.datekey), 0),
e.employeekey, s.totalcost
FROM dbo.factsales AS s
INNER JOIN dbo.dimstore AS st
ON s.storekey = st.storekey
INNER JOIN dimemployee AS e
ON e.employeekey = st.storemanager
WHERE s.datekey >= '20070101' AND s.datekey < '20070106'
),
d AS
(
SELECT m, employeekey, SalesAmount = SUM(totalcost)
FROM c
GROUP BY m, employeekey
)
SELECT
Mjesec = CONVERT(CHAR(7), m, 120),
employeekey,
SalesAmount
FROM d
ORDER BY employeekey;
If you can do the formatting in your app, then you can collapse this to:
;WITH c AS
(
SELECT m = DATEADD(MONTH, DATEDIFF(MONTH, 0, s.datekey), 0),
e.employeekey, s.totalcost
FROM dbo.factsales AS s
INNER JOIN dbo.dimstore AS st
ON s.storekey = st.storekey
INNER JOIN dimemployee AS e
ON e.employeekey = st.storemanager
WHERE s.datekey >= '20070101' AND s.datekey < '20070106'
)
SELECT Mjesec = m, employeekey, SalesAmount = SUM(totalcost)
FROM c
GROUP BY m, employeekey
ORDER BY employeekey;
Or even:
SELECT Mjesec = DATEADD(MONTH, DATEDIFF(MONTH, 0, s.datekey), 0),
e.employeekey, s.totalcost
FROM dbo.factsales AS s
INNER JOIN dbo.dimstore AS st
ON s.storekey = st.storekey
INNER JOIN dimemployee AS e
ON e.employeekey = st.storemanager
WHERE s.datekey >= '20070101' AND s.datekey < '20070106'
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, s.datekey, 0), 0), e.employeekey
ORDER BY employeekey;
Do:
SELECT CONVERT(CHAR(7),s.DateKey,120) AS Mjesec....
FROM ....
GROUP BY CONVERT(CHAR(7),s.DateKey,120)....
ORDER BY EmployeeKey

Get the error: The correlation name 'General' is specified multiple times in a FROM clause

ALTER PROCEDURE [dbo].[REPORTING_MonthlyClientTimesheet_wrapper2_TRR_Month]
(#StartDate DATETIME,
#taskcode VARCHAR(250),
#username VARCHAR(250))
AS
BEGIN
SET NOCOUNT ON
DECLARE #ProcedureName SYSNAME
-- Give them one full month of records
DECLARE #EndDate DATETIME
SET #ProcedureName = OBJECT_NAME(##PROCID)
--SET #EndDate = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#StartDate)+1,0)) -- end month
SET #EndDate = DATEADD(s, -1, DATEADD(YY, DATEDIFF(YYYY, 0, #StartDate) + 1, 0)) --set to end of Year
BEGIN TRY
SELECT DISTINCT
#username,
cal.calendaryear,
cal.calendarmonth,
cal.calendarday,
DATEPART(wk, Calendardate) AS weekno,
DATENAME(month, DATEADD(month, cal.calendarmonth - 1, 0)) AS iMonthName,
DATEADD(s, -1, DATEADD(YY, DATEDIFF(YYYY, 0, #StartDate) + 1, 0)) AS enddated,
LEFT(cal.dayofweekname, 2) AS Weekday,
-- Taskcode,
CASE WHEN Duration IS NULL THEN 0
ELSE duration
END AS hours,
CASE WHEN leave.leave IS NULL THEN 0
ELSE leave.leave
END AS leave,
CASE WHEN TOIL.toil IS NULL THEN 0
ELSE TOIL.toil
END AS toil,
CASE WHEN sick.sick IS NULL THEN 0
ELSE sick.sick
END AS sick,
CASE WHEN General.General IS NULL THEN 0
ELSE General.General
END AS General,
CONVERT(VARCHAR(10), Calendardate, 103) AS Calendardate
FROM
(SELECT
UserInfo.ID AS UserID,
dbo.UserInfo.FirstName,
tse.Id AS TimesheetentryID,
tse.EntryDate,
Duration,
TaskCode,
TaskId,
tts.Id AS tasktimesheetid,
YEAR(entrydate) AS EntryYear,
MONTH(entrydate) AS EntryMOnth,
DAY(entrydate) AS Entryday
FROM
TimesheetEntry tse
INNER JOIN TaskTimesheet tts ON tse.TaskTimesheetId = tts.Id
INNER JOIN dbo.Task WITH (NOLOCK) ON dbo.task.Id = TTS.TaskId
INNER JOIN dbo.ReportPeriod WITH (NOLOCK) ON TTS.ReportPeriodId = dbo.ReportPeriod.Id
INNER JOIN dbo.Login WITH (NOLOCK) ON dbo.ReportPeriod.UserId = dbo.Login.UserId
INNER JOIN dbo.UserInfo WITH (NOLOCK) ON dbo.ReportPeriod.UserId = dbo.UserInfo.Id
INNER JOIN dbo.[Login] logdet WITH (NOLOCK) ON logdet.Userid = UserInfo.Id
WHERE
Task.TaskCode = #taskcode
AND 'a\' + login.LoginName = #username) TimeSE
RIGHT JOIN dbo.TestCalendar cal ON cal.CalendarYear = Entryyear
AND cal.CalendarMonth = entrymonth
AND cal.CalendarDay = entryday
LEFT JOIN (SELECT --UserInfo.ID as UserID,
-- dbo.UserInfo.FirstName,
-- tse.Id as TimesheetentryID,
tse.EntryDate,
Duration AS General
-- TaskCode,
-- TaskId,
-- tts.Id as tasktimesheetid,
-- year(entrydate) as EntryYear,
-- month(entrydate) as EntryMOnth,
-- day(entrydate) as Entryday
FROM
TimesheetEntry tse
INNER JOIN TaskTimesheet tts ON tse.TaskTimesheetId = tts.Id
INNER JOIN dbo.Task WITH (NOLOCK) ON dbo.task.Id = TTS.TaskId
INNER JOIN dbo.ReportPeriod WITH (NOLOCK) ON TTS.ReportPeriodId = dbo.ReportPeriod.Id
INNER JOIN dbo.Login WITH (NOLOCK) ON dbo.ReportPeriod.UserId = dbo.Login.UserId
INNER JOIN dbo.UserInfo WITH (NOLOCK) ON dbo.ReportPeriod.UserId = dbo.UserInfo.Id
INNER JOIN dbo.[Login] logdet WITH (NOLOCK) ON logdet.Userid = UserInfo.Id
WHERE
Task.TaskCode = #taskcode
AND 'a\' + login.LoginName = #username
AND TaskCode = 'KPJ.GENERAL') AS General ON general.EntryDate = cal.CalendarDate
LEFT JOIN (SELECT
userid,
EntryDate,
SUM(Hours) AS leave
FROM
TimeOffs Toff
INNER JOIN TimeOffCode ToffC ON toff.TimeOffCodeId = toffc.Id
INNER JOIN dbo.TimeOffEntries ToffE ON toffe.timeoffid = toff.id
WHERE
name IN ('Bank & Public Holidays', 'Annual Leave', 'authorised Absence')
AND EntryDate >= #startdate
AND EntryDate <= #enddate
AND userid = (SELECT
UserId
FROM
login
WHERE
'a\' + LoginName = #username)
GROUP BY
toff.UserId,
EntryDate) AS Leave ON leave.EntryDate = cal.calendardate
LEFT JOIN --TOIL
(SELECT
toff.userid,
EntryDate,
Hours AS TOIL
FROM
TimeOffs Toff
INNER JOIN TimeOffCode ToffC ON toff.TimeOffCodeId = toffc.Id
INNER JOIN dbo.TimeOffEntries ToffE ON toffe.timeoffid = toff.id
WHERE
name IN ('TOIL')
AND EntryDate >= #StartDate
AND EntryDate <= #enddate
AND userid = (SELECT
UserId
FROM
Login
WHERE
'a\' + LoginName = #username)) AS TOIL ON TOIL.EntryDate = cal.calendardate
LEFT JOIN --SICK
(SELECT
toff.userid,
EntryDate,
Hours AS SICK
FROM
TimeOffs Toff
INNER JOIN TimeOffCode ToffC ON toff.TimeOffCodeId = toffc.Id
INNER JOIN dbo.TimeOffEntries ToffE ON toffe.timeoffid = toff.id
WHERE
name IN ('SICK')
AND EntryDate >= #startdate
AND EntryDate <= #enddate
AND userid = (SELECT
UserId
FROM
login
WHERE
'a\' + LoginName = #username)) AS SICK ON SICK.EntryDate = cal.calendardate
LEFT JOIN --SICK
(SELECT
toff.userid,
EntryDate,
Hours AS SICK
FROM
TimeOffs Toff
INNER JOIN TimeOffCode ToffC ON toff.TimeOffCodeId = toffc.Id
INNER JOIN dbo.TimeOffEntries ToffE ON toffe.timeoffid = toff.id
WHERE
name IN ('SICK')
AND EntryDate >= #startdate
AND EntryDate <= #enddate
AND userid = (SELECT
UserId
FROM
login
WHERE
'a\' + LoginName = #username)) AS General ON SICK.EntryDate = cal.calendardate
WHERE
cal.Calendardate >= #startdate
AND Cal.calendardate <= DATEADD(s, -1, DATEADD(YY, DATEDIFF(YYYY, 0, #startdate) + 1, 0))
ORDER BY
cal.CalendarMonth
END TRY
BEGIN CATCH
SELECT
#ProcedureName AS StoredProcName,
ERROR_NUMBER() AS ErrorNumber ;
RETURN(-1)
END CATCH
RETURN(0)
END
You have two sub-queries. Both aliases to the name General. You need to change the name of one of them, or delete one of them (The second one has a JOIN condition that doesn't relate to the sub-query, so it might be pasted in by mistake?)...
This should make it easier to see.
from
(A sub-query) TimeSE
right join
dbo.TestCalendar cal
on cal.CalendarYear =Entryyear
and cal.CalendarMonth = entrymonth
and cal.CalendarDay = entryday
LEFT JOIN
(a sub-query) AS General
ON general.EntryDate=cal.CalendarDate
LEFT JOIN
(a sub-query) as Leave
on leave.EntryDate=cal.calendardate
LEFT Join
(A sub-query) as TOIL
ON TOIL.EntryDate=cal.calendardate
LEFT JOIN
(a sub-query) as SICK
ON SICK.EntryDate=cal.calendardate
LEFT JOIN
(a sub-query) as General
ON SICK.EntryDate=cal.calendardate
WHERE
cal.Calendardate >=#startdate
and Cal.calendardate <=DATEADD(s,-1,DATEADD(YY, DATEDIFF(YYYY,0,#startdate)+1,0))
order by
cal.CalendarMonth