MS Access - Query Refactoring Assistance - sql

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.

Related

Access Crosstab Query: based on sales totals within TWO date ranges

I'm looking for a way to create an Access crosstab query reporting sales totals by 'Brand', for two different date ranges.:
For Distributor: "DistID" (column, not visible)
Sales Totals: "Sales" (column)
TWO different date ranges: "depDate" for Period 1 and Period 2 (column):
Period1 = Between [forms]![frmRPT_YTDDepl_SF]![BDT1] And [forms]![frmRPT_YTDDepl_SF]![EDT1]
Period2 = Between [forms]![frmRPT_YTDDepl_SF]![BDT2] And [forms]![frmRPT_YTDDepl_SF]![EDT2]
Brands = "DprodBrand" (rows)
Currently, I have TWO separate crosstab queries for each period, working properly. -> CODE BELOW.
I am looking for a way to create ONE query displaying Brand's sales totals for each date range, in two separate columns or one crosstab query.
Period1:
TRANSFORM Sum(tblDepletions_DETAIL.detQuan) AS Sales
SELECT tblProducts_DEPL.DprodBrand
FROM tblDepletions INNER JOIN (tblProducts_DEPL INNER JOIN tblDepletions_DETAIL ON tblProducts_DEPL.DprodZSKU = tblDepletions_DETAIL.detZSKU) ON tblDepletions.depID = tblDepletions_DETAIL.detDeplID
WHERE (((tblDepletions.depDate) Between [forms]![frmRPT_YTDDepl_SF]![BDT1] And [forms]![frmRPT_YTDDepl_SF]![EDT1]) AND ((tblDepletions.depDistID)=132))
GROUP BY tblProducts_DEPL.DprodBrand
ORDER BY tblProducts_DEPL.DprodBrand
PIVOT Format([depDate],"yy")-(Format(Date(),"yy"))+2 In (1,2);
Period2:
TRANSFORM Sum(tblDepletions_DETAIL.detQuan) AS Sales
SELECT tblProducts_DEPL.DprodBrand
FROM tblDepletions INNER JOIN (tblProducts_DEPL INNER JOIN tblDepletions_DETAIL ON tblProducts_DEPL.DprodZSKU = tblDepletions_DETAIL.detZSKU) ON tblDepletions.depID = tblDepletions_DETAIL.detDeplID
WHERE (((tblDepletions.depDate) Between [forms]![frmRPT_YTDDepl_SF]![BDT2] And [forms]![frmRPT_YTDDepl_SF]![EDT2]) AND ((tblDepletions.depDistID)=132))
GROUP BY tblProducts_DEPL.DprodBrand
ORDER BY tblProducts_DEPL.DprodBrand
PIVOT Format([depDate],"yy")-(Format(Date(),"yy"))+2 In (1,2);
Many Thanks!!! ~~ Jacob
Consider simply joining the two saved, crosstab queries like any other pair of queries or tables using the DprodBrand as join key:
SELECT CrosstabQ1.DprodBrand,
CrosstabQ1.[1] As Period1_Year1, CrosstabQ2.[1] As Period2_Year1,
CrosstabQ1.[2] As Period1_Year2, CrosstabQ2.[2] As Period2_Year2
FROM CrosstabQ1
INNER JOIN CrosstabQ2 ON CrosstabQ1.DprodBrand = CrosstabQ2.DprodBrand
Now if you only want one query to do it all, consider the conditional aggregate pivot query since crosstabs cannot be used as subqueries. Here you migrate WHERE to IIF() conditions:
SELECT p.DprodBrand,
SUM(IIF((d.depDate BETWEEN [Forms]![frmRPT_YTDDepl_SF]![BDT1]
AND [Forms]![frmRPT_YTDDepl_SF]![EDT1])
AND (Format(d.[depDate],"yy")-(Format(Date(),"yy"))+2 = 1),
dt.detQuan, NULL)) AS Period1_Year1,
SUM(IIF((d.depDate BETWEEN [Forms]![frmRPT_YTDDepl_SF]![BDT2]
AND [Forms]![frmRPT_YTDDepl_SF]![EDT2)
AND (Format(d.[depDate],"yy")-(Format(Date(),"yy"))+2 = 1),
dt.detQuan, NULL)) AS Period2_Year1,
SUM(IIF((d.depDate BETWEEN [Forms]![frmRPT_YTDDepl_SF]![BDT1]
AND [Forms]![frmRPT_YTDDepl_SF]![EDT1])
AND (Format(d.[depDate],"yy")-(Format(Date(),"yy"))+2 = 2),
dt.detQuan, NULL)) AS Period1_Year2,
SUM(IIF((d.depDate BETWEEN [Forms]![frmRPT_YTDDepl_SF]![BDT2]
AND [Forms]![frmRPT_YTDDepl_SF]![EDT2])
AND (Format(d.[depDate],"yy")-(Format(Date(),"yy"))+2 = 2),
dt.detQuan, NULL)) AS Period2_Year2
FROM tblDepletions d
INNER JOIN (tblProducts_DEPL p
INNER JOIN tblDepletions_DETAIL dt
ON p.DprodZSKU = dt.detZSKU)
ON d.depID = dt.detDeplID
WHERE ((d.depDistID)=132)
GROUP BY p.DprodBrand
ORDER BY p.DprodBrand
As this is Access, it might be simpler to save the two queries leaving out the ORDER BY.
Then create a new query:
SELECT *
FROM Q1
UNION ALL
SELECT *
FROM Q2
ORDER BY DprodBrand
By: Dale Fye (Access MVP):
I'm not sure you need a CrossTab for this.
Select DProdBrand,
SUM(IIF([DepDate] BETWEEN [Forms]![frmRpt_YTDDepl_SF]![BDT1]
AND [[forms]![frmRPT_YTDDepl_SF]![EDT1], [Sales], 0) as Period1,
SUM(IIF([DepDate] Between [forms]![frmRPT_YTDDepl_SF]![BDT2]
AND [forms]![frmRPT_YTDDepl_SF]![EDT2], [Sales], 0) as Period2,
SUM([Sales]) as [Sales Total]
FROM yourTable
GROUP BY DProdBrand
https://www.experts-exchange.com/questions/28978325/Access-Crosstab-Query-based-on-sales-totals-within-TWO-date-ranges.html

Handle Complex Query

I have following tables with their columns
tbAgent :- Agent, AgentX, AgentCode, NIPRNumber, PhysicalAddressState,
SystemUser
tbBroker :- Broker, BusinessName, BrokerCode,SystemUser
tbCompany :- Company, CompanyX
tbSystemUser :- SystemUser FirstName, LastName, EmailAddress
tbProduct :- Product, ProductX, ProductCode, Jurisdiction, CompanyId
tbLicence :- Licence, LicenceNumber,DateIssued,ExpirationDate,Jurisdiction,
StateIssued, BrokerId, AgentId
tbCompanyAgent :- CompanyId, AgentId, ProductId, LicenseNumber,
LicenseIssueDate,LicenceExpirationDate
tbBrokerAgent :- BrokerId, AgentId
tbJurisdiction :- Jurisdiction, JurisdictionX
In this project, we store Agents, Agencies (Brokers) and Companies in tbAgent, tbBroker and tbCompany respectively. We store Company's Products in tbProduct.
Thr Agent's LicenseDetails are stored in tbLicence. Agent's are appointed to Agencies(Brokers) and these details are stored in tbBrokerAgent.
Also Agents are appointed to Companies and these details are stored in tbCompanyAgent. The Agents are appointed to Companies, if Company's product's Jurisdiction matched with the Agent's License's Resident State or Non Resident state.
Note that Agent's has two type of licences stored in tbLicence, one is Resident and other is Non Resident Licenses. If it is Resident License, then the column name "Jurisdiction" contains 0 and If it is Non Resident License, then it contain actual Jurisdiction Id of State. If it contains 0 then we have to consider Agent's PhysicalAddressState as ResidentState.
All jurisdictions (States) are present in tbJurisdiction.
Now I have to create a view where I have to fetch the following Information
CompanyX
CompanyCode
BrokerX
BrokerCode
AgentX
Agentcode
NIPRNumber
ProductX
ProductCode
State
LicenceNumber
EffectiveDate
ExpirationDate
I have tried the following query
SELECT a.AgentCode,sy.AgentName,L.Licence,L.LicenceNumber,DateIssued as EffectiveDate,L.ExpirationDate,J.JurisdictionX as State
From tbAgent as a
INNER JOIN tbLicence L ON L.AgentId=a.Agent
LEFT OUTER JOIN (SELECT Jurisdiction,JurisdictionX FROM tbJurisdiction) as j on j.Jurisdiction=
(
CASE WHEN ISNULL(L.Jurisdiction,'0')='0' THEN a.PhysicalAddressState
ELSE
L.Jurisdiction
END
)
LEFT OUTER JOIN (SELECT SystemUser, (FirstName + ' '+LastName) as AgentName FROM tbSystemUser ) as sy on sy.SystemUser=a.SystemUser
The above query is fetching the following information
AgentX
Agentcode
NIPRNumber
State
LicenceNumber
EffectiveDate
ExpirationDate
Excluding the following columns
CompanyX
CompanyCode
BrokerX
BrokerCode
ProductX
ProductCode
I am not able to tweak the above query for fetching the excluding Column's information because the query is getting complex to handle...
Please help me !!!
If the question is about complexity, I hope CTE-technique will be a good tip for you:
;WITH cteJur as
(
SELECT
Jurisdiction,
JurisdictionX
FROM tbJurisdiction j
),
cteSysUsr as
(
SELECT
SystemUser,
(FirstName + ' '+LastName) as AgentName
FROM tbSystemUser su
),
cteAgent as
(
SELECT
a.AgentCode, a.SystemUser,
L.Licence, L.LicenceNumber,
L.DateIssued as EffectiveDate, L.ExpirationDate,
CASE
WHEN ISNULL(L.Jurisdiction,'0')='0'
THEN a.PhysicalAddressState
ELSE L.Jurisdiction
END as Jurisdiction
FROM tbAgent as a
INNER JOIN tbLicence L ON L.AgentId=a.Agent
)
SELECT
a.AgentCode, sy.AgentName,
a.Licence, a.LicenceNumber,
a.EffectiveDate, a.ExpirationDate,
J.JurisdictionX as State
FROM tbAgent as a
LEFT JOIN cteJur as j on j.Jurisdiction = a.Jurisdiction
LEFT JOIN cteSysUsr as sy on sy.SystemUser = a.SystemUser
If you were looking where to include your "excluded columns" - add them into appropriate CTE and reference them in final select. You don't have to put every joined table into a subquery. Just join it and reference table's columns in select list, that's it. Just as described in the query above.
First, you appear to have a good following of the tables and how related. I have tried to implement them and get ALL columns from the respective table(s). You can strip out whatever you want.
Now, first, I want you to look at the FROM clause section. Think of this before getting the columns, especially in a complex query of a lot of tables being joined. Take each one to the next. I always try to do my joins with the first table (or alias) as the left-side of the ON clause and the JOINING TO as the right-side... Then, if something is nested under the second, I keep the indentation going so I see the literal correlations more directly and have less chance of getting confused.
from
FirstTable alias1
JOIN SecondTable alias2
on alias1.IDColumn = alias2.IDColumn
JOIN ThirdTable alias3
on alias2.OtherID = alias3.OtherID
Now, in the case of your Jurisdictions, there are 3 possible places it CAN originate from... The agent, product and the license. Because I do not know which version you specifically want, I applied LEFT-JOINs to each one respectively. This allows me to use the same table multiple times with different aliases. Then I grab each JurisdictionX and call it an appropriate "as" name in the result.
Finally, I build out all the field columns that are wanted. If you wanted to narrow the list of data (such as a single broker) then you just apply the WHERE criteria. Hopefully this makes a lot of sense and you can strip out the extra fields you may not care about.
SELECT
a.Agent,
a.AgentX,
a.AgentCode,
a.NIPRNumber,
a.PhysicalAddressState,
a.SystemUser,
( AgUser.FirstName + ' '+ AgUser.LastName) as AgentName,
AgUser.EmailAddress as AgentEMail,
b.Broker,
b.BusinessName,
b.BrokerCode,
b.SystemUser as BrokerUser,
( BrUser.FirstName + ' '+ BrUser.LastName) as BrokerName,
BrUser.EmailAddress as BrokerEMail,
l.License,
l.LicenseNumber,
l.DateIssued,
l.ExpirationDate,
l.Jurisdiction,
l.StateIssued,
ca.LicenseNumber as CA_LicenseNumber,
ca.LicenseIssueDate as LicenseIssueDate,
ca.LicenseExpirationDate as LicenseExpirationDate,
c.Company,
c.CompanyX,
p.ProductX,
p.ProductCode,
AgJuris.JurisdictionX as AgentJurisdiction,
LicJuris.Jurisdiction as LicenseJurisdiction,
ProdJuris.Jurisdiction as ProductJurisdiction
from
tbAgent a
JOIN tbSystemUser AgUser
ON a.SystemUser = ag.SystemUser
JOIN tbLicense l
ON a.Agent = l.AgentID
JOIN tbBroker B
ON l.BrokerID = B.BrokerID
JOIN tbSystemUser BrUser
ON b.SystemUser = br.SystemUser
LEFT JOIN tbJurisdiction LicJuris
ON ISNULL(L.Jurisdiction,'0') = LicJuris.Jurisdiction
JOIN tbCompanyAgent ca
ON a.Agent = ca.AgentID
JOIN tbCompany c
ON ca.CompanyID = c.Company
JOIN tbProduct p
ON ca.CompanyID = p.CompanyID
AND ca.ProductID = p.Product
LEFT JOIN tbJurisdiction ProdJuris
ON p.Jurisdiction = ProdJuris.Jurisdiction
LEFT JOIN tbJurisdiction AgJuris
ON a.PhysicalAddressState = AgJuris.Jurisdiction
Additionally, for the issue on Jurisdictions, since you have all 3 POSSIBLE, you could add a last column such as
COALESCE( LicJuris.Jurisdiction, AgJuris.JurisdictionX ) as WhichJurisdiction
or considering all 3...
COALESCE( LicJuris.Jurisdiction, COALESCE( ProdJuris.Jurisdiction , AgJuris.JurisdictionX )) as WhichJurisdiction
So, if the license jurisdiction is not available, grab the value from product jurisdiction, if not that, fall back to the agent's jurisdiction.

SQL View - Challenge

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 -

Show records where team assignment = 1

by changing the below TeamRecords = 1 to = another number finds the rows with the amount I change to, its only sometimes its counting one too many which is odd. When a new Incident is created it has a unique number and every time a new assignment is added from the Task table it adds another row of the IncidentNumber, so you could have duplicate Incident number rows which I've remove with the seq = 1 below. When a new assignment is created it creates a new CreateddateTime in the Task table so for example you could do a Max(t.[CreatedDateTime] to find the last assignment of any IncidentNumber. So, the TeamRecords = 1 is what I need to find all records for that specific team where there is only 1 assignment for that team.
Does that help any?
Here is what I have so far...
Use TEST
Go
WITH RankResult AS
(
SELECT i.[IncidentNumber],
i.[CreatedDateTime],
i.[ResolutionDateAndTime],
i.[Priority],
i.[Status],
i.[ClientName],
i.[ClientSite],
t.[OwnerTeam],
t.[Owner],
row_number() over( partition by i.RecID
order by t.CreatedDateTime desc, t.OwnerTeam ) seq,
TeamRecords = COUNT(*) OVER(PARTITION BY t.ParentLink_RecID)
FROM Incident as i
Inner JOIN Task as t
ON i.RecID = t.ParentLink_RecID
WHERE t.OwnerTeam = 'Infrastructure Services'
AND i.CreatedDateTime >= '20121001'
AND i.CreatedDateTime <= '20131001'
)
SELECT DISTINCT
[IncidentNumber],
[CreatedDateTime],
[ResolutionDateAndTime],
[Priority],
[Status],
[ClientName],
[ClientSite],
[OwnerTeam],
[Owner]
FROM RankResult
Where TeamRecords = 1
And Seq = 1
Order By IncidentNumber Asc
GO
Using ROW_NUMBER means you will return the first assignment per team, not necessarily the teams with only one assignment. To do this you can use COUNT(*) OVER():
WITH RankResult AS
(
SELECT i.[IncidentNumber],
i.[CreatedDateTime],
i.[ResolutionDateAndTime],
i.[Priority],
i.[Status],
i.[ClientName],
i.[ClientSite],
t.[OwnerTeam],
t.[Owner],
TeamRecords = COUNT(*) OVER(PARTITION BY i.RecID)
FROM Incident as i
INNER JOIN Task as t
ON i.RecID = t.ParentLink_RecID
WHERE t.OwnerTeam = 'Info Services'
AND i.CreatedDateTime >= '20121001'
AND i.CreatedDateTime <= '20131001'
)
SELECT DISTINCT
[IncidentNumber],
[CreatedDateTime],
[ResolutionDateAndTime],
[Priority],
[Status],
[ClientName],
[ClientSite],
[OwnerTeam],
[Owner]
FROM RankResult
WHERE TeamRecords = 1;
2 things to note that I have changed in addition to the analytic function. Firstly I have changed your dates to the culture independant format yyyyMMdd, yyyy-MM-dd can still be ambiguous, so 2013-01-02 could be the 1st Feb or the 2nd Jan depending on your server/session settings. Secondly, Your where cluase was turning your join into an INNER JOIN anyway, so I just made it an INNER JOIN:
FROM Incident as i
LEFT JOIN Task as t
ON i.RecID = t.ParentLink_RecID
WHERE t.OwnerTeam = 'Info Services'
AND i.CreatedDateTime >= '20121001'
Here, if there is no match in Task then OwnerTeam will be NULL and NULL = 'Info Services' evaluates to false, so you will never return any rows with no match in Task thus making it an INNER JOIN). If you did in fact want a LEFT JOIN then you need to move this clause to the JOIN:
FROM Incident as i
LEFT JOIN Task as t
ON i.RecID = t.ParentLink_RecID
AND t.OwnerTeam = 'Info Services'
WHERE i.CreatedDateTime >= '20121001'
You can always use a simple subquery which groups across the relevant columns, counts them, filters where the count is 1, then joins it back to the main table to select the appropriate rows:
SELECT Incident.*
FROM (
SELECT OwnerTeam
FROM Incident AS Inc1
GROUP BY OwnerTeam
HAVING COUNT( * ) = 1
) AS Team
, Incident
WHERE Incident.OwnerTeam = Team.OwnerTeam
(Without more information, though, it's difficult to say if this will work for you.)

Paid Amount Greater than Total Amount Paid

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.