How to combine two select query results into one result using sp? - sql

I'm declaring two comparison dates, I want data from both dates. I'm using left join for combined propose but this is not correct way. I'm missing some data. Instead of left join which one is best for?
result
productid FirstQty SecondQty FirstProductRevenue SecondProductRevenue
COCAK117 1 2 1370.00 1440.00
COCAK632 1 2 1125.00 2250.00
COCAK656 1 NULL 795.00 NULL
COCAK657 1 2 720.00 2090.00
COCAK775 3 1 2475.00 825.00
I'm getting data from full of first table and matching productid from second table, but I want total productid's from both the tables.
CREATE PROCEDURE [dbo].[Orders]
(
#StartDate DATETIME,
#EndDate DATETIME,
#StartDate1 DATETIME,
#EndDate1 DATETIME,
#Rowname VARCHAR(100),
#AssociateName VARCHAR(50)
)
--[Orders] '05/03/2015','05/03/2015','05/05/2015','05/07/2015','Most Gifted Cakes','all'
AS BEGIN
if(#AssociateName='all')
BEGIN
----First duration for all associates-----
select t1.productid,t1.FirstQty,t2.SecondQty,t1.FirstProductRevenue,t2.SecondProductRevenue
from
(select op.Productid
, count(op.ProductId)as FirstQty
, Round(Sum(op.Price*op.Quantity),0) as FirstProductRevenue
from Orderdetails od
inner join (select Distinct Orderid,productid,Price,Quantity from Orderproducts) op on op.Orderid=od.Orderid
inner JOIN City ct ON od.RecipientCityName = ct.CityName
INNER JOIN Associates ass ON Ct.AssociateId = ass.AssociateId
Inner join HomepageRowWiseProducts hr on op.ProductId=hr.Productid
where Convert(datetime,Convert(Varchar(50),od.DeliveryDate,101)) between #StartDate and #EndDate
and (od.TransactionId IS NOT NULL or ltrim(od.TransactionId) != '')
and #Rowname=hr.HomepageRow_name and hr.status=1
Group by op.Productid
) t1
----Second duration for all associates-----
left join
(select op.Productid
, count(op.ProductId)as SecondQty
, Round(Sum(op.Price*op.Quantity),0) as SecondProductRevenue
from Orderdetails od
inner join (select Distinct Orderid,productid,Price,Quantity from Orderproducts) op on op.Orderid=od.Orderid
inner JOIN City ct ON od.RecipientCityName = ct.CityName
INNER JOIN Associates ass ON Ct.AssociateId = ass.AssociateId
Inner join HomepageRowWiseProducts hr on op.ProductId=hr.Productid
where Convert(datetime,Convert(Varchar(50),od.DeliveryDate,101)) between #StartDate1 and #EndDate1
and (od.TransactionId IS NOT NULL or ltrim(od.TransactionId) != '')
and #Rowname=hr.HomepageRow_name and hr.status=1
Group by op.Productid
) t2 on t1.productid=t2.productid
END

You can try to get all data at once and then sum only date ranges that you want.
I could made some mistake here as I don't have your data structures.
However you should get the idea how you can implement it.
select op.Productid
, sum( case when Convert(datetime,Convert(Varchar(50),od.DeliveryDate,101)) between #StartDate and #EndDate then
1 else 0 end) FirstQty
, sum( case when Convert(datetime,Convert(Varchar(50),od.DeliveryDate,101)) between #StartDate1 and #EndDate1 then
1 else 0 end) SecondQty,
, Round(Sum( case when Convert(datetime,Convert(Varchar(50),od.DeliveryDate,101)) between #StartDate and #EndDate
then op.Price*op.Quantity
else 0 end),0) as FirstProductRevenue
, Round(Sum( case when Convert(datetime,Convert(Varchar(50),od.DeliveryDate,101)) between #StartDate1 and #EndDate1
then op.Price*op.Quantity
else 0 end),0) as SecondProductRevenue
from Orderdetails od
inner join (select Distinct Orderid,productid,Price,Quantity from Orderproducts) op on op.Orderid=od.Orderid
inner JOIN City ct ON od.RecipientCityName = ct.CityName
INNER JOIN Associates ass ON Ct.AssociateId = ass.AssociateId
Inner join HomepageRowWiseProducts hr on op.ProductId=hr.Productid
where ( Convert(datetime,Convert(Varchar(50),od.DeliveryDate,101)) between #StartDate and #EndDate
Or Convert(datetime,Convert(Varchar(50),od.DeliveryDate,101)) between #StartDate1 and #EndDate1 )
and (od.TransactionId IS NOT NULL or ltrim(od.TransactionId) != '')
and #Rowname=hr.HomepageRow_name and hr.status=1
Group by op.Productid

Maybe this (simplified):
select coalesce(t1.productid, t2.productid) as productid, t1.FirstQty, t2.SecondQty, t1.FirstProductRevenue, t2.SecondProductRevenue
from
(select ...) t1
----Second duration for all associates-----
full join
(select ...) t2 on t1.productid = t2.productid

try this
you create a function as follows
CREATE FUNCTION OrderDetails (
#StartDate DATETIME,
#EndDate DATETIME
)
RETURNS #tblList TABLE
(
orderId VARCHAR(1000)
)
AS
BEGIN
select orderid
insert into #tblList
from Orderdetails od inner JOIN City ct ON od.RecipientCityName = ct.CityName
INNER JOIN Associates ass ON Ct.AssociateId = ass.AssociateId
Inner join HomepageRowWiseProducts hr on op.ProductId=hr.Productid
and (od.TransactionId IS NOT NULL or ltrim(od.TransactionId) != '')
and #Rowname=hr.HomepageRow_name and hr.status=1
where Convert(datetime,Convert(Varchar(50),od.DeliveryDate,101)) between #StartDate and #EndDate
return
end
then call the function in your stored procedure according to the date you are passing you don't miss any records
CREATE PROCEDURE [dbo].[Orders]
(
#StartDate DATETIME,
#EndDate DATETIME,
#StartDate1 DATETIME,
#EndDate1 DATETIME,
#Rowname VARCHAR(100),
#AssociateName VARCHAR(50)
)
--[Orders] '05/03/2015','05/03/2015','05/05/2015','05/07/2015','Most Gifted Cakes','all'
AS BEGIN
if(#AssociateName='all')
BEGIN
----First duration for all associates-----
select op1.Productid
, count(op.ProductId)as FirstQty
,count(op1.ProductId)as SecondQty
, Round(Sum(op.Price*op.Quantity),0) as FirstProductRevenue
, Round(Sum(op1.Price*op1.Quantity),0) as FirstProductRevenue
from (select Distinct Orderid,productid,Price,Quantity from Orderproducts opp inner join [Your_ScemaName].[OrderDetails](#StartDate,#EndDate) od on opp.Orderid=od.Orderid ) op
inner join (select Distinct Orderid,productid,Price,Quantity from Orderproducts opp inner join [Your_ScemaName].[OrderDetails](#StartDate1,#EndDate1) od on opp.Orderid=od.Orderid ) op1
-- since 1=1 is always true you will get all data
on 1=1
Group by op.Productid
end
end

Related

QUERY & SUBQUERY OPTIMISATION

I've this query. the problem is that it takes like 5min or more to be excecuted.
I'm using a subquery to bring me only values >200
ALTER PROCEDURE [dbo].[RATIO] #DATED nvarchar(30),#DATEF nvarchar(30), #REG nvarchar(30)
SELECT
[REGION] = ET_REGION,
[MAGASIN] = ET2.ET_LIBELLE ,
(SELECT
COUNT(DISTINCT GL_NUMERO)
FROM GCLIGNEARTDIM
LEFT OUTER JOIN ETABLISS ET4 ON GL_ETABLISSEMENT=ET4.ET_ETABLISSEMENT
WHERE
CAST(GL_DATEPIECE AS DATE) BETWEEN CAST(#DATED AS DATE) AND CAST(#DATEF AS DATE)
AND ET4.ET_LIBELLE = ET2.ET_LIBELLE
AND GP_TOTALTTC < 200
)'S : <200'
FROM GCLIGNEARTDIM
LEFT OUTER JOIN ETABLISS ET2 ON GL_ETABLISSEMENT=ET2.ET_ETABLISSEMENT
WHERE
CAST(GL_DATEPIECE AS DATE) BETWEEN CAST(#DATED AS DATE) AND CAST(#DATEF AS DATE)
GROUP BY
ET_REGION,
ET2.ET_LIBELLE
It's tough doing this without the underlying data but from what I can read of what you're doing then something like this might do it for you;
ALTER PROCEDURE [dbo].[RATIO] #DATED nvarchar(30),#DATEF nvarchar(30), #REG nvarchar(30)
AS
DECLARE #DATED_Date DATE = #DATED;
DECLARE #DATEF_Date DATE = #DATEF;
SELECT
[REGION] = ET_REGION,
[MAGASIN] = ET2.ET_LIBELLE ,
COUNT(DISTINCT CASE WHEN GP_TOTALTTC < 200 THEN GL_NUMERO END) AS 'S : <200'
FROM GCLIGNEARTDIM
LEFT OUTER JOIN ETABLISS ET2 ON GL_ETABLISSEMENT=ET2.ET_ETABLISSEMENT
WHERE CAST(GL_DATEPIECE AS DATE) BETWEEN #DATED_Date AND #DATEF_Date
GROUP BY ET_REGION, ET2.ET_LIBELLE

What is an alternative to using subqueries in this SQL query that will give us better performance?

We have a Transact-SQL query that contains subqueries in the where section. Inner Join gives unwanted results of adding tOrderDetails fields multiple times so we resorted to the (poor performance) sub queries. It is timing out often. We need the same result but with better performance. Any suggestions?
SELECT sum (cast(Replace(tOrders.TotalCharges,'$','') as money)) as TotalCharges
FROM [ArtistShare].[dbo].tOrders
WHERE tOrders.isGiftCardRedemption = 0
and tOrders.isTestOrder=0
and tOrders.LastDateUpdate between #startDate and #endDate
and (SELECT count(tORderDetails.ID)
from tORderDetails
where tORderDetails.ORderID = tORders.ORderID
and tOrderDetails.isPromo=1) = 0
and (SELECT top 1 tProjects.ProjectReleaseDt
from tProjects JOIN tOrderDetails
on tOrderDetails.ProjectID = tProjects.ID
where tOrderDetails.OrderID = tOrders.OrderID) >= #startDate
Why do you count records if you just want to know if at least one exists or not exists?
SELECT Sum (Cast(Replace(tOrders.TotalCharges, '$', '') AS MONEY)) AS TotalCharges
FROM [ArtistShare].[dbo].tOrders
WHERE tOrders.isGiftCardRedemption = 0
AND tOrders.isTestOrder = 0
AND tOrders.LastDateUpdate BETWEEN #startDate AND #endDate
AND NOT EXISTS
(
SELECT 1 FROM tORderDetails
WHERE tORderDetails.ORderID = tORders.ORderID
AND tOrderDetails.isPromo = 1 )
AND EXISTS
(
SELECT 1 FROM tProjects INNER JOIN tOrderDetails
ON tOrderDetails.ProjectID = tProjects.ID
WHERE tOrderDetails.OrderID = tOrders.OrderID
AND tProjects.ProjectReleaseDt >= #startDate )
Although I think EXISTS may have the best performance, you might also consider the following approach. When you mention in your question that your query has "unwanted results of adding tOrderDetails fields multiple times" it's probably because you have multiple tOrderDetail records so you need to collapse them with a GROUP BY. Rather than using a correlated sub-query which is very inefficient, use a single sub-query with INNER JOIN like this.
SELECT
sum (cast(Replace(tOrders.TotalCharges, '$', '') as money)) as TotalCharges
FROM [ArtistShare].[dbo].tOrders
INNER JOIN (
SELECT OrderID
FROM tOrderDetails d INNER JOIN tProjects p on d.ProjectID = p.ID
WHERE d.isPromo = 0 AND p.ProjectReleaseDt > #startDate
GROUP BY OrderID
) qualifyingOrders ON qualifyingOrders.OrderID = tOrders.OrderID
WHERE tOrders.isGiftCardRedemption = 0
and tOrders.isTestOrder=0
and tOrders.LastDateUpdate between #startDate and #endDate
Again, you should compare this with the EXISTS approach to see which one performs better and makes the most sense for what you are trying to achieve.
One additional approach you could try is to put your sub-query data in to temporary tables first and then query on those.
Obviously I don't have your data or understand the data relationships exactly but hopefully the example below will get you on your way to the correct query for your needs.
Worth comparing the performance at least.
DECLARE #ORDERDETAILS TABLE
(
INT idCount,
INT orderId
)
INSERT INTO
#ORDERDETAILS
SELECT
COUNT(tORderDetails.ID),
tORderDetails.ORderID
WHERE
tOrderDetails.isPromo = 1
GROUP BY
tORderDetails.ORderID
DECLARE #PROJECTS TABLE
(
DATETIME releaseDte,
INT orderId
)
INSERT INTO
#PROJECTS
SELECT
tProjects.ProjectReleaseDt,
tOrderDetails.OrderID
FROM
tProjects JOIN tOrderDetails ON tOrderDetails.ProjectID = tProjects.ID
SELECT
sum (cast(Replace(tOrders.TotalCharges,'$','') as money)) as TotalCharges
FROM
[ArtistShare].[dbo].tOrders JOIN #ORDERDETAILS ON #ORDERDETAILS.orderId = tORders.ORderID
JOIN #PROJECTS ON #PROJECTS.orderId = tOrders.OrderID)
WHERE tOrders.isGiftCardRedemption = 0
and tOrders.isTestOrder=0
and tOrders.LastDateUpdate between #startDate and #endDate
AND #ORDERDETAILS.idCount = 0
--and (SELECT count(tORderDetails.ID)
-- from tORderDetails
-- where tORderDetails.ORderID = tORders.ORderID
-- and tOrderDetails.isPromo=1) = 0
AND #PROJECTS.releaseDte >= #startDate --NOT QUITE SURE WHAT THIS EXACTLY MIMICS WHAT YOU ARE TRYING TO DO BUT IF NOT YOU COULD REMOVE THE JOIN AND SUB-QUERY AS FOLLOWS
--AND (SELECT TOP 1 #PROJECTS.releaseDte WHERE PROJECTS.orderId = tOrders.OrderID) >= #startDate
--and (SELECT top 1 tProjects.ProjectReleaseDt
-- from tProjects JOIN tOrderDetails
-- on tOrderDetails.ProjectID = tProjects.ID
-- where tOrderDetails.OrderID = tOrders.OrderID) >= #startDate

I have two SELECTS in the same query - i need to make inner join between them

This is how my query looks:
DECLARE #month date
DECLARE #CustomerId int
DECLARE #InterfacedSystemId int
SET #month = '2013-05-01'
SET #CustomerId = 24
SET #InterfacedSystemId = 1
SELECT * FROM
(
SELECT CONVERT(BIGINT,MisparHeshbonit) AS PreProcInvoiceNumber ,CONVERT(DATE,TaarichErech,103) AS PreProcDate , ROUND(sum(convert(float,SchumBruto)),2) AS PreProcSum
FROM [VisaCalCredit] VCC
WHERE CONVERT(DATE,TaarichErech,103) BETWEEN #month AND DATEADD(DAY,-1,DATEADD(MONTH,1,#month))
AND VCC.CustomerID = #CustomerID
GROUP BY MisparHeshbonit , CONVERT(DATE,TaarichErech,103)
) AS PreTable
ORDER BY PreProcInvoiceNumber, PreProcDate
SELECT * FROM
(
SELECT InvoiceNumber AS PostProcInvoiceNumber,ActualPaymentTime AS PostProcDate ,ROUND(sum(GrossAmount),2) AS PostProcSum
FROM [CreditAndDebit] C INNER JOIN [Transaction] T ON C.TransactionID = T.ID
WHERE ActualPaymentTime BETWEEN #month AND DATEADD(DAY,-1,DATEADD(MONTH,1,#month))
AND T.CustomerID = #CustomerId
AND T.InterfacedSystemID = 1
GROUP BY InvoiceNumber , ActualPaymentTime
) AS PostTable
ORDER BY PostProcInvoiceNumber ,PostProcDate
I need to find the differences between the PreProcSum and the PostProcSum in those tables - and I cannot make inner join between the inner tables themselves (trigger other problems).
How can I make this inner join between those two tables i've defined in this query?
If your key is (InvoiceNumber, Date), I believe you can do this:
;WITH PreTable AS (
SELECT
CONVERT(BIGINT,MisparHeshbonit) AS PreProcInvoiceNumber,
CONVERT(DATE,TaarichErech,103) AS PreProcDate,
ROUND(sum(convert(float,SchumBruto)),2) AS PreProcSum
FROM [VisaCalCredit] VCC
WHERE
CONVERT(DATE,TaarichErech,103) BETWEEN #month AND DATEADD(DAY,-1,DATEADD(MONTH,1,#month))
AND VCC.CustomerID = #CustomerID
GROUP BY MisparHeshbonit, CONVERT(DATE,TaarichErech,103)
),
PostTable AS (
SELECT
InvoiceNumber AS PostProcInvoiceNumber,
ActualPaymentTime AS PostProcDate,
ROUND(sum(GrossAmount),2) AS PostProcSum
FROM [CreditAndDebit] C INNER JOIN [Transaction] T ON C.TransactionID = T.ID
WHERE ActualPaymentTime BETWEEN #month AND DATEADD(DAY,-1,DATEADD(MONTH,1,#month))
AND T.CustomerID = #CustomerId
AND T.InterfacedSystemID = 1
GROUP BY InvoiceNumber, ActualPaymentTime
),
MergedKeys AS (
SELECT
PreProcInvoiceNumber AS InvoiceNumber,
PreProcDate AS TheDate
FROM PreTable
UNION ALL
SELECT
PostProcInvoiceNumber,
PostProcDate
FROM PostTable
)
SELECT *
FROM
MergedKeys mk
LEFT JOIN PreTable prt
ON prt.PreProcInvoiceNumber = mk.InvoiceNumber
AND prt.PreProcDate= mk.TheDate
LEFT JOIN PostTable pot
ON pot.PostProcInvoiceNumber = mk.InvoiceNumber
AND pot.PostProcDate= mk.TheDate
ORDER BY
mk.InvoiceNumber,
mk.TheDate
Replace LEFT JOIN with JOIN if you are sure you will get all the invoice data in both of your selects.

Sum a column of a table based on another sum of a table

I have this code:
declare #ReportLines table
(RebateInvoiceID int,
RebateSetupID int ,
ShortItemNo float primary key(RebateInvoiceID,RebateSetupID,ShortItemNo),
TotalAmount float,
InvoiceTotal float,
TotalQuantity int )
insert #ReportLines
select
i.RebateInvoiceID
, coalesce(rs.WholesalerRebateSetupID,r.RebateSetupID)
, bl.ShortItemNo
, sum(round(r.Amount,2)) as TotalAmount
, sum(round(TotalAmount,2)) as InvoiceTotal
, sum(r.Quantity) TotalQuantity
from
#Invoices i
join RebateInvoices ri (nolock) on
ri.RebateInvoiceID=i.RebateInvoiceID
inner loop join Rebates r (nolock) on
r.RebateInvoiceID=i.RebateInvoiceID
join RebateSetup rs (nolock) on
rs.RebateSetupID=r.RebateSetupID
join BidLines bl (nolock) on
r.BidLineGuid=bl.BidLineGuid
join #Products p on
p.ShortItemNo=bl.ShortItemNo
left join ChargebackDetailHistory cd (nolock) on
r.DocumentBranchPlant = cd.DocumentBranchPlant
and r.DocumentNumber = cd.DocumentNumber
and r.DocumentType = cd.DocumentType
and r.LineNumber = cd.LineNumber
left join EDI.dbo.JDE_SaleDetail sd (nolock) on
r.DocumentBranchPlant = sd.BranchPlant
and r.DocumentNumber = sd.OrderNumber
and r.DocumentType = sd.OrderType
and r.LineNumber = sd.LineNumber
where
cd.InvoiceDate between #BeginDate and #EndDate
or sd.InvoiceDate between #BeginDate and #EndDate
group by
i.RebateInvoiceID
, coalesce(rs.WholesalerRebateSetupID,r.RebateSetupID)
, bl.ShortItemNo
I want to sum the invoice total amount column from the total amount column. When I run the above query i get a bunch of weird totals. The invoice total should be one number for each row and be consistent with the rebateinvoiceid since thats what its grouped by, correct?
You can make another Nesty query... Something Like this:
insert #ReportLines
select
RebateInvoiceID
, ID
, ShortItemNo
, TotalAmount
, sum(round(TotalAmount,2)) as InvoiceTotal
, TotalQuantity
from
(
select
i.RebateInvoiceID
, coalesce(rs.WholesalerRebateSetupID,r.RebateSetupID) as ID
, bl.ShortItemNo
, sum(round(r.Amount,2)) as TotalAmount
, sum(r.Quantity) TotalQuantity
from (... <the rest of your code here> ...)
) As MyTable
group by
RebateInvoiceID, ID, ShortItemNo, TotalAmount, TotalQuantity

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