Understanding nested select queries - sql

Have a question in regards to what was a select into query that I am changing into an insert into query with a select and I just wanted somebody to help me understand the query and know why the only fields in the select it wants are only certain fields.
Ok so below is a create table statement I have written for the temp tables '#Infants' and '#MobileBookings'.
create table #MobileBookings
(
Reference nvarchar(50),
CreatedDate datetime,
FirstName nvarchar(50),
Surname nvarchar(50),
PersonTypeId int,
PackageId int,
PersonId int,
ProductId int,
StatusId smallint
)
create table #Infants
(
Reference nvarchar(50),
CreatedDate datetime,
FirstName nvarchar(50),
Surname nvarchar(50),
PersonTypeId int,
ProductPersonId int,
StatusId smallint,
FlightNumber nvarchar(50),
DepartureDateTime datetime,
SectorName nvarchar(50),
BoundID varchar(8)
)
Now what I have in the existing code (that I didn't write but trying to manipulate by including insert into instead of what previously was select into to remove certain warnings.
insert into #Infants (
Reference, CreatedDate, FirstName, Surname,
PersonTypeId, ProductPersonId, StatusId, FlightNumber,
DepartureDateTime, SectorName, BoundID
)
select * from
(
select
x.Reference, x.CreatedDate, x.FirstName, x.Surname,
x.PersonTypeId, pp.ProductPersonId, pp.StatusId as 'ProductPersonStatusID', null as 'DependantPPID',
fl.FlightNumber,
fl.DepartureDateTime, fs.SectorName, iif(fr.BoundID=0,'OutBound','InBound') as 'FlightBound'
from #MobileBookings as x
inner join Reservations_Live.dbo.ProductPerson as pp with (nolock) on pp.ProductID = x.ProductId and pp.PersonId = x.PersonId
inner join Reservations_Live.dbo.FlightReservation as fr with (nolock) on fr.ProductId = x.ProductId
inner join Reservations_Live.dbo.Flight as fl with (nolock) on fl.FlightId = fr.FlightId
inner join Reservations_Live.dbo.FlightSector as fs with (nolock) on fs.FlightSectorId = fl.FlightSectorId
INNER join
(
select x.PackageId as 'PKID', frp.DependantProductPersonId as 'DepPPID', frp.ProductPersonID as 'CarerPPID',
pp.StatusId as 'CarerPPST'
from #MobileBookings as x
inner join Reservations_Live.dbo.ProductPerson as pp with (nolock) on pp.ProductID = x.ProductId and pp.PersonId = x.PersonId
inner join Reservations_Live.dbo.FlightReservationPassenger as frp with (nolock) on frp.ProductPersonID = pp.ProductPersonId
where x.PersonTypeId = 1
and pp.StatusId = 3
and frp.DependantProductPersonId is not null
)
as car on car.PKID = x.PackageId and car.DepPPID = pp.ProductPersonId
where x.StatusId < 7
and x.PersonTypeId = 3
and pp.StatusId = 2
and fl.FlightStatusId < 3
and fl.DepartureDateTime > GETUTCDATE()
) as inf;
set #ActualRowCount = ##rowcount;
Ok so in visual studio, if I hover over the * in the select statement, it displays a hover box that shows the only fields it requires to select:
Reference (nvarchar, null),
CreatedDate (datetime, null),
FirstName (nvarchar, null),
Surname (nvarchar, null),
PersonTypeId (int, null),
ProductPersonStatusID(, null),
DependantPPID(void, not null),
FlightBound (, null)
I'm assuming I need to change my create table and insert into to only include these relevant fields above but what I want to know is how come it only wants to select these fields and not include any other relevant fields?
Also in regards to the ProductPersonStatusID and DependantPPID which is based on the 'StatusID', are they actually displayed as two columns in the final output, meaning the create table will need to include both these columns and they both also need to be included in the insert into? StatusId is an int so if this is the case, I'm assuming 'ProductPersonStatusID' should be set as an int but DependantPPID should be set as a null in the CREATE statement?
UPDATE:
Hopefully I'm in the right section but included the subquery for inf as stated in the comment:
update pp
set pp.StatusId = 3
output 'ProductPerson', 'ProductPersonId', inserted.ProductPersonId,
Core.updXMLFragment('StatusId',inserted.StatusId,deleted.StatusId)
into #OutputList
from Reservations_Live.dbo.ProductPerson as pp
inner join #Infants as inf on inf.ProductPersonId = pp.ProductPersonId;
set #UpdateRowCount = ##Rowcount;
Just to make sure, I have changed the create table and the insert into statement to the follow, which I hope is correct:
create table #Infants
(
Reference nvarchar(50),
CreatedDate datetime,
FirstName nvarchar(50),
Surname nvarchar(50),
PersonTypeId int,
ProductPersonStatusID int,
DependantPPID int,
FlightBound varchar(8)
);
--
insert into #Infants (Reference, CreatedDate, FirstName, Surname, PersonTypeId, ProductPersonStatusID, DependantPPID, FlightBound)
select * from...

