How to use Left Join in subquery SQL Server? - sql

I am trying to use left join in subquery in SQL Server. My query looks fine to me but it gives syntax error.
This is my query:
(
SELECT
FK_OrderNo AS LHNo, VendorName AS LHVendor
FROM
tbl_ShipmentAPAR
LEFT JOIN
tbl_vendors ON FK_VendorID = VendorID
WHERE
FK_ServiceID = 'LH'
) LHBase ON PK_OrderNo = LHNo
LEFT JOIN
(SELECT
FK_OrderNo AS DANo,
VendorName AS DAVendor
FROM
tbl_ShipmentAPAR
LEFT JOIN
tbl_vendors ON FK_VendorId = VendorId
WHERE
FK_ServiceId = 'DA') DABase ON PK_OrderNo = DANo
This is the error I'm getting:
This is my table structure:
CREATE TABLE tbl_ShipmentAPAR
(
VendorID int PRIMARY KEY,
VendorName varchar(200),
FK_OrderNo int
)
CREATE TABLE tbl_vendors
(
FK_VendorID int,
FOREIGN KEY (FK_VendorID) REFERENCES tbl_ShipmentAPAR(VendorID),
FK_ServiceID varchar(200)
)
INSERT INTO tbl_ShipmentAPAR VALUES (1, 'John',123)
INSERT INTO tbl_vendors VALUES (1,'LH')

As #Chris mentioned, the query is bit incomplete. I guess you are trying to do something like this:
SELECT * FROM /*--> Added new */
(
SELECT
FK_OrderNo AS LHNo, VendorName AS LHVendor
FROM
tbl_ShipmentAPAR
LEFT JOIN
tbl_vendors ON FK_VendorID = VendorID
WHERE
FK_ServiceID = 'LH'
) LHBase
LEFT JOIN
(SELECT
FK_OrderNo AS DANo,
VendorName AS DAVendor
FROM
tbl_ShipmentAPAR
LEFT JOIN
tbl_vendors ON FK_VendorId = VendorId
WHERE
FK_ServiceId = 'DA') DABase ON LHBase.LHNo = DABase.DANo /* -->Modified PKOrder no to LHNo because PKOrder no doesn't exist in either of the sub-queries */
This query worked for me. Comment to this answer if something must be changed.

Related

declare table inserted values duplicated

I try to get two different table values to insert one declare table but the employee ID is duplicate,
DECLARE #WSotable TABLE
(
Employee int,
ChargedQty int,
ReturnQty int
)
--insert first table data
INSERT INTO #WSotable
SELECT DISTINCT
MD_Employee.ID,
SUM(TR_InvoiceDetails.InvoiceQuantity) AS ChargedQty,
0 AS ChargedQty
FROM
TR_SalesOrderHeader
INNER JOIN
TR_InvoiceHeader ON TR_InvoiceHeader.SalesOrderID = TR_SalesOrderHeader.ID
INNER JOIN
TR_InvoiceDetails ON TR_InvoiceDetails.InvoiceID = TR_InvoiceHeader.ID
INNER JOIN
MD_ItemMaster ON TR_InvoiceDetails.ItemID = MD_ItemMaster.ID
INNER JOIN
MD_Supplier ON MD_ItemMaster.SupplierID= MD_Supplier.ID
INNER JOIN
MD_Employee ON TR_SalesOrderHeader.CreatedBy = MD_Employee.ID
WHERE
MD_Supplier.ID = 3
AND MD_ItemMaster.ID = 572
GROUP BY
MD_Employee.ID
--insert second table data
INSERT INTO #WSotable
SELECT DISTINCT
MD_Employee.ID,
0 AS ChargedQty,
SUM(TR_SalesReturnDetails.ReturnQuantity) AS ReturnQty
FROM
TR_SalesReturnHeader
INNER JOIN
TR_SalesReturnDetails ON TR_SalesReturnDetails.SalesReturnID = TR_SalesReturnDetails.ID
INNER JOIN
MD_ItemMaster ON TR_SalesReturnDetails.ItemID = MD_ItemMaster.ID
INNER JOIN
MD_Supplier ON MD_ItemMaster.SupplierID= MD_Supplier.ID
INNER JOIN
MD_Employee ON TR_SalesReturnHeader.CreatedBy = MD_Employee.ID
WHERE
MD_Supplier.ID = 3
AND MD_ItemMaster.ID = 572
GROUP BY
MD_Employee.ID
Result:
I need to stop EmployeeID duplicates
Return the data with a final aggregation:
select Employee, sum(ChargedQty) ChargedQty, sum(ReturnQty) ReturnQty
from #WSotable
group by Employee

