I have a query that uses two SELECT statements that are combined using a UNION ALL. Both statements pull data from similar tables to populate the query results. I am attempting to remove the "semi-duplicate" rows from the query, but am having issues doing so.
My query is the following:
SELECT DISTINCT *
FROM
(
SELECT
TeamNum = CASE
WHEN T.TeamName = 'Alpha Team'
THEN '1'
WHEN T.TeamName IN ('Bravo Team', 'Charlie Team')
THEN '2'
WHEN T.TeamName = 'Delta Team'
THEN '3'
ELSE '<Undefined>'
END,
P.PatientLastName AS LastName,
P.PatientFirstName AS FirstName,
R.PrimaryCity AS City,
ReimbursorName = CASE
WHEN RE.ReimbursorDescription = 'Medicare'
Then 'R1'
WHEN RE.ReimbursorDescription = 'Medicaid'
Then 'R2'
ELSE 'R3'
END,
P.PatientID AS PatientID
FROM
PatReferrals PR LEFT JOIN Patient P ON PR.PatientID = P.PatientID,
Patient P LEFT OUTER JOIN Rolodex R ON P.RolodexID = R.RolodexID,
PatReferrals PR LEFT OUTER JOIN PatReimbursors PRE ON PR.PatientID = PRE.PatientID,
PatReimbursors PRE LEFT OUTER JOIN Reimbursors RE ON PRE.ReimbursorID = RE.ReimbursorID,
PatReferrals PR FULL OUTER JOIN Teams T ON PR.TeamID = T.TeamID,
WHERE
PR.ReferralDate BETWEEN GETDATE()-4 AND GETDATE()-1
AND PR.Status <> 'R'
AND PRE.CoveragePriority = '1'
AND PRE.ExpirationDate IS NULL
UNION ALL
SELECT
TeamNum = CASE
WHEN T.TeamName = 'Alpha Team'
THEN '1'
WHEN T.TeamName IN ('Bravo Team', 'Charlie Team')
THEN '2'
WHEN T.TeamName = 'Delta Team'
THEN '3'
ELSE '<Undefined>'
END,
P.PatientLastName AS LastName,
P.PatientFirstName AS FirstName,
R.PrimaryCity AS City,
ReimbursorName = CASE
WHEN RE.ReimbursorDescription = 'Medicare'
Then 'E1'
WHEN RE.ReimbursorDescription = 'Medicaid'
Then 'E2'
ELSE 'E3'
END,
P.PatientID AS PatientID
FROM
PatReferrals PR LEFT JOIN Patient P ON PR.PatientID = P.PatientID,
Patient P LEFT OUTER JOIN Rolodex R ON P.RolodexID = R.RolodexID,
PatReferrals PR LEFT OUTER JOIN PatEligibilities PE ON PR.PatientID = PE.PatientID,
PatEligibilities PE LEFT OUTER JOIN Reimbursors RE ON PE.ReimbursorID = RE.ReimbursorID,
PatReferrals PR FULL OUTER JOIN Teams T ON PR.TeamID = T.TeamID,
WHERE
PR.ReferralDate BETWEEN GETDATE()-4 AND GETDATE()-1
AND PR.Status <> 'R'
AND PE.Status <> 'V'
AND PE.ApplicationDate BETWEEN DATE(PR.ReferralDate)-5 AND DATE('2100/01/01')
)
AS DUMMYTBL
ORDER BY
DUMMYTBL.LastName ASC,
DUMMYTBL.FirstName ASC
The results that I receive when I run the query is the following:
3 Doe Jane Town R1 19874
1 Roe John City R3 50016
1 Roe John City E1 50016
2 Smith Jane Town E3 33975
The data that I am needing to remove is duplicate rows based on a certain criteria once the results are brought in from the original query. Each person can only be listed once and they must have a single pay source (R1, R2, R3, E1, E2, E3). If there is a R#, than there cannot be a E# listed for that person. If there are no R#'s than an E# must be listed. As shown in my example results, line 2 and 3 have the same person listed, but two pay sources (R3 and E1).
How can I go about making each person have only one row shown using the criteria that I have listed?
EDIT: Modifed the SQL query to show the original variables from the WHERE clauses in order to show further detail on the query. The PatReimbursors and the PatEligibilities tables have similar data, but the criteria is different in order to pull the correct data.
Your query does not make sense. I would start by eliminating the implicit cartesian product, generated by the , in the from clause.
My guess is that the from clause should be:
FROM
PatReferrals PR LEFT JOIN
Patient P
ON PR.PatientID = P.PatientID left outer join
Rolodex R
ON P.RolodexID = R.RolodexID left outer join
PatEligibilities PE
ON PR.PatientID = PE.PatientID left outer join
Reimbursors RE
ON PE.ReimbursorID = RE.ReimbursorID left outer join
Teams T ON PR.TeamID = T.TeamID
Once you do this, you may not need the union all or the select distinct. You may be able to put both the reimbursors and the eligibilities in the same query.
Use a subquery or subqueries.
The overall query should be written using the following pattern:
Select Distinct [Person Data]
From PersonTable
left Join to otherTable1 -- add outer join for each table you need data from
On [Conditions that ensure join can generate only one row per person,
... and specify which of possibly many rows to get...]
Make sure the conditions eliminate any possibility for the join to generate more than one row from the other [outer] table per person row in in the person table,. This may (and often does) require that the join condition be based on a subquery, as, for example...
Select Distinct [Person Data]
From PersonTable p
left Join to employments e -- add outer join for each table you need data from
On e.PersonId = p.PersonId
and e.HireDate = (Select Max(hiredate) from employments
where personId = p.PersonId)
After working with this for quite some time today, I found a solution to the problem that I was having. Here is the solution that works and pulls the correct information that I was needing:
SELECT DISTINCT
TeamNum,
LastName,
FirstName,
City,
ReimbursorName = CASE
WHEN max(ReimbursorName) IN ('R1', 'E1')
THEN '1'
WHEN max(ReimbursorName) IN ('R2', 'E2')
THEN '2'
ELSE '3'
END,
PatientID
FROM
(
SELECT
TeamNum = CASE
WHEN T.TeamName = 'Alpha Team'
THEN '1'
WHEN T.TeamName IN ('Bravo Team', 'Charlie Team')
THEN '2'
WHEN T.TeamName = 'Delta Team'
THEN '3'
ELSE '<Undefined>'
END,
P.PatientLastName AS LastName,
P.PatientFirstName AS FirstName,
R.PrimaryCity AS City,
ReimbursorName = CASE
WHEN RE.ReimbursorDescription = 'Medicare'
Then 'R1'
WHEN RE.ReimbursorDescription = 'Medicaid'
Then 'R2'
ELSE 'R3'
END,
P.PatientID AS PatientID
FROM
PatReferrals PR LEFT JOIN Patient P ON PR.PatientID = P.PatientID,
Patient P LEFT OUTER JOIN Rolodex R ON P.RolodexID = R.RolodexID,
PatReferrals PR LEFT OUTER JOIN PatReimbursors PRE ON PR.PatientID = PRE.PatientID,
PatReimbursors PRE LEFT OUTER JOIN Reimbursors RE ON PRE.ReimbursorID = RE.ReimbursorID,
PatReferrals PR FULL OUTER JOIN Teams T ON PR.TeamID = T.TeamID
WHERE
PR.ReferralDate BETWEEN GETDATE()-4 AND GETDATE()-1
AND PR.Status <> 'R'
AND PRE.CoveragePriority = '1'
AND PRE.ExpirationDate IS NULL
UNION ALL
SELECT
TeamNum = CASE
WHEN T.TeamName = 'Alpha Team'
THEN '1'
WHEN T.TeamName IN ('Bravo Team', 'Charlie Team')
THEN '2'
WHEN T.TeamName = 'Delta Team'
THEN '3'
ELSE '<Undefined>'
END,
P.PatientLastName AS LastName,
P.PatientFirstName AS FirstName,
R.PrimaryCity AS City,
ReimbursorName = CASE
WHEN RE.ReimbursorDescription = 'Medicare'
Then 'E1'
WHEN RE.ReimbursorDescription = 'Medicaid'
Then 'E2'
ELSE 'E3'
END,
P.PatientID AS PatientID
FROM
PatReferrals PR LEFT JOIN Patient P ON PR.PatientID = P.PatientID,
Patient P LEFT OUTER JOIN Rolodex R ON P.RolodexID = R.RolodexID,
PatReferrals PR LEFT OUTER JOIN PatEligibilities PE ON PR.PatientID = PE.PatientID,
PatEligibilities PE LEFT OUTER JOIN Reimbursors RE ON PE.ReimbursorID = RE.ReimbursorID,
PatReferrals PR FULL OUTER JOIN Teams T ON PR.TeamID = T.TeamID
WHERE
PR.ReferralDate BETWEEN GETDATE()-4 AND GETDATE()-1
AND PR.Status <> 'R'
AND PE.Status <> 'V'
AND PE.ApplicationDate BETWEEN DATE(PR.ReferralDate)-5 AND DATE('2100/01/01')
)
AS DUMMYTBL
GROUP BY
TeamNum,
LastName,
FirstName,
City,
PatientID
ORDER BY
DUMMYTBL.LastName ASC,
DUMMYTBL.FirstName ASC
Thanks for all the responses that were provided.
Related
Let's assume we have a table Instrument with child tables Equity and Bond having a foreign key InstrumentId. Each instrument has a unique record in one of the child tables.
Is it possible to make a view using left joins to see all the instrument with a column containing the table name in which the record is present ?
SELECT Instrument.InstrumentId, Instrument.Name, ***CHILD_TABLE_NAME***
FROM Instrument
LEFT OUTER JOIN
Equity ON Equity.InstrumentId = Instrument.InstrumentId
LEFT OUTER JOIN
Bond ON SBond.InstrumentId = Instrument.InstrumentId
An alternative is to make an union of inner joins:
SELECT instrumentId, Name, instrumentType
FROM
(SELECT Instrument.instrumentId, Name, 'Equity' as instrumentType FROM dbo.Equity inner join Instrument on Instrument.InstrumentId = Equity.InstrumentId
UNION
SELECT Instrument.instrumentId, Name, 'Bond' as instrumentType from dbo.Bond inner join Instrument on Instrument.InstrumentId = Bond.InstrumentId) u
one option is to include the table name in your joins like this
SELECT i.InstrumentId,
i.Name,
e.TableEquity,
b.TableBond
FROM Instrument i
LEFT OUTER JOIN (select 'Equity' as TableEquity from Equity) e
ON i.InstrumentId = e.InstrumentId
LEFT OUTER JOIN (select 'Bond' as TableBond from Bond) b
ON i.InstrumentId = b.InstrumentId
EDIT by #sofsntp : to merge the Equity/Bond in one column
SELECT i.InstrumentId,
i.Name,
(ISNULL(e.TableEquity,'') + ISNULL(b.TableBond ,''))
FROM Instrument i
LEFT OUTER JOIN (select *, 'Equity' as TableEquity from Equity) e
ON e.InstrumentId = i.InstrumentId
LEFT OUTER JOIN (select *, 'Bond' as TableBond from StraightBond) b
ON b.InstrumentId = i.InstrumentId
Use a case expression:
SELECT i.InstrumentId, i.Name,
(CASE WHEN e.InstrumentId IS NOT NULL THEN 'Equity'
WHEN b.InstrumentId IS NOT NULL THEN 'Bond'
END) as which_table
FROM Instrument i LEFT OUTER JOIN
Equity e
ON e.InstrumentId = i.InstrumentId LEFT OUTER JOIN
Bond b
ON b.InstrumentId = i.InstrumentId ;
Note: This gives the first match. If you want both:
SELECT i.InstrumentId, i.Name,
((CASE WHEN e.InstrumentId IS NOT NULL THEN 'Equity' ELSE '' END) +
(CASE WHEN b.InstrumentId IS NOT NULL THEN 'Bond' ELSE '' END)
) as which_table
FROM Instrument i LEFT OUTER JOIN
Equity e
ON e.InstrumentId = i.InstrumentId LEFT OUTER JOIN
Bond b
ON b.InstrumentId = i.InstrumentId ;
EDIT
I am adding END which was missing
I have the following query that counts members:
`SELECT
distinct count(cst_recno) AS [Member ID],
adr_country AS Country
FROM
mb_membership
JOIN mb_member_type on mbt_key = mbr_mbt_key
JOIN co_customer ON cst_key=mbr_cst_key and mbr_delete_flag =0 and
cst_delete_flag=0
LEFT JOIN co_individual ON cst_key=ind_cst_key and ind_delete_flag=0
LEFT JOIN co_customer_x_customer ON cxc_cst_key_1 = co_customer.cst_key and
(cxc_end_date is null or datediff(dd,getdate(),cxc_end_date) >=0) and
cxc_rlt_code='Chapter Member'
LEFT JOIN co_chapter ON cxc_cst_key_2=chp_cst_key
LEFT JOIN co_customer_x_address ON cst_cxa_key=cxa_key
LEFT JOIN co_address ON adr_key=cxa_adr_key
LEFT JOIN co_country on adr_country=cty_code
LEFT JOIN co_region on rgn_key=cty_rgn_key
LEFT JOIN vw_client_uli_member_type WITH (NOLOCK) ON cst_key=mem_cst_key
WHERE mbr_join_date >= '7/1/2015' and mbt_code not like '%Council%'
AND ind_int_code <> 'staff' and cst_org_name_dn not like '%urban land ins%'
and cst_eml_address_dn not like '%#uli.org'
and adr_country ='singapore'
group by adr_country`
and the query returns:
Member ID Country
145 Singapore
However, I know that it includes a few duplicates because when I take out a count function and don't have a group by clause it returns 140 distinct rows.
When I check why it includes a few dupes it is caused by one of the dates.
Can you advise? I basically want to run the query that will display 140 distinct count of Member ID:
Member ID Country
140 Singapore
Instead of SELECT distinct count(cst_recno)... use SELECT count(distinct cst_recno)...:
SELECT
count(distinct cst_recno) AS [Member ID],
adr_country AS Country
FROM
mb_membership
JOIN mb_member_type on mbt_key = mbr_mbt_key
JOIN co_customer ON cst_key=mbr_cst_key and mbr_delete_flag =0 and
cst_delete_flag=0
LEFT JOIN co_individual ON cst_key=ind_cst_key and ind_delete_flag=0
LEFT JOIN co_customer_x_customer ON cxc_cst_key_1 = co_customer.cst_key and
(cxc_end_date is null or datediff(dd,getdate(),cxc_end_date) >=0) and
cxc_rlt_code='Chapter Member'
LEFT JOIN co_chapter ON cxc_cst_key_2=chp_cst_key
LEFT JOIN co_customer_x_address ON cst_cxa_key=cxa_key
LEFT JOIN co_address ON adr_key=cxa_adr_key
LEFT JOIN co_country on adr_country=cty_code
LEFT JOIN co_region on rgn_key=cty_rgn_key
LEFT JOIN vw_client_uli_member_type WITH (NOLOCK) ON cst_key=mem_cst_key
WHERE mbr_join_date >= '7/1/2015' and mbt_code not like '%Council%'
AND ind_int_code <> 'staff' and cst_org_name_dn not like '%urban land ins%'
and cst_eml_address_dn not like '%#uli.org'
and adr_country ='singapore'
group by adr_country`
I've got a group of tables in SQL Server that I need to count on with specific counting criteria for each table, the problem I'm having that I need to group this by users, which are contained in one table and are mapped to the tables I need to count on via a relationship table.
This is the relationship table
Relationship User Work Item
Analyst 1 IR1
Analyst 2 IR2
Analyst 2 IR3
Analyst 1 IR4
User 3 IR1
Analyst 1 SR2
Analyst 1 SR3
Analyst 2 SR4
This is the IR table (the SR table is identical)
ID Status
IR1 Active
IR2 Active
IR3 Closed
IR4 Active
This is the user table
User Name
1 Dave
2 Jim
3 Karl
What I need is a table like below counting only the active items
Name IR Count SR Count
Dave 2 2
Jim 1 1
All I seem to be able to do currently is count all of the users regardless of status, I think this may be due to the left joins. I basically had:
Select u.name,
count (ir),
count (sr) from user u
Inner join relationship r on r.user=u.user and r.relationship = 'Analyst'
Left Join IR on r.workitem=ir.id and ir.Status = 'Active'
Left Join SR on r.workitem=sr.id and sr.Status = 'Active'
Group by u.name
I have simplified the above as much as possible. This is the actual query:
SELECT
u.DisplayName as Analyst,
u.BaseManagedEntityId as AUsername,
COUNT(distinct i.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) AS 'Active Incidents',
COUNT(distinct sr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Service Requests',
COUNT(distinct cr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Change Requests',
COUNT(distinct ma.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Manual Activities'
FROM MTV_System$Domain$User u
INNER JOIN RelationshipView r ON r.TargetEntityId = u.BaseManagedEntityId AND r.RelationshipTypeId = '15E577A3-6BF9-6713-4EAC-BA5A5B7C4722' AND r.IsDeleted ='0'
LEFT JOIN MTV_System$WorkItem$Incident i ON r.SourceEntityId = i.BaseManagedEntityId AND (i.Status_785407A9_729D_3A74_A383_575DB0CD50ED != '2B8830B6-59F0-F574-9C2A-F4B4682F1681' AND i.Status_785407A9_729D_3A74_A383_575DB0CD50ED != 'BD0AE7C4-3315-2EB3-7933-82DFC482DBAF')
LEFT JOIN MTV_System$WorkItem$ServiceRequest sr ON r.SourceEntityId = SR.BaseManagedEntityId AND (sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F = '72B55E17-1C7D-B34C-53AE-F61F8732E425' OR sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F = '59393F48-D85F-FA6D-2EBE-DCFF395D7ED1' OR sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F = '05306BF5-A6B9-B5AD-326B-BA4E9724BF37')
LEFT JOIN MTV_System$WorkItem$ChangeRequest cr on r.SourceEntityId = cr.BaseManagedEntityId AND (cr.Status_72C1BC70_443C_C96F_A624_A94F1C857138 = '6D6C64DD-07AC-AAF5-F812-6A7CCEB5154D' or cr.Status_72C1BC70_443C_C96F_A624_A94F1C857138 = 'DD6B0870-BCEA-1520-993D-9F1337E39D4D')
LEFT JOIN MTV_System$WorkItem$Activity$ManualActivity MA on r.SourceEntityId = ma.BaseManagedEntityId AND (ma.Status_8895EC8D_2CBF_0D9D_E8EC_524DEFA00014 = '11FC3CEF-15E5-BCA4-DEE0-9C1155EC8D83' OR ma.Status_8895EC8D_2CBF_0D9D_E8EC_524DEFA00014 = 'D544258F-24DA-1CF3-C230-B057AAA66BED')
GROUP BY u.DisplayName,u.BaseManagedEntityId
Order by u.DisplayName
your over simplification seems to have lost your what appears to be your issue from some of your comments. Using left joins would include any of the users even if they don't have a count of one of your other tables. However if you want your result set to only include usres that have at least 1 Incident and/or 1 Request and/or 1 Change Request. Etc. you can either filter the aggretation you are doing after the fact to remove when Incidents + Requests + ... = 0. Or you can filter them out by adding a WHERE statement that says WHEN NOT all of those other tables are null which is the same as OR IS NOT NULL...
SELECT
u.DisplayName as Analyst,
u.BaseManagedEntityId as AUsername,
COUNT(distinct i.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) AS 'Active Incidents',
COUNT(distinct sr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Service Requests',
COUNT(distinct cr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Change Requests',
COUNT(distinct ma.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Manual Activities'
FROM
MTV_System$Domain$User u
INNER JOIN RelationshipView r
ON r.TargetEntityId = u.BaseManagedEntityId
AND r.RelationshipTypeId = '15E577A3-6BF9-6713-4EAC-BA5A5B7C4722'
AND r.IsDeleted ='0'
LEFT JOIN MTV_System$WorkItem$Incident i
ON r.SourceEntityId = i.BaseManagedEntityId
AND i.Status_785407A9_729D_3A74_A383_575DB0CD50ED NOT IN ('2B8830B6-59F0-F574-9C2A-F4B4682F1681','BD0AE7C4-3315-2EB3-7933-82DFC482DBAF')
LEFT JOIN MTV_System$WorkItem$ServiceRequest sr
ON r.SourceEntityId = SR.BaseManagedEntityId
AND sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F IN ('72B55E17-1C7D-B34C-53AE-F61F8732E425','59393F48-D85F-FA6D-2EBE-DCFF395D7ED1','05306BF5-A6B9-B5AD-326B-BA4E9724BF37')
LEFT JOIN MTV_System$WorkItem$ChangeRequest cr
ON r.SourceEntityId = cr.BaseManagedEntityId
AND cr.Status_72C1BC70_443C_C96F_A624_A94F1C857138 IN ('6D6C64DD-07AC-AAF5-F812-6A7CCEB5154D','DD6B0870-BCEA-1520-993D-9F1337E39D4D')
LEFT JOIN MTV_System$WorkItem$Activity$ManualActivity MA
ON r.SourceEntityId = ma.BaseManagedEntityId
AND ma.Status_8895EC8D_2CBF_0D9D_E8EC_524DEFA00014 IN ('11FC3CEF-15E5-BCA4-DEE0-9C1155EC8D83','D544258F-24DA-1CF3-C230-B057AAA66BED')
WHERE
i.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C IS NOT NULL
OR sr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C IS NOT NULL
OR cr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C IS NOT NULL
OR ma.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C IS NOT NULL
GROUP BY u.DisplayName,u.BaseManagedEntityId
Order by u.DisplayName
Also note the user of IN and NOT IN in the join conditions instead of OR all of the time.
The issue is count(). Instead, you want count(distinct):
Select u.name,
count(distinct ir),
count(distinct sr)
from user u
. . .
This generates a Cartesian product between the ir and sr values. If you have largish numbers in each group, then aggregating before the join is a better approach.
;WITH T AS
(
SELECT
U.UserID,
U.Name,
CASE WHEN R.WorkItem LIKE 'IR%' THEN R.WorkItem ELSE '' END AS IRCode,
CASE WHEN R.WorkItem LIKE 'SR%' THEN R.WorkItem ELSE '' END AS SRCode
FROM #tblUser U
INNER JOIN #tblRelationship R ON U.UserId=R.UserId
)
SELECT
Name,
SUM(CASE IRCode WHEN '' THEN 0 ELSE 1 END) AS 'IR Count',
SUM(CASE SRCode WHEN '' THEN 0 ELSE 1 END) AS 'SR Count'
FROM T
WHERE
(
(T.IRCode=''
OR
T.SRCode='')
AND
(
T.IRCode IN (SELECT ID FROM #tblIR WHERE Status='Active')
OR
T.SRCode IN (SELECT ID FROM #tblSR WHERE Status='Active')
)
)
GROUP BY T.Name
Try with the below script .
SELECT u.name
,SUM(t1.[IR Count]) [IR Count]
,SUM(t2.[SR Count]) [SR Count]
FROM #user u
INNER JOIN #relationship r on r.[user]=u.[user]and r.relationship = 'Analyst'
CROSS APPLY (SELECT COUNT(DISTINCT ID) [IR Count]
FROM #IR ir WHERE r.workitem=ir.id and ir.Status = 'Active') t1
CROSS APPLY (SELECT COUNT(DISTINCT ID) [SR Count]
FROM #SR sr WHERE r.workitem=sr.id and sr.Status = 'Active')t2
GROUP BY u.name
OUTPUT :
SR Count in your sample output is wrong ,if the SR table is same as that of IR table (Status of the SR3 is closed for the user 'dave' so that will be ignored.) .
This is what I've come up with that seems to work based off the actual table
SELECT
u.DisplayName as Analyst,
u.BaseManagedEntityId as AUsername,
COUNT(distinct i.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) AS 'Active Incidents',
COUNT(distinct sr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Service Requests',
COUNT(distinct cr.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Change Requests',
COUNT(distinct ma.Id_9A505725_E2F2_447F_271B_9B9F4F0D190C) as 'Active Manual Activities'
FROM MTV_System$Domain$User u
LEFT JOIN RelationshipView r ON r.TargetEntityId = u.BaseManagedEntityId AND r.RelationshipTypeId = '15E577A3-6BF9-6713-4EAC-BA5A5B7C4722' AND r.IsDeleted ='0'
LEFT JOIN MTV_System$WorkItem$Incident i ON r.SourceEntityId = i.BaseManagedEntityId
LEFT JOIN MTV_System$WorkItem$ServiceRequest sr ON r.SourceEntityId = SR.BaseManagedEntityId
LEFT JOIN MTV_System$WorkItem$ChangeRequest cr on r.SourceEntityId = cr.BaseManagedEntityId
LEFT JOIN MTV_System$WorkItem$Activity$ManualActivity MA on r.SourceEntityId = ma.BaseManagedEntityId
Where (i.Status_785407A9_729D_3A74_A383_575DB0CD50ED != '2B8830B6-59F0-F574-9C2A-F4B4682F1681' AND i.Status_785407A9_729D_3A74_A383_575DB0CD50ED != 'BD0AE7C4-3315-2EB3-7933-82DFC482DBAF')
OR (sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F = '72B55E17-1C7D-B34C-53AE-F61F8732E425' OR sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F = '59393F48-D85F-FA6D-2EBE-DCFF395D7ED1' OR sr.Status_6DBB4A46_48F2_4D89_CBF6_215182E99E0F = '05306BF5-A6B9-B5AD-326B-BA4E9724BF37')
OR (cr.Status_72C1BC70_443C_C96F_A624_A94F1C857138 = '6D6C64DD-07AC-AAF5-F812-6A7CCEB5154D' or cr.Status_72C1BC70_443C_C96F_A624_A94F1C857138 = 'DD6B0870-BCEA-1520-993D-9F1337E39D4D')
OR (ma.Status_8895EC8D_2CBF_0D9D_E8EC_524DEFA00014 = '11FC3CEF-15E5-BCA4-DEE0-9C1155EC8D83' OR ma.Status_8895EC8D_2CBF_0D9D_E8EC_524DEFA00014 = 'D544258F-24DA-1CF3-C230-B057AAA66BED')
GROUP BY u.DisplayName,u.BaseManagedEntityId
Order by u.DisplayName
I have a query that I need to update to allow user to filter out pending applications. I have created the parameter and tried to implement using case but it is not working or giving any error messages on how to correct it. The code is:
select distinct pers.person_fname,
pers.person_mname,
pers.person_lname,
le.nationalprovidernumber NPN,
lic.licensenumber LICENSE_NUMBER,
adr.address_line1 ADDRESS1,
adr.address_line2 ADDRESS2,
adr.address_line3 ADDRESS3,
adr.city CITY,
sp.state_province_name STATE,
adr.postal_code ZIP_CODE,
eml.email,
rtp.residencetype_name RESIDENCY,
ltp.licensetype_name LICENSE_TYPE,
lic.expirationdate DATE_OF_EXPIRATION
from odilic_admin.license lic
inner join odilic_admin.licenseststimeline lst
on lic.license_id = lst.license_id
inner join odilic_admin.licenseststype lstp
on lst.licenseststype_id = lstp.licenseststype_id
inner join odilic_admin.licensedef ldef
on lic.licensedef_id = ldef.licensedef_id
inner join odilic_admin.licensetype ltp
on ldef.licensetype_id = ltp.licensetype_id
inner join odilic_admin.residencetype rtp
on ldef.residencetype_id = rtp.residencetype_id
inner join odilic_admin.licensingentity le
on lic.licensingentity_id = le.licensingentity_id
inner join odilic_admin.individual ind
on le.licensingentity_id = ind.licensingentity_id
inner join odidir_admin.person pers
on ind.person_id = pers.person_id
left outer join odidir_admin.person_address_rel par
on pers.person_id = par.person_id
left outer join odidir_admin.address adr
on par.address_id = adr.address_id
left outer join odidir_admin.address_type atp
on adr.address_type_id = atp.address_type_id
left outer join odidir_admin.state_province sp
on adr.state_province_id = sp.state_province_id
left outer join
(select pr.person_id, em.email_id, em.email
from odidir_admin.person pr,
odidir_admin.person_email_rel pe,
odidir_admin.email em
where pr.person_id = pe.person_id
and pe.email_id = em.email_id
and email_type_id = 2) eml
on pers.person_id = eml.person_id
where
ltp.licensetype_id in (:License_type)
and lstp.licenseststype_name = 'Active'
and atp.address_type_name = 'Mailing Licensing'
and (lic.expirationdate >= current_date and
trunc(lic.expirationdate) = :Expiration_Date)
and sysdate between lst.periodbegindate and lst.periodenddate
order by lic.licensenumber
In order to get applications that are pending I need to access the table odilic_admin.licenseappl and filter out all licenses with appststype = 2 (pending). To do this I added a join to the query before the last left outer join andt hen a case at bottom for when this parameter is selected.
select distinct pers.person_fname,
pers.person_mname,
pers.person_lname,
le.nationalprovidernumber NPN,
lic.licensenumber LICENSE_NUMBER,
adr.address_line1 ADDRESS1,
adr.address_line2 ADDRESS2,
adr.address_line3 ADDRESS3,
adr.city CITY,
sp.state_province_name STATE,
adr.postal_code ZIP_CODE,
eml.email,
rtp.residencetype_name RESIDENCY,
ltp.licensetype_name LICENSE_TYPE,
lic.expirationdate DATE_OF_EXPIRATION
from odilic_admin.license lic
inner join odilic_admin.licenseststimeline lst
on lic.license_id = lst.license_id
inner join odilic_admin.licenseststype lstp
on lst.licenseststype_id = lstp.licenseststype_id
inner join odilic_admin.licensedef ldef
on lic.licensedef_id = ldef.licensedef_id
inner join odilic_admin.licensetype ltp
on ldef.licensetype_id = ltp.licensetype_id
inner join odilic_admin.residencetype rtp
on ldef.residencetype_id = rtp.residencetype_id
inner join odilic_admin.licensingentity le
on lic.licensingentity_id = le.licensingentity_id
inner join odilic_admin.individual ind
on le.licensingentity_id = ind.licensingentity_id
inner join odidir_admin.person pers
on ind.person_id = pers.person_id
left outer join odidir_admin.person_address_rel par
on pers.person_id = par.person_id
left outer join odidir_admin.address adr
on par.address_id = adr.address_id
left outer join odidir_admin.address_type atp
on adr.address_type_id = atp.address_type_id
left outer join odidir_admin.state_province sp
on adr.state_province_id = sp.state_province_id
**left outer join odilic_admin.licenseappl appl
on lic.licensingentity_id = appl.licenseappl_id**
left outer join
(select pr.person_id, em.email_id, em.email
from odidir_admin.person pr,
odidir_admin.person_email_rel pe,
odidir_admin.email em
where pr.person_id = pe.person_id
and pe.email_id = em.email_id
and email_type_id = 2) eml
on pers.person_id = eml.person_id
where
ltp.licensetype_id in (:License_type)
and lstp.licenseststype_name = 'Active'
and atp.address_type_name = 'Mailing Licensing'
and (lic.expirationdate >= current_date and
trunc(lic.expirationdate) = :Expiration_Date)
and sysdate between lst.periodbegindate and lst.periodenddate
**case :pending when = yes then appl.applststype_id !=2
end**
order by lic.licensenumber
Instead of the case I have also tried using an IF with the same result. This looks like:
if :Pending = 1
then
and appl.applststype_id != 2;
end if;
Any help to get me past this is greatly appreciated and I will be sure to vote and select most correct answer to help me solve this.
Assuming that your :pending parameter is a numeric where a value of 1 indicates that pending licences are to be excluded and you only want to exclude licence applications that are pending, try adding the following condition in place of your existing case clause:
and (:pending <> 1 or appl.applststype_id !=2)
A logistic regression is a composed of a uniquely identifying number, followed by multiple binary variables (always 1 or 0) based on whether or not a person meets certain criteria. Below I have a query that lists several of these binary conditions. With only four such criteria the query takes a little longer to run than what I would think. Is there a more efficient approach than below? Note. tblicd is a large table lookup table with text representations of 15k+ rows. The query makes no real sense, just a proof of concept. I have the proper indexes on my composite keys.
select patient.patientid
,case when exists
(
select c.patientid from tblclaims as c
inner join patient as p on p.patientid=c.patientid
and c.admissiondate = p.admissiondate
and c.dischargedate = p.dischargedate
where patient.patientid = p.patientid
group by c.patientid
having count(*) > 1000
)
then '1' else '0'
end as moreThan1000
,case when exists
(
select c.patientid from tblclaims as c
inner join patient as p on p.patientid=c.patientid
and c.admissiondate = p.admissiondate
and c.dischargedate = p.dischargedate
where patient.patientid = p.patientid
group by c.patientid
having count(*) > 1500
)
then '1' else '0'
end as moreThan1500
,case when exists
(
select distinct picd.patientid from patienticd as picd
inner join patient as p on p.patientid= picd.patientid
and picd.admissiondate = p.admissiondate
and picd.dischargedate = p.dischargedate
inner join tblicd as t on t.icd_id = picd.icd_id
where t.descrip like '%diabetes%' and patient.patientid = picd.patientid
)
then '1' else '0'
end as diabetes
,case when exists
(
select r.patientid, count(*) from patient as r
where r.patientid = patient.patientid
group by r.patientid
having count(*) >1
)
then '1' else '0'
end
from patient
order by moreThan1000 desc
I would start by using subqueries in the from clause:
select q.patientid, moreThan1000, moreThan1500,
(case when d.patientid is not null then 1 else 0 end),
(case when pc.patientid is not null then 1 else 0 end)
from patient p left outer join
(select c.patientid,
(case when count(*) > 1000 then 1 else 0 end) as moreThan1000,
(case when count(*) > 1500 then 1 else 0 end) as moreThan1500
from tblclaims as c inner join
patient as p
on p.patientid=c.patientid and
c.admissiondate = p.admissiondate and
c.dischargedate = p.dischargedate
group by c.patientid
) q
on p.patientid = q.patientid left outer join
(select distinct picd.patientid
from patienticd as picd inner join
patient as p
on p.patientid= picd.patientid and
picd.admissiondate = p.admissiondate and
picd.dischargedate = p.dischargedate inner join
tblicd as t
on t.icd_id = picd.icd_id
where t.descrip like '%diabetes%'
) d
on p.patientid = d.patientid left outer join
(select r.patientid, count(*) as cnt
from patient as r
group by r.patientid
having count(*) >1
) pc
on p.patientid = pc.patientid
order by 2 desc
You can then probably simplify these subqueries more by combining them (for instance "p" and "pc" on the outer query can be combined into one). However, without the correlated subqueries, SQL Server should find it easier to optimize the queries.
Example of left joins as requested...
SELECT
patientid,
ISNULL(CondA.ConditionA,0) as IsConditionA,
ISNULL(CondB.ConditionB,0) as IsConditionB,
....
FROM
patient
LEFT JOIN
(SELECT DISTINCT patientid, 1 as ConditionA from ... where ... ) CondA
ON patient.patientid = CondA.patientID
LEFT JOIN
(SELECT DISTINCT patientid, 1 as ConditionB from ... where ... ) CondB
ON patient.patientid = CondB.patientID
If your Condition queries only return a maximum one row, you can simplify them down to
(SELECT patientid, 1 as ConditionA from ... where ... ) CondA