I suggest you remove the select * altogether. This is bad practice. There is rarely a good reason to use SELECT * As it was you had a couple of fields mismatched.
Note how the order of fields in the INSERT needs to match the order of fields in the SELECT. That's why I like to spread them across a few lines so I can match them up.
Also WITH (NOLOCK) is not magic go fast switch but that's for another post....
insert into #Infants (
Reference, CreatedDate,
FirstName, Surname,
PersonTypeId, ProductPersonId,
StatusId, FlightNumber,
DepartureDateTime, SectorName,
BoundID
)
select
x.Reference, x.CreatedDate,
x.FirstName, x.Surname,
x.PersonTypeId, pp.ProductPersonId,
pp.StatusId as [ProductPersonStatusID], fl.FlightNumber,
fl.DepartureDateTime, fs.SectorName,
iif(fr.BoundID=0,'OutBound','InBound') as [FlightBound]
from #MobileBookings as x
inner join Reservations_Live.dbo.ProductPerson as pp with (nolock) on pp.ProductID = x.ProductId and pp.PersonId = x.PersonId
inner join Reservations_Live.dbo.FlightReservation as fr with (nolock) on fr.ProductId = x.ProductId
inner join Reservations_Live.dbo.Flight as fl with (nolock) on fl.FlightId = fr.FlightId
inner join Reservations_Live.dbo.FlightSector as fs with (nolock) on fs.FlightSectorId = fl.FlightSectorId
INNER join
(
select x.PackageId as 'PKID', frp.DependantProductPersonId as 'DepPPID', frp.ProductPersonID as 'CarerPPID',
pp.StatusId as 'CarerPPST'
from #MobileBookings as x
inner join Reservations_Live.dbo.ProductPerson as pp with (nolock) on pp.ProductID = x.ProductId and pp.PersonId = x.PersonId
inner join Reservations_Live.dbo.FlightReservationPassenger as frp with (nolock) on frp.ProductPersonID = pp.ProductPersonId
where x.PersonTypeId = 1
and pp.StatusId = 3
and frp.DependantProductPersonId is not null
)
as car on car.PKID = x.PackageId and car.DepPPID = pp.ProductPersonId
where x.StatusId < 7
and x.PersonTypeId = 3
and pp.StatusId = 2
and fl.FlightStatusId < 3
and fl.DepartureDateTime > GETUTCDATE()

Related

Return two relationship in one resultset

