QUERY & SUBQUERY OPTIMISATION - sql

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

Related

Order by on a nested query

Is their a way to order this by the Time column? I am not sure how to do this. The time is the schedule and I just need it to go from the morning to the evening.
Can I just nest another select statement and use that?
Thank you.
SELECT
DoseLevel,
LastName,
FirstName,
DOB,
EMPLID,
Time,
(
SELECT v.ColorCode
FROM ABCDocumentation cd1
LEFT JOIN ABCDocumentation cd2ON cd1.ABCDocumentationID = cd2.PairID
LEFT JOIN Medicine v ON v.MedicineID = cd1.MedicineID
LEFT JOIN Manufacturers mfg ON v.MFG_Seq = mfg.MFG_Seq
WHERE cd2.ABCDocumentationID = dt.ABCDocumentationID
) AS ParentColorCode,
(
SELECT mfg.Description
FROM ABCDocumentation cd1
LEFT JOIN ABCDocumentation cd2 ON cd1.ABCDocumentationID = cd2.PairID
LEFT JOIN Medicine v ON v.MedicineID = cd1.MedicineID
LEFT JOIN Manufacturers mfg ON v.MFG_Seq = mfg.MFG_Seq
WHERE cd2.ABCDocumentationID = dt.ABCDocumentationID
) AS ParentManuDesc
FROM
(
SELECT
cd.DoseLevel,
e.LastName,
e.FirstName,
e.DOB,
cvse.EMPLID,
cvse.AdminScheduleSlotsEmployeeID,
cd.ABCDocumentationID,
cvss.Time,
cd.ModifyDate AS 'StartTime'
FROM ABCAdminSchedule cvs
LEFT JOIN ABCAdminScheduleSlots cvss ON cvs.AdminScheduleID = cvss.AdminScheduleID
LEFT JOIN ABCAdminScheduleSlotsEmployee cvse ON cvss.AdminScheduleSlotsID = cvse.AdminScheduleSlotsID
LEFT JOIN ABCDocumentation cd ON cvse.AdminScheduleSlotsEmployeeID = cd.AdminScheduleSlotsEmployeeID
LEFT JOIN Employee e ON cvse.EmplID = e.EMPLID
WHERE CAST(TIME AS Date) = CAST(GETDATE() AS Date) AND CampusID = '06'
AND cvse.AdminScheduleSlotsEmployeeID IS NOT NULL
) dt
First off, there is no need for the derived table dt, as you are not doing any further processing.
Secondly, you can combine the two correlated subqueries into one with an APPLY.
Thirdly, conversions on columns can cause performance issues, so you can change the date check to a half-open interval, converting just GETDATE().
Finally you can add at the end an ORDER BY clause to sort.
SELECT
cd.DoseLevel,
e.LastName,
e.FirstName,
e.DOB,
cvse.EMPLID,
cvss.Time,
Parent.ColorCode,
Parent.Description
FROM ABCAdminSchedule cvs
LEFT JOIN ABCAdminScheduleSlots cvss ON cvs.AdminScheduleID = cvss.AdminScheduleID
LEFT JOIN ABCAdminScheduleSlotsEmployee cvse ON cvss.AdminScheduleSlotsID = cvse.AdminScheduleSlotsID
LEFT JOIN ABCDocumentation cd ON cvse.AdminScheduleSlotsEmployeeID = cd.AdminScheduleSlotsEmployeeID
LEFT JOIN Employee e ON cvse.EmplID = e.EMPLID
OUTER APPLY
(
SELECT v.ColorCode, mfg.Description
FROM ABCDocumentation cd1
LEFT JOIN ABCDocumentation cd2ON cd1.ABCDocumentationID = cd2.PairID
LEFT JOIN Medicine v ON v.MedicineID = cd1.MedicineID
LEFT JOIN Manufacturers mfg ON v.MFG_Seq = mfg.MFG_Seq
WHERE cd2.ABCDocumentationID = dt.ABCDocumentationID
) AS Parent
WHERE TIME >= CAST(GETDATE() AS Date) AND TIME < CAST(DATEADD(day, 1, GETDATE()) AS DATE)
AND CampusID = '06'
AND cvse.AdminScheduleSlotsEmployeeID IS NOT NULL
ORDER BY TIME
please
declare #tm table (id int identity, timee time(7))
insert into #tm (timee) values ('01:05:45'),
('10:15:18'),
('14:18:59'),
('09:15:10'),
('18:19:21'),
('21:05:17')
this is a default
select * from #tm order by id
this is a, what do you need
select tm.*,
iif(tm.part_time = 1, 'morning', 'evening') m_e from (select
case
when timee between '09:00:00' and '19:00:00' then 1
else 2 end part_time,
*
from #tm) tm
order by part_time, timee

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

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

Adding columns from different tables in SQL Server within a stored procedure

I am writing this stored procedure to get details from 4 differnt tables using join and simple logic, but while acculmulating it all in the end using UNION os not working as I am getting the error : expecting AS,ID or quoted_id, please suggest what am I doing wrong in this.
ALTER PROCEDURE [dbo].[cp_RejectionAnalysis]
(#RunDate DATE --'20150501')
AS
BEGIN
SET NOCOUNT ON;
--DECLARE #RunDate DATE = '20150401'
DECLARE #StartDate DATE = DATEADD(DD, -30, #RunDate);
DECLARE #GeRejectionDate AS TABLE (PayerName VARCHAR(120),
ClaimCount INT);
WITH rejections AS
(
SELECT
i.Number,
COUNT(DISTINCT CASE WHEN far.SubmissionDate < #RunDate THEN far.ClaimKey ELSE NULL END) AS TotalRejectsFirst30,
COUNT(DISTINCT CASE WHEN far.SubmissionDate = #RunDate THEN far.ClaimKey ELSE NULL END) AS TotalRejectsRunDate
FROM
table1 far
INNER JOIN
table2 i ON far.InsurerInfoKey = i.InsurerKey
WHERE
far.isRejection = 1
AND (far.MessageDate >= #StartDate AND far.MessageDate <= #RunDate)
GROUP BY
i.Number),
totalclaims AS
(
SELECT
i.Number,
SUM(CASE WHEN ts.SubmissionDate < #RunDate THEN ts.TotalClaims ELSE 0 END) AS TotalClaimsFirst30,
SUM(CASE WHEN ts.SubmissionDate = #RunDate THEN ts.TotalClaims ELSE 0 END) AS TotalClaimsRunDate
FROM
table3 ts
INNER JOIN
table2 i ON ts.InsurerInfoKey = i.InsurerKey
WHERE
ts.SubmissionDate >= #StartDate
AND ts.SubmissionDate <= #RunDate
GROUP BY
i.Number
--ORDER BY i.Number
)
/*, PaymentRejectionDetails AS (
(SELECT DISTINCT ra.Message AS ErrorMessage, ra.ErrorListKey AS ErrorListKey
FROM dimErrorListRejectionAnalysis ra
INNER JOIN table1 far on ra.ErrorListKey= far.ErrorListKey
WHERE (far.MessageDate >= #StartDate AND far.MessageDate <= #RunDate))
UNION
(SELECT DISTINCT QcHistClaimId AS ClaimId FROM table1 far
WHERE (far.MessageDate >= #StartDate AND far.MessageDate <= #RunDate))
UNION
(SELECT DISTINCT SITEID FROM table4 ds
INNER JOIN table1 far ON ds.sitekey=far.sitekey
WHERE (far.MessageDate >= #StartDate AND far.MessageDate <= #RunDate))
)*/
, ClaimsID AS
(
SELECT DISTINCT ClaimId
FROM table1 far
WHERE (far.MessageDate >= #StartDate AND far.MessageDate <= #RunDate))
, SiteId AS
(
SELECT DISTINCT SITEID
FROM table4 ds
INNER JOIN table1 far ON ds.sitekey = far.sitekey
WHERE (far.MessageDate >= #StartDate AND far.MessageDate <= #RunDate))
SELECT *
INTO D
FROM
(SELECT ClaimId FROM ClaimsID
UNION
SELECT SITEID FROM SiteId
UNION
SELECT
r.PayerNumber, r.TotalRejectsFirst30,
r.TotalRejectsRunDate,
ISNULL(t.TotalClaimsFirst30, 0) AS ClaimsFirst30,
ISNULL(t.TotalClaimsRunDate, 0) AS ClaimsRunDate
FROM
rejections r
LEFT OUTER JOIN
totalclaims t ON t.PayerNumber = r.PayerNumber)
END
Invalid use of UNION here
SELECT ClaimId FROM ClaimsID
UNION
SELECT SITEID FROM SiteId
UNION
SELECT r.PayerNumber, r.TotalRejectsFirst30, r.TotalRejectsRunDate, ISNULL(t.TotalClaimsFirst30, 0) AS ClaimsFirst30, ISNULL(t.TotalClaimsRunDate, 0) AS ClaimsRunDate
FROM rejections r
First you need to understand the scenario of UNION
Combines the results of two or more queries into a single result set
that includes all the rows that belong to all queries in the union.
The UNION operation is different from using joins that combine columns
from two tables.
The following are basic rules for combining the result sets of two queries by using UNION:
The number and the order of the columns must be the same in all queries.
The data types must be compatible.
EDIT 2:
i'm not sure what you really want, and you didn't response to my comment.
but my guess you can try using LEFT JOIN
SELECT
r.PayerNumber,
r.TotalRejectsFirst30,
r.TotalRejectsRunDate,
ISNULL(t.TotalClaimsFirst30, 0) AS ClaimsFirst30,
ISNULL(t.TotalClaimsRunDate, 0) AS ClaimsRunDate,
c.ClaimId as ClaimId
FROM rejections r LEFT JOIN ClaimsID c On r.ClaimId=c.ClaimId
Please remove the asterisks around the last block and add an alias for the sub query.
*SELECT * INTO D FROM
(
SELECT ClaimId FROM ClaimsID UNION SELECT SITEID FROM SiteId
UNION
SELECT r.PayerNumber, r.TotalRejectsFirst30, r.TotalRejectsRunDate, ISNULL(t.TotalClaimsFirst30, 0) AS ClaimsFirst30, ISNULL(t.TotalClaimsRunDate, 0) AS ClaimsRunDate
FROM rejections r
LEFT OUTER JOIN totalclaims t ON t.PayerNumber = r.PayerNumber)*
You can't union rows with number/type of fields. What is the end result you expect from this whole procedure? By the way, posting the create scripts for the tables would help answer the question.

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.