I have an Access DB I am maintaining for a client.
I have 4 tables. Claims, Eligibility, Pharmacy, and Codes.
The Primary Key I am using is PHID + SID = MemberID which I am linking to each table, and then the Codes table is merely used for a description. See queries below for better visualization of that...
Query 1: Member_Claims_Query
SELECT
Eligibility.GROUPID,
Eligibility.PHID & '-' & Eligibility.SID AS MemberID,
[Eligibility].[DOB] AS DOB,
Eligibility.GENDER,
Eligibility.RELATIONSHIP_CODE,
MaxDiagDollars.HighestDiagPaid/SUM(Claims.PAID_AMT) AS ['%'],
MaxDiagDollars.HighestDiagPaid/SUM(Claims.PAID_AMT) as 'Percent',
ROUND(SUM(Claims.PAID_AMT)) AS TOTALPAID,
ROUND(Sum(IIf(Format(Serv_Beg_Date,'yyyy')='2011',Claims.PAID_AMT,0))) AS 2011TOTALPAID,
ROUND(Sum(IIf(Format(Serv_Beg_Date,'yyyy')='2012',Claims.PAID_AMT,0))) AS 2012TOTALPAID,
ROUND(Sum(IIf(Format(Serv_Beg_Date,'yyyy')='2013',Claims.PAID_AMT,0))) AS 2013TOTALPAID
FROM (Claims
INNER JOIN Eligibility
ON (Claims.[SID] = Eligibility.[SID]) AND (Claims.[PHID] = Eligibility.[PHID]))
INNER JOIN (SELECT PHID, SID, MAX(TotalPaid) AS HighestDiagPaid
FROM (SELECT [PHID], [SID], DIAG_CODE1, SUM(PAID_AMT) AS TotalPaid FROM Claims GROUP BY [PHID], [SID], [DIAG_CODE1]) AS [%$###_Alias] GROUP BY PHID, SID) AS MaxDiagDollars ON ( MaxDiagDollars.[PHID]=Eligibility.[PHID] ) AND ( MaxDiagDollars.[SID] = Eligibility.[SID] )
WHERE Eligibility.DOB < DateAdd( 'y', -2, DATE())
GROUP BY
Eligibility.GROUPID, Eligibility.PHID & '-' & Eligibility.SID, [Eligibility].[DOB], Eligibility.GENDER, Eligibility.RELATIONSHIP_CODE, MaxDiagDollars.HighestDiagPaid
HAVING SUM(Claims.PAID_AMT)>10000 and MaxDiagDollars.HighestDiagPaid/SUM(Claims.PAID_AMT) <= 0.80;
This query is supposed to take the Total Amount Paid per Member and give a Total Amount PAid, and then yearly break outs.
Query 2: Member_By_Diag
SELECT
Eligibility.PHID & '-' & Eligibility.SID AS MemberID,
Claims.Diag_Code1,
ROUND(Sum(Claims.PAID_AMT)) AS TotalPaid,
ROUND(Sum(IIf(Format(Serv_Beg_Date,'yyyy')='2011',Claims.PAID_AMT,0))) AS 2011TotalPaid,
ROUND(Sum(IIf(Format(Serv_Beg_Date,'yyyy')='2012',Claims.PAID_AMT,0))) AS 2012TotalPaid,
ROUND( Sum(IIf(Format(Serv_Beg_Date,'yyyy')='2013',Claims.PAID_AMT,0))) AS 2013TotalPaid
FROM
(Claims
INNER JOIN Eligibility
ON (Claims.[SID] = Eligibility.[SID]) AND (Claims.[PHID] = Eligibility.[PHID]))
INNER JOIN Pharmacy
ON (Eligibility.SID = Pharmacy.SID) AND (Eligibility.PHID = Pharmacy.PHID)
GROUP BY
Eligibility.PHID & '-' & Eligibility.SID, Claims.Diag_Code1
HAVING count( [Pharmacy].[NDC] ) >4 and count(IIF(Claims.REV_CODE= '450',1,0) ) > 1
ORDER BY Eligibility.PHID & '-' & Eligibility.SID;
The second query is essentially supposed to take the Codes for each member and break out their amount paids by Diagnosis code.
Query 3: combined_query
SELECT *
FROM (Member_Claims_Query AS a INNER JOIN Member_by_Diag AS b ON a.MemberID=b.MemberID) INNER JOIN Codes AS c ON c.DxCode = b.Diag_Code1;
ISSUE
My Client sent me an e-mail stating that the Total Paid in the Member_By_Diag query is sometimes higher than the Total Paid by the Member_By_Claim query. yet they are being computed the same way.
I opened up the DB and wrote a simple query to see how many records were returning where the b.Total_Paid ( Member_By_Diag.Total_Paid) is greater than the Member_Claims_Query.Total_Paid.
It returned 262/1278 records where this was the case.
SELECT * FROM Combined_Query WHERE b_TotalPaid > a_TotalPaid
This picture acurately describes what I am seeing along with my client.
As you can see. a_TotalPaid > b_TotalPaid. But if you look up at my query, they are the same? Is this a group by issue? or a join issue? Any help would be much appreciated.
There are a couple of differences between the queries that could be contributing to this. The main culprits are your INNER JOIN statements and your HAVING statement. Those could easily be excluding records that will have an effect on your TotalPaid field. Without the original dataset, there's not much I can tell you, but you may want to run those queries and play with removing and inserting the various INNER JOIN and HAVING clauses to see which one is deleting the records that are causing your totals to not be equal.
I appreciate the answers everyone... You didn't exactly answer the question, but the inner join on Pharmacy was causing the issue, I was specifically using it in relation to the HAVING clause, when I added a count(*) I noticed it was actually multiplying my results. For Ex. If a member had 7 claims, and 6 Pharmacy records it was multiplying it making it 42 records making my total paids extremely high, and they weren't relating to the CLAIMS themselves...hence the ultimate issue. Here is the solution in the Member_By_Diag Query:
SELECT Eligibility.PHID & '-' & Eligibility.SID AS MemberID, Claims.Diag_Code1, Round(Sum(Claims.PAID_AMT)) AS TotalPaid, Round(Sum(IIf(Format(Serv_Beg_Date,'yyyy')='2011',Claims.PAID_AMT,0))) AS 2011TotalPaid, Round(Sum(IIf(Format(Serv_Beg_Date,'yyyy')='2012',Claims.PAID_AMT,0))) AS 2012TotalPaid, Round(Sum(IIf(Format(Serv_Beg_Date,'yyyy')='2013',Claims.PAID_AMT,0))) AS 2013TotalPaid, Count(*) AS Expr1
FROM (Claims INNER JOIN Eligibility ON (Claims.[SID] = Eligibility.[SID]) AND (Claims.[PHID] = Eligibility.[PHID])) INNER JOIN ***(SELECT PHID, SID, COUNT(NDC) AS RXCount FROM Pharmacy GROUP BY PHID, SID ORDER BY PHID, SID) AS Pharmacy*** ON (Eligibility.SID = Pharmacy.SID) AND (Eligibility.PHID = Pharmacy.PHID)
GROUP BY Eligibility.PHID & '-' & Eligibility.SID, Claims.Diag_Code1
***HAVING Count(IIf([Claims].[REV_CODE]='450',1,0))>1***
ORDER BY Eligibility.PHID & '-' & Eligibility.SID;
This made the dollars look much more reasonable. Thanks everyone.
Related
I am working on a database of a large retail store.
I have to query data from multiple tables to get numbers such as revenue, raw proceeds and compare different time periods.
Most of it is quite easy but I was struggling to work out a way of joining multiple CTEs.
I made a fiddle so you know what I am talking about.
I simplified the structure a lot and left out quite a few columns in the subqueries because they do not matter in this case.
As you can see every row in every table has country and brand in it.
The final query has to be grouped by those.
What I first tried was to FULL JOIN all the tables, but that didn't work in some cases as you can see here: SQLfiddle #1. Note the two last rows which did not group correctly.
Select Coalesce(incoming.country, revenue.country, revcompare.country,
openord.country) As country,
Coalesce(incoming.brand, revenue.brand, revcompare.brand,
openord.brand) As brand,
incoming.OrdersNet,
openord.OpenOrdersNet,
revenue.Revenue,
revenue.RawProceeds,
revcompare.RevenueCompare,
revcompare.RawProceedsCompare
From incoming
Full Join openord On openord.country = incoming.country And
openord.brand = incoming.brand
Full Join revenue On revenue.country = incoming.country And
revenue.brand = incoming.brand
Full Join revcompare On revcompare.country = incoming.country And
revcompare.brand = incoming.brand
Group By incoming.OrdersNet,
openord.OpenOrdersNet,
revenue.Revenue,
revenue.RawProceeds,
revcompare.RevenueCompare,
revcompare.RawProceedsCompare,
incoming.country,
revenue.country,
openord.country,
revcompare.country,
incoming.brand,
revenue.brand,
revcompare.brand,
openord.brand
Order By country,
brand
I then rewrote the query keeping all the CTEs. I added another CTE (basis) which UNIONs all the possible country and brand combinations and left joined on that one.
Now it works fine (check it out here -> SQLfiddle #2) but it just seems so complicated. Isn't there an easier way to achieve this? The only thing I probably won't be able to change are the CTEs as in real life they are way more complex.
WITH basis AS (
SELECT Country, Brand FROM incoming
UNION
SELECT Country, Brand FROM openord
UNION
SELECT Country, Brand FROM revenue
UNION
SELECT Country, Brand FROM revcompare
)
SELECT
basis.Country,
basis.Brand,
incoming.OrdersNet,
openord.OpenOrdersNet,
revenue.Revenue,
revenue.RawProceeds,
revcompare.RevenueCompare,
revcompare.RawProceedsCompare
FROM basis
LEFT JOIN incoming On incoming.Country = basis.Country AND incoming.Brand = basis.Brand
LEFT JOIN openord On openord.Country = basis.Country AND openord.Brand = basis.Brand
LEFT JOIN revenue On revenue.Country = basis.Country AND revenue.Brand = basis.Brand
LEFT JOIN revcompare On revcompare.Country = basis.Country AND revcompare.Brand = basis.Brand
Thank you all for your help!
Since you only work with two tables, orders and rev, consider conditional aggregation by moving WHERE conditions to CASE logic for single aggregate query. Also, consider only one CTE for all possible country/brand pairs for LEFT JOIN on the two tables.
WITH cb AS (
SELECT Country, Brand FROM orders
UNION
SELECT Country, Brand FROM rev
)
SELECT cb.Country
, cb.Brand
, SUM(o.netprice) AS OrdersNet
, SUM(CASE
WHEN o.isopen = 1
THEN o.netprice
END) AS OpenOrdersNet
, SUM(CASE
WHEN r.bdate BETWEEN '2020-12-01' AND '2020-12-31'
THEN r.netprice
END) AS Revenue
, SUM(CASE
WHEN r.bdate BETWEEN '2020-12-01' AND '2020-12-31'
THEN r.rpro
END) AS RawProceeds
, SUM(CASE
WHEN r.bdate BETWEEN '2020-11-01' AND '2020-11-30'
THEN r.netprice
END) AS RevenueCompare
, SUM(CASE
WHEN r.bdate BETWEEN '2020-11-01' AND '2020-11-30'
THEN r.rpro
END) AS RawProceedsCompare
FROM cb
LEFT JOIN orders o
ON cb.Country = o.Country
AND cb.Brand = o.Brand
LEFT JOIN rev r
ON cb.Country = r.Country
AND cb.Brand = r.Brand
GROUP BY cb.Country
, cb.Brand
SQL Fiddle
I have four tables. Here are the skeletons...
ACADEMIC_TBL
academic_id
academic_name
AFFILIATION_TBL
academic_id*
institution_id*
joined_date
leave_date
INSTITUTION_TBL
institution_id
institution_name
REVIEW_TBL
academic_id*
institution_id*
date_posted
review_score
Using these tables I need to find the academic (displaying their name, not ID) with the highest number of reviews and the institution name (not ID) they are currently affiliated with. I imagine this will need to be done using multiple sub-select scripts but I'm having trouble figuring out how to structure it.
this will work:
SELECT at.academic_name,
it.institution_name,
Max(rt.review_score),
from academic_tbl at,
affiliation_tbl afft,
institution_tbl it,
review_tbl rt
WHERE AT.academic_id=afft.academic_id
AND afft.institution_id=it.institution_id
AND afft.academic_id=rt.academic_id
GROUP BY at.academia_name,it.instituton_id
You need an aggregated query that JOINs all 4 tables to count how many reviews were performed by each academic.
Query :
SELECT
inst.institution_name,
aca.academic_name,
COUNT(*)
FROM
academic_tbl aca
INNER JOIN affiliation_tbl aff ON aff.academic_id = aca.academic_id
INNER JOIN institution_tbl inst ON inst.institution_id = aff.institution_id
INNER JOIN review_tbl rev ON rev.academic_id = aca.academic_id AND rev.institution_id = aff.institution_id
GROUP BY
inst.institution_name,
aca.academic_name,
inst.institution_id,
aca.academic_id
NB :
added the academic and institution id to the GROUP BY clause to prevent potential academics or institutions having the same name from being (wrongly) grouped together
if the same academic performed reviews for different institutions, then you will find one row for each academic / institution couple, which, if I understood you right, is what you want
Try this one:
select
inst.institution_name
, aca.academic_name
from
academic_tbl aca
, institution_tbl inst
, affiliation_tbl aff
, review_tbl rev
, (
select
max(rt.review_score) max_score
from
review_tbl rt
, affiliation_tbl aff_inn
where
rt.date_posted >= aff_inn.join_date
and rt.date_posted <= aff_inn.leave_date
and rt.academic_id = aff_inn.academic_id
and rt.institution_id = aff_inn.institution_id
)
agg
where
aca.academic_id = inst.academic_id
and inst.institution_id = aff.institution_id
and aff.institution_id = rev.institution_id
and aff.academic_id = rev.academic_id
and rev.date_posted >= aff.join_date
and rev.date_posted <= aff.leave_date
and rev.review_score = agg.max_score
;
It might return more than one academic, if there are more with the same score (maximum one).
scenario : I have Three Tables(Prisoners,AddPaymentTransaction,WithdrawPaymentTransation)
Date in Tables : i have 1 row of prisoner with PrisonerID=5 and two rows in both other table,
i have wrote query to return there data if any prisoner have add some payment in there account or with draw any payment from there payment on same day or on different dates etc.
here is my query :
select at.PrisonerID ,at.Amount as AAmount,at.Date as ADate,wt.Amount as WAmount,wt.Date as WDate
from Prisoners p, AddPaymentTransaction at,WithdrawPaymentTransation wt
where p.PrisonerID=at.PrisonerID and p.PrisonerID=wt.PrisonerID and at.PrisonerID=wt.PrisonerID and at.PrisonerID=5
but it gives me 4 rows, 9 rows when i have 3 rows of data in each Table etc.
i want rows of data with out duplicate. any suggestions or help will be highly appreciated.
It looks like at.PrisonerID = wt.PrisonerID in your query might be what is causing all of the duplicates. I am guessing AddPaymentTransaction and WithdrawPaymentTransation should not be linked together. So, how about the following:
SELECT at.PrisonerID, at.Amount as AAmount, at.Date as ADate,
wt.Amount as WAmount, wt.Date as WDate
FROM Prisoners p
INNER JOIN AddPaymentTransaction at p.PrisonerID = at.PrisonerID
INNER JOIN WithdrawPaymentTransation wt ON p.PrisonerID = wt.PrisonerID
WHERE at.PrisonerID = 5
but this probably isn't going to give you exactly what you are looking for either. So maybe something like the following:
SELECT * FROM
(
SELECT p.PrisonerID, 'AddPayment' AS Type,
apt.Amount as TransAmount, apt.Date AS TransDate
FROM Prisoners p
INNER JOIN AddPaymentTransaction apt ON p.PrisonerID = apt.PrisonerID
WHERE apt.PrisonerID = 5
UNION
SELECT p.PrisonerID, 'WithdrawPayment' AS Type,
wt.Amount as TransAmount, wt.Date as TransDate
FROM Prisoners p
INNER JOIN WithdrawPaymentTransation wt ON p.PrisonerID = wt.PrisonerID
WHERE wt.PrisonerID = 5
) AS mq
ORDER BY mq.TransDate DESC
I have a small challenge trying to create a "work in progress view"
I'm not convinced my statement is the best or correct and resulted in an error "Subquery returned more than 1 value"
I have three key tables;
Tasks
PurchaseOrderItem
Resource
There is a unique reference field across all the tables e.g. Tasks.TA_SEQ, PurchaseOrderItem.TA_SEQ and Resource.TA_SEQ
I need to sum different totals from all these tables and the relationship are as follows;
1 Task - many PurchaseOrderItem
1 Task - many Resources
I need to sum all the Purchase order cost values (line items can vary) against active purchase orders for the Task and also sum all the resource cost (3 people - quantity can vary) against the task, any help would be much appreciated. if I can make it also any easier any advice would be appreciated.
Part of my Query as it stands;
SELECT
dbo.F_TASKS.TA_SEQ,
(
SELECT
SUM(POI_TOTAL)
From F_PO_ITEM
where POI_FKEY_TA_SEQ = dbo.F_TASKS.TA_SEQ
and POI_FKEY_POH_SEQ in
(
select
POH_SEQ
from F_PO_HEAD
where POH_STATUS in ('DORMANT', 'ACTIVE')
)
) AS [Pending PO Cost],
dbo.F_TASKS.TA_PO_COST AS [PO Cost],
dbo.F_TASKS.TA_LABOUR_COST AS [Labour Cost],
dbo.F_TASKS.TA_LABOUR_COST - SUM(dbo.F_TASK_TIME.TT_OTHER_COSTS) AS [New Labour Cost],
-----------Not Working from
(select
SUM(dbo.F_TASK_TIME.TT_OTHER_COSTS)
from F_TASK_TIME
where TT_FKEY_TA_SEQ = dbo.F_TASKS.TA_SEQ) + dbo.F_TASKS.TA_PO_COST AS [Subcontractor Costs],
(SUM(dbo.F_TASK_TIME.TT_OTHER_COSTS + dbo.F_TASKS.TA_PO_COST)) * 0.12 AS [Subcontractor Uplift],
((SUM(dbo.F_TASK_TIME.TT_OTHER_COSTS + dbo.F_TASKS.TA_PO_COST)) * 0.12) + (SUM(dbo.F_TASK_TIME.TT_OTHER_COSTS + dbo.F_TASKS.TA_PO_COST)) AS [Subcontractor Uplift Total]
-----------Not Working To
FROM dbo.F_TASKS
LEFT OUTER JOIN dbo.F_TASK_TIME
ON dbo.F_TASKS.TA_SEQ = dbo.F_TASK_TIME.TT_FKEY_TA_SEQ
LEFT OUTER JOIN dbo.F_PO_ITEM
ON dbo.F_TASKS.TA_SEQ = dbo.F_PO_ITEM.POI_FKEY_TA_SEQ
WHERE (dbo.F_TASKS.TA_TASK_DESC = 'BREAKDOWN')
AND (dbo.F_TASKS.TA_PO_COST >= 0)
AND (dbo.F_TASKS.TA_STATUS IN ('ACTIVE', 'ASSIGNED', 'COMPLETE'))
GROUP BY dbo.F_TASKS.TA_PO_COST, dbo.F_TASKS.TA_SEQ, dbo.F_TASKS.TA_LABOUR_COST
Rather than trying to fix your SQL, I'm going to propose a different wau of doing it. I couldn';t easily understand all the wheres in your selects in the select clause, so I've just done the first two.
This approach uses LEFT OUTER JOINs to queries which total by ta_seq. These are guaranteed to return only one row/ta_seq as that's how there're grouped:
SELECT
t.TA_SEQ,
isnull(po.poi_total, 0) [Pending PO Cost],
t.TA_PO_COST AS [PO Cost],
t.TA_LABOUR_COST AS [Labour Cost],
t.TA_LABOUR_COST - isnull(tt.other_costs, 0) AS [New Labour Cost],
-- other cols missed
FROM dbo.F_TASKS t
left outer join
(
t.ta_seq, SUM(POI_TOTAL) poi_total
From F_PO_ITEM poi
where POI_FKEY_POH_SEQ in
(
select
POH_SEQ
from F_PO_HEAD
where POH_STATUS in ('DORMANT', 'ACTIVE')
)
group by t.ta_seq
) po on po.ta_seq = t.ta_seq
left outer join
(
select tt.TT_FKEY_TA_SEQ ta_seq, sum(tt.tt_other_costs) other_costs
from F_TASK_TIME tt
group by tt.TT_FKEY_TA_SEQ
) tt on tt.ta_seq = t.ta_seq
WHERE (t.TA_TASK_DESC = 'BREAKDOWN')
AND (t.TA_PO_COST >= 0)
AND (t.TA_STATUS IN ('ACTIVE', 'ASSIGNED', 'COMPLETE'))
GROUP BY t.TA_PO_COST, t.TA_SEQ, t.TA_LABOUR_COST
I've also used table aliases as I find the schema.tablename format is making me blind (and not helping me decode the missed subqueries).
To put in the missing columns, just translate them into additional LEFT OUTER JOINs as above.
Cheers -
I have a page in one of my client's websites that generates an extensive report pulling data from numerous tables throughout the website's MS Access database. One of the unfortunate architectural issues of the website is the existence of two nearly identical tables that represent the same "type" of data, but one is an "old" version and the other is a "new" version. When the report is generated I need to perform some aggregate operations on the two similar tables. The initial query joined these tables into the rest of the data and called the appropriate aggregate functions on the joined tables. Soon I realized that a join would not work because the two tables do not necessarily have the same row count, thus causing the aggregate function to improperly group the rows from both tables...
Were this MSSQL or MySQL I would probably create a VIEW containing the composite data from both tables, but unfortunately I'm stuck in MS Access where such "novel" concepts do not exist... The solution I was able to come up with works, but has got to be some of the ugliest SQL I have ever seen. Basically, I create a SQL query including all of the appropriate columns from multiple joined tables and one of the two similar tables. Then I create a second SQL query containing all of the same fields and join the other similar table. Finally, I UNION the two queries and wrap them into a subquery within the FROM clause of an outer query.
The end result is a massive query with a ton of duplicate selects that I included only because of the need to aggregate data from the two similar tables. I really would like to refactor the query into something less awful, but I'm not sure where to start... Any advice?
SELECT contractid,
pholderid,
policyholdername,
policyholdercity,
policyholderstate,
vehicleyear,
vehiclemake,
vehiclemodel,
Iif(claimmileage > vehiclemileage, claimmileage, vehiclemileage) AS mileage,
clientname,
contracttype,
contractmonths,
wholesaleprice,
begindate,
cancelleddate,
cancelledalphatotal,
paiddate,
voided,
Sum(claimscost) AS totalclaimscost,
Sum(claimscount) AS totalclaimscount,
DateAdd('m', contractmonths, begindate) AS expirationdate,
Iif(paiddate IS NOT NULL AND contractmonths > 0,
Iif(voided = true,
Iif(cancelleddate IS NOT NULL,
Iif(((cancelleddate - begindate) / (364.25 / 12)) >= contractmonths,
1,
((cancelleddate - begindate) / (364.25 / 12)) / contractmonths),
Iif(((Date() - begindate) / (364.25 / 12)) >= (contractmonths),
1,
((Date() - begindate) / (364.25 / 12)) / contractmonths)),
((Date() - begindate) / (364.25 / 12)) / contractmonths),
0) AS earnedfactor,
(earnedfactor * wholesaleprice) AS earnedpremium,
Iif(voided = true, 0, (wholesaleprice - earnedpremium)) AS unearnedpremium,
Iif(voided = true AND cancelledalphatotal IS NOT NULL, cancelledalphatotal, 0) AS refund,
Iif(earnedpremium > 0,totalclaimscost / earnedpremium, 0) AS lossratio
FROM (SELECT contracts.id AS contractid,
policyholders.id AS pholderid,
policyholders.firstname
+ ' '
+ policyholders.lastname AS policyholdername,
policyholders.city AS policyholdercity,
policyholders.state AS policyholderstate,
vehicles.yr AS vehicleyear,
vehicles.make AS vehiclemake,
vehicles.model AS vehiclemodel,
vehicles.mileage AS vehiclemileage,
clients.coname AS clientname,
contracttypes.name AS contracttype,
coverageavailable.contractmonths AS contractmonths,
contracts.contractwholesalecost AS wholesaleprice,
contracts.begindate AS begindate,
contracts.cancelledon AS cancelleddate,
contracts.cancelledalphatotal AS cancelledalphatotal,
contracts.paidon AS paiddate,
contracts.voided AS voided,
Sum(Iif(claims.totalrepaircost IS NULL,0,claims.totalrepaircost)) AS claimscost,
Count(claims.id) AS claimscount,
Max(Iif(claims.currentmileage IS NULL,0,claims.currentmileage)) AS claimmileage
FROM claims
RIGHT JOIN (coverageavailable
INNER JOIN ((((policyholders
INNER JOIN clients
ON policyholders.clientid = clients.id)
INNER JOIN contracts
ON policyholders.id = contracts.policyholderid)
INNER JOIN vehicles
ON contracts.vehicleid = vehicles.id)
INNER JOIN contracttypes
ON contracts.contracttypeid = contracttypes.id)
ON coverageavailable.id = contracts.termid)
ON claims.policyholderid = policyholders.id
WHERE contractmonths > 0
AND contracts.begindate IS NOT NULL
AND contracttypes.id <> 3
GROUP BY contracts.id,
policyholders.id,
policyholders.firstname,
policyholders.lastname,
policyholders.city,
policyholders.state,
vehicles.yr,
vehicles.make,
vehicles.model,
vehicles.mileage,
clients.coname,
contracttypes.name,
coverageavailable.contractmonths,
contracts.contractwholesalecost,
contracts.begindate,
contracts.cancelledon,
contracts.paidon,
contracts.voided,
contracts.cancelledalphatotal
UNION
SELECT contracts.id AS contractid,
policyholders.id AS pholderid,
policyholders.firstname
+ ' '
+ policyholders.lastname AS policyholdername,
policyholders.city AS policyholdercity,
policyholders.state AS policyholderstate,
vehicles.yr AS vehicleyear,
vehicles.make AS vehiclemake,
vehicles.model AS vehiclemodel,
vehicles.mileage AS vehiclemileage,
clients.coname AS clientname,
contracttypes.name AS contracttype,
coverageavailable.contractmonths AS contractmonths,
contracts.contractwholesalecost AS wholesaleprice,
contracts.begindate AS begindate,
contracts.cancelledon AS cancelleddate,
contracts.cancelledalphatotal AS cancelledalphatotal,
contracts.paidon AS paiddate,
contracts.voided AS voided,
Sum(Iif(claim.inspector1paidout IS NULL,0,claim.inspector1paidout))
+ Sum(Iif(claim.inspector2paidout IS NULL,0,claim.inspector2paidout))
+ Sum(Iif(claim.mechanicpaidout IS NULL,0,claim.mechanicpaidout))
+ Sum(Iif(claim.partdealerpaidout IS NULL,0,claim.partdealerpaidout)) AS claimscost,
Count(claim.id) AS claimscount,
Max(Iif(claim.mileage IS NULL,0,claim.mileage)) AS claimmileage
FROM claim
RIGHT JOIN (coverageavailable
INNER JOIN ((((policyholders
INNER JOIN clients
ON policyholders.clientid = clients.id)
INNER JOIN contracts
ON policyholders.id = contracts.policyholderid)
INNER JOIN vehicles
ON contracts.vehicleid = vehicles.id)
INNER JOIN contracttypes
ON contracts.contracttypeid = contracttypes.id)
ON coverageavailable.id = contracts.termid)
ON claim.contractid = contracts.id
WHERE contractmonths > 0
AND contracts.begindate IS NOT NULL
AND contracttypes.id <> 3
GROUP BY contracts.id,
policyholders.id,
policyholders.firstname,
policyholders.lastname,
policyholders.city,
policyholders.state,
vehicles.yr,
vehicles.make,
vehicles.model,
vehicles.mileage,
clients.coname,
contracttypes.name,
coverageavailable.contractmonths,
contracts.contractwholesalecost,
contracts.begindate,
contracts.cancelledon,
contracts.paidon,
contracts.voided,
contracts.cancelledalphatotal)
GROUP BY contractid,
pholderid,
policyholdername,
policyholdercity,
policyholderstate,
vehicleyear,
vehiclemake,
vehiclemodel,
vehiclemileage,
clientname,
contracttype,
contractmonths,
wholesaleprice,
begindate,
cancelleddate,
cancelledalphatotal,
paiddate,
voided,
Iif(claimmileage > vehiclemileage, claimmileage, vehiclemileage)
ORDER BY clientname,
begindate DESC
Hopefully all that makes at least some sense...
QueryDef in Access, is similar to a VIEW in other RDBMS.
Based on the first glance, it is better to get the UNION part of the query in a querydef.