Below are the oversimplified inspired from my production schema.
Thus, I want to return all these information in one result set.
My desired result set
I have tried this query but it return wrong result.
SELECT u.*
,f.*
,uv.*
,v.*
FROM User u
LEFT JOIN UserFarm uf ON uf.UserID = u.ID
LEFT JOIN Farm f ON f.ID = uf.FarmID
LEFT JOIN FarmVehicle fv ON f.ID = fv.FarmID
LEFT JOIN UserVehicle uv ON u.ID = uv.UserID
LEFT JOIN Vehicle v ON fv.VehicleID = v.ID
WHERE u.ID = 1
Edit: This is the result from above query.
Could anyone advise me on this, I really need to return in the desired result.
You could build a query to return the data you want in the first row, and null in the columns you don't want for that row. Then create another query for the second row and use union all to combine the data together:
declare #UserVehicle table (UserID int, VehicleID int, IsService bit)
declare #User table (ID int, Name varchar(10))
declare #UserFarm table (UserID int, FarmID int)
declare #Farm table (ID int, Name varchar(10))
declare #FarmVehicle table (FarmID int, VehicleID int)
declare #Vehicle table (ID int, [Type] varchar(10), Name varchar(10))
insert into #UserVehicle values (1, 2, 1)
insert into #User values (1, 'Sam')
insert into #UserFarm values (1, 1)
insert into #Farm values (1, 'Flora')
insert into #FarmVehicle values (1, 1)
insert into #Vehicle values (1, 'Larry', 'Scania'), (2, 'Unknown', 'Civic')
select [User.ID] = u.ID
,[User.Name] = u.Name
,[Farm.ID] = f.ID
,[Farm.Name] = f.Name
,[UserVehicle.UserID] = null
,[UserVehicle.VehicleID] = null
,[UserVehicle.IsService] = null
,[Vehicle.ID] = v.ID
,[Vehicle.Name] = v.Name
from #User u
left join #UserFarm uf on u.ID = uf.UserID
left join #Farm f on uf.FarmID = f.ID
left join #FarmVehicle fv on f.ID = fv.VehicleID
left join #Vehicle v on fv.VehicleID = v.ID
union all
select [User.ID] = u.ID
,[User.Name] = u.Name
,[Farm.ID] = null
,[Farm.Name] = null
,[UserVehicle.UserID] = uv.UserID
,[UserVehicle.VehicleID] = uv.VehicleID
,[UserVehicle.IsService] = case when uv.IsService = 0 then 'No' else 'Yes' end
,[Vehicle.ID] = v.ID
,[Vehicle.Name] = v.Name
from #User u
left join #UserFarm uf on u.ID = uf.UserID
left join #UserVehicle uv on u.ID = uv.UserID
left join #Vehicle v on uv.VehicleID = v.ID
This query returns the following dataset:
User.ID User.Name Farm.ID Farm.Name UserVehicle.UserID UserVehicle.VehicleID UserVehicle.IsService Vehicle.ID Vehicle.Name
----------- ---------- ----------- ---------- ------------------ --------------------- --------------------- ----------- ------------
1 Sam 1 Flora NULL NULL NULL 1 Scania
1 Sam NULL NULL 1 2 Yes 2 Civic
If you do not want to see users who are not assigned to vehicles or farms, then change all left join to inner join.
Try with following query
SELECT U.*,T.* FROM (
SELECT F.FARMID,F.NAME AS NAM
,UV.*
,V.*
FROM VEHICLE V
LEFT JOIN FARMVEHICLE FV ON FV.VEHICLEID = V.ID
LEFT JOIN USERVEHICLE UV ON UV.VEHICLEID = V.ID
LEFT JOIN FARM F ON F.FARMID = FV.FARMID
LEFT JOIN USERFARM UF ON UF.FARMID = F.FARMID)T, USER U
Let me know if any issue in query.
You want to show a user's farms and vehicles. However farms and vehicles can be related, and in that case you want to show them together in a row rather than in separated rows.
Example: User1 is related to Farm1, Farm2, and Farm3 and to Vehicle1, Vehicle2, and Vehicle3. Moreover, Farm1 is related to Vehicle1 and Vehicle2 and Farm2 is also related to Vehicle1.
Then you want:
user | farm | vehicle
------+-------+---------
User1 | Farm1 | Vehicle1
User1 | Farm1 | Vehicle2
User1 | Farm2 | Vehicle1
User1 | Farm3 | -
User1 | - | Vehicle3
So the second and third columns show the relations of farms with vehicles. You get these with a full outer join. The join's ON clause is a bit tricky. You want the userid to match and the combination of farmid and vehicleid to be found in the bridge table farmvehicle. Here is one way to do this:
with rel as
(
select coalesce(uf.userid, uv.userid) as userid, uf.farmid, uv.vehicleid
from userfarm uf
full outer join uservehicle uv
on uf.userid = uv.userid
and exists (select * from farmvehicle fv where fv.farmid = uf.farmid
and fv.vehicleid = uv.vehicleid)
)
select u.name as user_name, f.name as farm_name, v.name as vehicle_name
from usr u
left join rel on u.id = rel.userid
left join farm f on f.id = rel.farmid
left join vehicle v on v.id = rel.vehicleid
order by user_name, farm_name, vehicle_name;
Rextester demo: http://rextester.com/DNKSU25931