TSQL not pulling in complete data set

I have a complicated stored procedure that worked great until the client wanted to change it.
I am not great with complicated TSQL so I have no idea what is wrong with my code.
Here is the situation. I have three temp tables, Cost, Adjustments, and Payments.
In the end I merge all these tables together in a report table. The problem I am having is even if one or even two of these tables are null, as long as one table has data I need that data to show. I currently have it set up with full outer joins but I'm still not getting the full list, I'm missing probably....50 ish records that should be there.
Can anyone look at this code and tell me what the heck I'm doing wrong? I'm bringing all the data together on #ThisReportAll
UPDATE: So I removed the having clause to see what was going on, and the data for the overdue balance is returning null. So the math isn't...mathing correctly, any ideas?
CODE
CREATE TABLE #BalanceAdjustmentsAll (CustomerId int, Amount decimal(20,2));
CREATE TABLE #AnimalCostsAll (thisIndex int IDENTITY(1,1), AnimalTypeId int, Cost decimal(20,2));
CREATE TABLE #TotalAnimalCostAll (thisIndex int IDENTITY(1,1), YearSetupId int, AnimalTypeId int, AnimalType varchar(max), OwnerId int, CustomerId int, AnimalCount int, TtlSpeciesCost decimal(20,2));
CREATE TABLE #CustomerPaymentsAll (thisIndex int IDENTITY(1,1), CustomerID nvarchar(max), TtlPayments decimal(20,2));
CREATE TABLE #CustomerInfoAll (thisIndex int IDENTITY(1,1), OwnerId int, CustomerId int, FName nvarchar(200), LName nvarchar(200),BName nvarchar(200));
CREATE TABLE #ThisReportAll (thisIndex int IDENTITY(1,1), CustomerID nvarchar(max), Year char(4), OverdueBalance decimal(20,2), YearSetupId int);
INSERT INTO #BalanceAdjustmentsAll (CustomerId, Amount)
SELECT CustomerId, SUM(Amount)
FROM BalanceAdjustment
WHERE YearSetupId = 3
GROUP BY CustomerId;
/* GET Costs per Animal for 'This' yearID */
INSERT INTO #AnimalCostsAll (AnimalTypeId, Cost)
SELECT AnimalTypeId, Cost
FROM PerCapitaFee
WHERE YearSetupId = 3;
/* GET animal type totals for owner per year */
INSERT INTO #TotalAnimalCostAll (yearSetupId,AnimalTypeId,AnimalType,OwnerId,CustomerId,AnimalCount,TtlSpeciesCost)
SELECT YearSetup.YearSetupId,AnimalCount.AnimalTypeId,AnimalType.ShortDescription,Owner.OwnerId,Report.CustomerId,AnimalCount.Count,(ac.Cost * AnimalCount.Count)
FROM AnimalCount
INNER JOIN #AnimalCostsAll as ac
ON ac.AnimalTypeId = AnimalCount.AnimalTypeId
INNER JOIN AnimalType
ON AnimalCount.AnimalTypeId=AnimalType.AnimalTypeId
INNER JOIN AnimalLocation
ON AnimalLocation.AnimalLocationid=AnimalCount.AnimalLocationId
INNER JOIN Owner
ON Owner.OwnerId=AnimalLocation.OwnerId
AND Owner.OwnerType = 'P'
INNER JOIN Report
ON Report.ReportId=Owner.ReportId
INNER JOIN YearSetup
ON Report.YearSetupId=YearSetup.YearSetupId
INNER JOIN County
ON County.CountyId=AnimalLocation.CountyId
WHERE YearSetup.YearSetupId = 3 AND Report.Completed IS NOT NULL AND Report.CustomerId IS NOT NULL
/* Get The total payments a customer has made */
INSERT INTO #CustomerPaymentsAll (CustomerID,TtlPayments)
SELECT BPS.CustomerId,SUM(BPS.Amount)
FROM BatchPaymentSplit BPS
LEFT JOIN BatchPayment bp ON BPS.BatchPaymentId=bp.BatchPaymentId
LEFT JOIN Batch b ON bp.BatchId=b.BatchId
WHERE BPS.CustomerId IS NOT NULL
AND
(
((b.BatchTypeId = 'M' OR b.BatchTypeId = 'C' OR b.BatchTypeId = 'E') AND (b.BatchStatusId = 'S'))
OR
((b.BatchTypeId = 'B' OR b.BatchTypeId = 'N' OR b.BatchTypeId = 'R' OR b.BatchTypeId = 'T') AND (b.BatchStatusId = 'S' OR b.BatchStatusId='C'))
)
AND
BPS.YearSetupId = 3
GROUP BY BPS.CustomerId;
/* Deal with the name/id stuff */
INSERT INTO #CustomerInfoAll(FName, LName, BName, OwnerId, CustomerId)
SELECT
o.FirstName AS FName,
o.LastName AS LName,
o.BusinessName AS BName,
o.OwnerId AS OwnerId,
r.CustomerId AS CustomerId
FROM Owner o
INNER JOIN Report r
ON o.ReportId = r.ReportId
AND o.OwnerType = 'P'
WHERE r.CustomerId IN (SELECT CustomerId FROM #TotalAnimalCostAll)
AND r.Completed IS NOT NULL
AND r.YearSetupId = 3
AND NOT EXISTS(
SELECT 1 FROM Report
WHERE r.CustomerId = Report.CustomerId
AND Report.Completed IS NOT NULL
AND r.ReportId != Report.ReportId
AND r.YearSetupId = Report.YearSetupId
AND (
r.Completed < Report.Completed
OR (
r.Completed = Report.Completed
AND r.ReportId < Report.ReportId
)
)
)
ORDER BY CustomerId;
/** MAKE IT SO #1 **************************************************/
/* Simply Joining The Customer Info to the calculated totals to avoid any aggregation shenanigans... */
INSERT INTO #ThisReportAll (CustomerID,Year,OverdueBalance,YearSetupId)
SELECT COALESCE(t.CustomerId,cp.CustomerId,ba.CustomerID), ys.Name AS Year,
CASE
WHEN (SUM(t.TtlSpeciesCost) < 5 AND SUM(t.TtlSpeciesCost) > 0) AND (ys.Name='2015' OR ys.Name='2016')
THEN (5) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
ELSE SUM(t.TtlSpeciesCost) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
END
AS TtlOwnerCost, t.YearSetupId AS YearSetupId
FROM #TotalAnimalCostAll t
FULL OUTER JOIN #CustomerPaymentsAll cp ON t.CustomerId=cp.CustomerID
FULL OUTER JOIN #BalanceAdjustmentsAll ba ON COALESCE(t.CustomerId,cp.CustomerId)=ba.CustomerID
LEFT JOIN YearSetup ys ON COALESCE(t.CustomerId,cp.CustomerId,ba.CustomerID) = ys.YearSetupId
GROUP BY COALESCE(t.CustomerId,cp.CustomerId,ba.CustomerID),ys.Name,cp.TtlPayments, ba.Amount, t.YearSetupId
HAVING
CASE WHEN (SUM(t.TtlSpeciesCost) < 5 AND SUM(t.TtlSpeciesCost) > 0) AND (ys.Name='2015' OR ys.Name='2016')
THEN SUM(5) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
ELSE SUM(t.TtlSpeciesCost) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
END < 0;
/* Return some meaningful report data */
SELECT r.Year AS [YearName],r.CustomerID,left(ci.FName,20) AS [FirstName], left(ci.LName,40) AS [LastName], left(ci.BName,40) AS [BusinessName],r.OverdueBalance AS [Balance],r.YearSetupId
FROM #ThisReportAll r
LEFT JOIN #CustomerInfoAll ci ON r.CustomerID = ci.CustomerId
ORDER BY CAST(r.CustomerID as int) ASC;
DROP TABLE #BalanceAdjustmentsAll;
DROP TABLE #AnimalCostsAll;
DROP TABLE #TotalAnimalCostAll;
DROP TABLE #CustomerPaymentsAll;
DROP TABLE #CustomerInfoAll;
DROP TABLE #ThisReportAll;
Found it. I didn't have a default value for t.TtlSpeciesCost if it was null
SUM(t.TtlSpeciesCost) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
to
SUM(ISNULL(t.TtlSpeciesCost,0)) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
Some missing records may be found here:
by adjusting /* Get The total payments a customer has made */
INSERT INTO #CustomerPaymentsAll (CustomerID,TtlPayments)
SELECT BPS.CustomerId,SUM(BPS.Amount)
FROM BatchPaymentSplit BPS
LEFT JOIN BatchPayment bp
ON BPS.BatchPaymentId=bp.BatchPaymentId
LEFT JOIN Batch b
ON bp.BatchId=b.BatchId
AND ((b.BatchTypeId IN ('M', 'C', 'E') AND b.BatchStatusId = 'S')
OR (b.BatchTypeId IN ('B','N','R','T') AND (b.BatchStatusId IN ('S','C')))
WHERE BPS.CustomerId IS NOT NULL
AND BPS.YearSetupId = 3
GROUP BY BPS.CustomerId;
The WHERE on B would have negated the left join causing null records to be omitted. or made the left join to behave like an inner join.
To know for certain we need sample data from your tables showing which records are being omitted that you need to retain.
I also refactored the OR's and made them "IN"s to improve readability.

changing temp tables to declaring them

Just a question regards to temp tables and declaring table. If I change the temp tables 'ChangedData' and 'PackageDatatoProcess' to their own variables '#ChangedData' and '#PackageDatatoProcess', can I ask how I am suppose to change the select into statement as I have not quite done this before. Virtually I told that we can declare tables rather than using the select into but just need a bit of help with this:
select distinct * into #PackageDataToProcess from #ChangedData pp
outer apply (
select pk.Reference, pjl.PackageToJournalLinkId, j.CreatedDate, pccl.PackageCostChangeLogId from Jet2Holidays.dbo.Package pk
inner join Jet2Holidays.dbo.PackageToJournalLink pjl on pk.PackageId = pjl.PackageId
inner join Jet2Holidays.dbo.Journal j on pjl.JournalId = j.JournalId
and j.PrincipalName= iif(#AllowNonSupportChanges = 0, 'HolidaysSupport', j.PrincipalName)
inner join Jet2Holidays.dbo.BusinessProcess bp on pjl.BusinessProcessId = bp.BusinessProcessId
and bp.[Description] = iif(#AllowNonSupportChanges = 0, 'CallCentreAction', bp.[Description])
left outer join Jet2Holidays.dbo.PackageCostChangeLog pccl on pccl.PackageToJournalLinkId = pjl.PackageToJournalLinkId
where pk.Reference = pp.PackageReference
and pp.JournalID = pjl.JournalId
) as packageData
First, you declare your variable tables like so:
DECLARE #PackageDataToProcess TABLE
(
Reference UNIQUEIDENTIFIER
, PackageToJournalLinkId INT
, CreatedDate DATETIME
, PackageCostChangeLogId INT
, {other columns here}
)
DECLARE #ChangedData TABLE
(
Reference UNIQUEIDENTIFIER
, PackageToJournalLinkId INT
, CreatedDate DATETIME
, PackageCostChangeLogId INT
, {other columns here}
)
At this point you can populate your #ChangedData table like so:
INSERT #ChangedData ( Reference, PackageToJournalLinkId, CreatedDate, PackageCostChangeLogId, {other columns})
SELECT Reference, PackageToJournalLinkId, CreatedDate, PackageCostChangeLogId, {other columns}
FROM ChangedDataSource -- Table, Procedure, Function
And then you can run your code by substituting #PackageDataToProcess for #PackageDataToProcess. Here it is again with a slight re-write (from the original):
INSERT #PackageDataToProcess
select distinct pp.* from #ChangedData pp
outer apply (
select pk.Reference, pjl.PackageToJournalLinkId, j.CreatedDate, pccl.PackageCostChangeLogId from Jet2Holidays.dbo.Package pk
inner join Jet2Holidays.dbo.PackageToJournalLink pjl on pk.PackageId = pjl.PackageId
inner join Jet2Holidays.dbo.Journal j on pjl.JournalId = j.JournalId
and j.PrincipalName= iif(#AllowNonSupportChanges = 0, 'HolidaysSupport', j.PrincipalName)
inner join Jet2Holidays.dbo.BusinessProcess bp on pjl.BusinessProcessId = bp.BusinessProcessId
and bp.[Description] = iif(#AllowNonSupportChanges = 0, 'CallCentreAction', bp.[Description])
left outer join Jet2Holidays.dbo.PackageCostChangeLog pccl on pccl.PackageToJournalLinkId = pjl.PackageToJournalLinkId
where pk.Reference = pp.PackageReference
and pp.JournalID = pjl.JournalId
) as packageData
Your declared tabled will go out of scope in a similar manner to the way your non-global temporary table do.

SQL selecting not surely existing column from on table or another

I use generalisation/specialize table Zadavatel (which contains primary key) as either table Sukromna_osoba or Firma (both contains foreign key that points on Zadavatel).
I need to select Sukromna_osoba table if Sukromna_osoba.meno = 'string' exists or Firma table if Firma.nazov_firmy = 'string' exists, both if both conditions are true. I also need this to be in one select.
CREATE TABLE Zadavatel (
id_zadavatela INTEGER,
adresa VARCHAR(25)
);
CREATE TABLE Sukromna_osoba (
id_sukromnej_osoby INTEGER,
meno VARCHAR(20),
mobil INTEGER,
email VARCHAR(20)
);
CREATE TABLE Firma (
id_firmy INTEGER,
nazov_firmy VARCHAR(20),
ico INTEGER,
bankove_spojenie INTEGER
);
id_zadavatela is primary key, and id_sukromnej_osoby and id_firmy are foreign keys which points at id_zadavatela.
I tried something like this:
SELECT PR.id_projektu, PR.popis, ZAD.id_zadavatela, FI.nazov_firmy
FROM Projekt PR JOIN Zamestnanec ZAM ON PR.manazer = ZAM.osobne_cislo
JOIN Zadavatel ZAD ON PR.zadavatel = ZAD.id_zadavatela
JOIN Firma FI ON ZAD.id_zadavatela = FI.id_firmy
WHERE ZAM.meno = 'Jan Novák' OR (
SELECT PR1.id_projektu, PR1.popis, ZAD1.id_zadavatela, SO1.meno
FROM Projekt PR1 JOIN Zamestnanec ZAM1 ON PR1.manazer = ZAM1.osobne_cislo
JOIN Zadavatel ZAD1 ON PR1.zadavatel = ZAD1.id_zadavatela
JOIN Sukromna_osoba SO1 ON ZAD1.id_zadavatela = SO1.id_sukromnej_osoby
WHERE ZAM1.meno = 'Jan Novák'
)
Since you do not know if it's a firm or a person, you could use left outer join on both, like this:
SELECT PR.id_projektu, PR.popis, ZAD.id_zadavatela, FI.nazov_firmy, SO.meno
FROM Projekt PR
JOIN Zamestnanec ZAM ON PR.manazer = ZAM.osobne_cislo
JOIN Zadavatel ZAD ON PR.zadavatel = ZAD.id_zadavatela
LEFT OUTER JOIN Firma FI ON ZAD.id_zadavatela = FI.id_firmy
LEFT OUTER JOIN Sukromna_osoba SO ON ZAD.id_zadavatela = SO.id_sukromnej_osoby
WHERE ZAM.meno = 'Jan Novák'
One of the two result columns, nazov_firmy or meno, will be NULL.

Error while using same table data twice during inner join

Suppose I have a table, in Database name 'Old', as below:
TABLE A
(
SeniorVehicle varchar(255),
SeniorVehicleAllowance int,
JuniorVehicle varchar(255),
JuniorVehicleAllowance int
ManagerVehicle varchar(255),
ManagerVehicleAllowance int
);
And another table, in Database name 'New' as below:
TABLE B
(
SeniorVehicle int,
SeniorVehicleAllowance int,
JuniorVehicle int,
JuniorVehicleAllowance int,
ManagerVehicle int,
ManagerVehicleAllowance int
);
I want to bring the data from TABLE A of Database 'Old' to TABLE B of Database 'New'.
The thing is that, there is a table named Vehicle in both databases as bellow:
TABLE Vehicle
(
VehicleID int pk,
VehicleName varchar(255)
)
Values in SeniorVehicle, JuniorVehicle and ManagerVehicle columns in TABLE A are the VehicleName value in TABLE Vehicle. But the value of SeniorVehicle, JuniorVehicle and ManagerVehicle that must be stored in TABLE B must be the value of VehicleID column in the Vehicle Table.
How to achieve this without error????
I have tried the following:
INSERT INTO B
(SeniorVehicle, SeniorVehicleAllowance, JuniorVehicle, JuniorniorVehicleAllowance, ManagerVehicle, ManagerVehicleAllowance)
SELECT Vehicle.VehicleID, c.SeniorVehicleAllowance, c.VehicleID, c.JuniorVehicleAllowance, c.VehicleID, c.ManagerVehicleAllowance
FROM (SELECT b.SeniorVehicle, b.SeniorVehicleAllowance, Vehicle.VehicleID, b.JuniorVehicleAllowance, b.VehicleID, b.ManagerVehicleAllowance
FROM (SELECT a.SeniorVehicle, a.SeniorVehicleAllowance, a.JuniorVehicle, a.JuniorVehicleAllowance, Vehicle.VehicleID, a.ManagerVehicleAllowance
FROM (SELECT SeniorVehicle, SeniorVehicleAllowance, JuniorVehicle, JuniorVehicleAllowance, ManagerVehicle, ManagerVehicleAllowance FROM A) as a
Inner join
Vehicle
ON a.ManagerVehicle = Vehicle.VehicleName) as b
Inner join
Vehicle
ON b.JuniorVehicle = Vehicle.VehicleName) as c
Inner join
Vehicle
ON c.SeniorVehicle = Vehicle.VehicleName
I get the following error:
The column 'VehicleID' was specified multiple times for 'c'
My Databse is MSSQL Server 2008 R2
Reformatting your current query gives:
SELECT
Vehicle.VehicleID,
c.SeniorVehicleAllowance,
c.VehicleID,
c.JuniorVehicleAllowance,
c.VehicleID,
c.ManagerVehicleAllowance
FROM (
SELECT b.SeniorVehicle,
b.SeniorVehicleAllowance,
Vehicle.VehicleID,
b.JuniorVehicleAllowance,
b.VehicleID,
b.ManagerVehicleAllowance
FROM (
SELECT a.SeniorVehicle,
a.SeniorVehicleAllowance,
a.JuniorVehicle,
a.JuniorVehicleAllowance,
Vehicle.VehicleID,
a.ManagerVehicleAllowance
FROM (
SELECT SeniorVehicle,
SeniorVehicleAllowance,
JuniorVehicle,
JuniorVehicleAllowance,
ManagerVehicle,
ManagerVehicleAllowance
FROM A
) as a
Inner join Vehicle
ON a.ManagerVehicle = Vehicle.VehicleName
) as b
Inner join Vehicle
ON b.JuniorVehicle = Vehicle.VehicleName
) as c
Inner join Vehicle
ON c.SeniorVehicle = Vehicle.VehicleName
In this query, the sub query aliased c has two columns called VehicleID (which is what your error message is telling you.
The smallest change to fix the issue is to alias the columns in the sub query, e.g:
SELECT
Vehicle.VehicleID AS SeniorVehicleId,
c.SeniorVehicleAllowance,
c.JuniorVehicleId,
c.JuniorVehicleAllowance,
c.ManagerVehicleID,
c.ManagerVehicleAllowance
FROM (
SELECT b.SeniorVehicle,
b.SeniorVehicleAllowance,
Vehicle.VehicleID AS JuniorVehicleId,
b.JuniorVehicleAllowance,
b.ManagerVehicleID,
b.ManagerVehicleAllowance
FROM (
SELECT a.SeniorVehicle,
a.SeniorVehicleAllowance,
a.JuniorVehicle,
a.JuniorVehicleAllowance,
Vehicle.VehicleID AS ManagerVehicleID,
a.ManagerVehicleAllowance
-- Rest ommited for brevity
It would be also possible to re-write the query with more joins, and omit the need for the subqueries altogether also:
SELECT srmgr.VehicleId AS SeniorVehicleId,
A.SeniorVehicleAllowance,
jrmgr.VehicleId AS JuniorVehicleId,
A.JuniorVehicleAllowance,
mgr.VehicleId AS ManagerVehicleId,
A.ManagerVehicleAllowance
FROM A
INNER JOIN Vehicle AS mgr
ON a.ManagerVehicle = mgr.VehicleName
INNER JOIN Vehicle AS jrmgr
ON a.ManagerVehicle = jrmgr.VehicleName
INNER JOIN Vehicle AS srmgr
ON a.ManagerVehicle = srmgr.VehicleName