SQL Server Left Join Counting

I got this sample code
create table #Reservation
(id int identity(1,1),
name varchar(50)
);
create table #Reservation_details
(id int identity(1,1),
reservation_id int,
reservation_date date,
seated tinyint
);
create table #Payment
(id int identity(1,1),
reservation_id int,
payment decimal(18,2)
);
insert into #Reservation(name)
values ('Spiderman'),('Superman'),('Batman'),('Hulk');
insert into #Reservation_details(reservation_id,reservation_date,seated)
values (1,'2017-12-07',0),(2,'2017-12-08',0),(3,'2017-12-08',1),(4,'2017-12-08',0);
insert into #Payment(reservation_id,payment)
values(1,220),(2,1000)
select
A.id,
A.name,
B.reservation_date,
B.seated,
C.payment
from #Reservation A
inner join #Reservation_details B
on B.reservation_id = A.id
left join #Payment C
on C.reservation_id = B.reservation_id
where reservation_date = '2017-12-08'
drop table #Reservation
drop table #Reservation_details
drop table #Payment
I wanted to get the count of all reservations where date is '2017-12-08' and seated = 1 or payment is not null
I've tried putting where date is '2017-12-08' and seated = 1 or payment is not
null
but instead it showed me the past date also how do use where as count?
Try it
select COUNT(*)
from #Reservation A
inner join #Reservation_details B on B.reservation_id = A.id
left join #Payment C on C.reservation_id = B.reservation_id
where reservation_date = '2017-12-08'
and (B.seated=1 or C.payment is not null)
I think you forgot to use brackets (condition1 OR condition2) for OR operation.
See operator precedence - https://learn.microsoft.com/en-us/sql/t-sql/language-elements/operator-precedence-transact-sql
In your case if you don't use brackets then
reservation_date = '2017-12-08' and B.seated=1 or C.payment is not null
equals the following
(reservation_date = '2017-12-08' and B.seated=1) or C.payment is not null
select
A.id,
A.name,
B.reservation_date,
B.seated,
C.payment
from (#Reservation A
inner join #Reservation_details B
on B.reservation_id = A.id
left join #Payment C
on C.reservation_id = B.reservation_id)
where B.reservation_date = '2017-12-08'
AND (B.seated =1 or C.payment is null)
You can use COUNT function by using HAVING in WHERE clause , it should be last statement and after the GROUP BY clause

MS-SQL 2008 issues with multiple tables query

I need help with writing a SQL query. My tables are:
Contribution:
contribution_id | amount | person_id | currency_type
Person
Person_id | firstname | lastname
related related_id | person_id | related_personID
Currency Type CurrencyTypeID | CurrencyName
There are other tables and fields, but these are the ones I need.
Here is the problem I am having..
When a person contributes the first and last name is easy, but when a Brokerage firm contributes, I need to include the real person first name and last name (not the Brokerage Account).
The Brokerage is on the same table as the person.
So far, i have if the contribution.currencyType = '12492' then i need to get the information from related table to find the real person_id.
What I do get when I run the code below is all the data, except when the currencytype = 12492 then I get null for first and last name.
Here is my code so far:
`
declare #fund int = 165
declare #payment_luid int = 58
DECLARE #report_information TABLE(
ContributionID varchar(20),
ContributionDate date,
firstname varchar(50),
lastname varchar(50),
memberID varchar(20),
Pledge money,
cash money,
non_cash money,
fund_name VARCHAR(50))
INSERT INTO #report_information
SELECT c.contribution_id,
c.contribution_date,
case when c.currency_type = '12492' then t3.first_name else t1.first_name end,
case when c.currency_type = '12492' then t3.last_name else t1.last_name end,
case when c.currency_type = '12492' THEN t3.person_id else c.person_id end as MemberID,
case when c.currency_type = '12492' then (select amount From ctrb_pledge where ctrb_pledge.person_id = t3.person_id and fund_id = #fund) else (select amount from ctrb_pledge where ctrb_pledge.person_id = c.person_id and fund_id =#fund) END,
CASE WHEN C.currency_type_luid NOT IN (SELECT lookup_id FROM core_lookup WHERE lookup_type_id=#payment_luid AND lookup_qualifier2 ='1') THEN CCF.amount ELSE 0 END,
CASE WHEN CCF.non_cash = 1 OR C.currency_type IN (SELECT lookup_id FROM core_lookup WHERE lookup_type_id=#payment_luid AND lookup_qualifier2 ='1') THEN CCF.amount ELSE 0 END,
f.fund_name
FROM contribution as c
left join core_person as t1
on t1.person_id = c.person_id
left join relationship as t2
on t2.person_id = c.person_id
left join person as t3
on related_person_id = c.person_id
JOIN ctrb_contribution_fund CCF ON CCF.contribution_id=C.contribution_id
JOIN ctrb_fund F ON F.fund_id = CCF.fund_id
where f.fund_id = #fund
order by contribution_id
SELECT lastname
,firstname
,memberID
,coalesce(SUM(pledge),0) as Pledge
,SUM(cash) AS cash_gifts
,SUM(non_cash) AS non_cash_gifts
,SUM(cash + non_cash) as TotalGiving
,coalesce(SUM(pledge)-(SUM(cash)+SUM(non_cash)),0) as Balance
,fund_name
FROM #report_information
GROUP BY memberid, lastname, firstname, fund_name
ORDER BY lastname asc
`
I figured this problem out. By changing the join statements to FULL JOIN OUTER my missing records appeared.
join core_person as cp
on cp.person_id = c.person_id
full outer join core_relationship as rel
on rel.person_id = c.person_id
full outer join core_person as newCp
on rel.related_person_id = newcp.person_id
I did change my table to something I can remember. t1 = cp,t2 = rel,t3 = newcp.

Joining Two Temp Tables

I would like to join two temp tables into one big temp table. I want all of the records from my first temp table and want the records from my second temp table ONLY if the ProductID doesn't exist in my first temp table.
First temp table:
--define temporary table
declare #tmp table (
ManagerID int null,
ManagerName varchar(250),
ProductID int null,
ProductName varchar(250),
RFIFixedIncomeAttributionID int null,
Value decimal(8,4) null,
Name varchar(250),
Sector varchar(250)
)
--populate temp table
insert into #tmp
select
m.ManagerID, m.ManagerName, p.ID as 'ProductID', p.ProductName, sa.RFIFixedIncomeAttributionID, sa.Value, sc.Name,
case when gm.GeographicMandateID = 2 and s1.SubType1ID = 10 and s2.SubType2ID = 39 then 'Core'
when gm.GeographicMandateID = 2 and s1.SubType1ID = 10 and s2.SubType2ID = 38 then 'Intermediate'
end as 'Sector'
from Products p
join Managers m on m.ManagerID = p.ManagerID
left join RFIFixedIncomeAttribution fia on fia.ParentID = p.ID and fia.ParentTypeID = 26
left join RFIFixedIncomeSectorAllocation sa on sa.RFIFixedIncomeAttributionID = fia.ID
and sa.RFIFixedIncomeDataTypeID = 1
join RFIFixedIncomeSectorCategories sc on sc.ID = sa.RFIFixedIncomeSectorCategoryID
join SubType1 s1 on s1.SubType1ID = p.SubType1ID
join SubType2 s2 on s2.SubType2ID = p.SubType2ID
join GeographicMandates gm on gm.GeographicMandateID = p.GeographicMandateID
where p.prodclasscategoryid = 4
and fia.year = 2014
and fia.quarter = 6/3
and p.Rank = 1
order by m.ManagerName, p.ProductName
--get filtered dataset
select * from #tmp
where
Sector in ('Core')
Second temp table:
--define temporary table
declare #tmp2 table (
ManagerID int null,
ManagerName varchar(250),
ProductID int null,
ProductName varchar(250),
RFIFixedIncomeAttributionID int null,
Value decimal(8,4) null,
Name varchar(250),
Sector varchar(250)
)
--populate temp table
insert into #tmp2
select
m.ManagerID, m.ManagerName, p.ID as 'ProductID', p.ProductName, sa.RFIFixedIncomeAttributionID, sa.Value, sc.Name,
case when gm.GeographicMandateID = 2 and s1.SubType1ID = 10 and s2.SubType2ID = 39 then 'Core'
when gm.GeographicMandateID = 2 and s1.SubType1ID = 10 and s2.SubType2ID = 38 then 'Intermediate'
end as 'Sector'
from Products p
join Managers m on m.ManagerID = p.ManagerID
join Vehicles v on v.ProductID = p.ID
join ManagerAccounts ma on ma.VehicleID = v.ID
join Accounts a on a.MgrAccountID = ma.MgrAccountID
left join RFIFixedIncomeAttribution fia on fia.ParentID = a.AccountID and fia.ParentTypeID = 6
left join RFIFixedIncomeSectorAllocation sa on sa.RFIFixedIncomeAttributionID = fia.ID
and sa.RFIFixedIncomeDataTypeID = 1
join RFIFixedIncomeSectorCategories sc on sc.ID = sa.RFIFixedIncomeSectorCategoryID
join SubType1 s1 on s1.SubType1ID = p.SubType1ID
join SubType2 s2 on s2.SubType2ID = p.SubType2ID
join GeographicMandates gm on gm.GeographicMandateID = p.GeographicMandateID
where p.prodclasscategoryid = 4
and fia.year = 2014
and fia.quarter = 6/3
and p.Rank = 1
order by m.ManagerName, p.ProductName
--get filtered dataset
select * from #tmp2
where
Sector in ('Core')
Few points that have already brought up
Union is the term you want, join is something quite different.
You are not working with temp tables, you are working with table variables. Not quite the same thing
mysql and mssql are not the same thing, tag your questions as one or the other, not both.
select * from #tmp
union all
select * from #tmp2 where productID not in (select productID from #tmp)
Not sure if I'd rely on this query in MySQL as it'll struggle with the not in clause...you can use the join syntax in Jasmine's answer for the second half of the union clause.
This is a case of "find all rows with NO MATCH in the other table" and we have a pattern for that. First, swap your tables - the table where you expect to be missing rows will be the second or RIGHT table, the other is the LEFT table.
select <columns>
from table1
LEFT OUTER JOIN table1.ID = table2.ID
where table2.ID IS NULL
OR... don't swap the tables and use RIGHT OUTER JOIN - but that's non-standard.
In your code, there's a problem...
and fia.quarter = 6/3
is equivalent to:
and fia.quarter = 2
I think you need some quotation marks there.

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.