Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 Query for Unmatching Records

Author  Topic 

tkepongo
Yak Posting Veteran

62 Posts

Posted - 2012-01-06 : 12:49:40
Hello all,

I've spent several hours trying to get a simple query to work, but have had no success.

Background: For the company's internal audits, an auditor is required to perform at least one audit per calendar quarter. I need to run a query to see the number of audits an auditor has for the quarter.

Tables:

------tbl_Audit-------
----------------------
Audit_ID|Quarter|Year|
--1231--|--Q4---|2011|
--1232--|--Q1---|2012|
--1233--|--Q1---|2012|
--1234--|--Q1---|2012|
--1235--|--Q1---|2012|
--1236--|--Q1---|2012|
--1237--|--Q1---|2012|

-jntbl_AuditToAuditor-
----------------------
Audit_ID|Auditor_ID
--1231--|----1----|
--1232--|----2----|
--1233--|----3----|
--1234--|----2----|

View:

----v_AuditorName-----
----------------------
Auditor_ID|-Full_Name--|
----1-----|--Bob Doe---|
----2-----|--Jane Doe--|
----3-----|--Herp Derp-|
----4-----|--John Doe--|
----5-----|-Howard Doe-|

My Closest Query:


DECLARE @CurrentYear smallint -- Current year
DECLARE @Quarter varchar (5)
SET @CurrentYear = (SELECT DATENAME(yy, GETDATE()))
SET @Quarter = 'Q' + CAST ((SELECT DATENAME(qq, GETDATE())) as varchar(5))
SELECT v.Auditor_ID,
CASE
WHEN t.ScheduledYear is NULL THEN @CurrentYear ELSE t.ScheduledYear END AS ScheduledYear,
CASE
WHEN t.ScheduledQuarter is NULL THEN @Quarter ELSE t.ScheduledQuarter END AS ScheduledQuarter,
COUNT (t.Audit_ID) as AuditCount,
tb.Auditor_ID
FROM (dbo.v_AuditorName as v
FULL OUTER JOIN dbo.jntbl_AuditToAuditor as j ON j.Auditor_ID= v.Auditor_ID
FULL OUTER JOIN dbo.tbl_Audit as t on j.Audit_ID = t.Audit_ID)
FULL JOIN dbo.v_AuditorName as tb on tb.Auditor_ID = v.Auditor_ID
WHERE (t.ScheduledYear= @CurrentYear or t.ScheduledYear is NULL)
AND (t.ScheduledQuarter = @Quarter or t.ScheduledQuarter is NULL)
GROUP BY v.Auditor_ID, t.ScheduledYear, t.ScheduledQuarter, tb.Auditor_ID
ORDER BY t.ScheduledYear ASC
PRINT @Quarter
PRINT @CurrentYear


Results:
-----------------------------------
Auditor_ID|Year|Quarter|AuditCount
---NULL---|2012|--Q1---|-----3-----
----2-----|2012|--Q1---|-----2-----
----3-----|2012|--Q1---|-----1-----
----4-----|2012|--Q1---|-----0-----
----5-----|2012|--Q1---|-----0-----

Desired Results:
-----------------------------------
Auditor_ID|Year|Quarter|AuditCount
---NULL---|2012|--Q1---|-----3-----
----1-----|2012|--Q1---|-----0-----
----2-----|2012|--Q1---|-----2-----
----3-----|2012|--Q1---|-----1-----
----4-----|2012|--Q1---|-----0-----
----5-----|2012|--Q1---|-----0-----
NOTE: The NULL row is for the audits without an auditor assigned to it.

I have spent hours using different combinations of joins, cross joins, subqueries, and even unions. Since Auditor 1 has had a previous audit in the last quarter, I can't find a way to have Auditor 1 included in the results. Am I missing something very obvious here?

Thanks for any help.

X002548
Not Just a Number

15586 Posts

Posted - 2012-01-06 : 13:17:11
I'm Sure this is not the WHOLE Story..but here's a start..and you should post your samples like this for faster responses...oh and use [ code] [ /code] tags with out the space to retain spacing...hit reply to see my example with the code tags



-- I need to run a query to see the number of audits an auditor has for the quarter.

CREATE TABLE #tbl_Audit ([Audit_ID] int, [Quarter] char(2), [Year] char(4))
GO

INSERT INTO #tbl_Audit ([Audit_ID], [Quarter], [Year])
SELECT 1231, 'Q4', 2011 UNION ALL
SELECT 1232, 'Q1', 2012 UNION ALL
SELECT 1233, 'Q1', 2012 UNION ALL
SELECT 1234, 'Q1', 2012 UNION ALL
SELECT 1235, 'Q1', 2012 UNION ALL
SELECT 1236, 'Q1', 2012 UNION ALL
SELECT 1237, 'Q1', 2012
GO

CREATE TABLE #jntbl_AuditToAuditor ([Audit_ID] int, [Auditor_ID] int)
GO

INSERT INTO #jntbl_AuditToAuditor ([Audit_ID], [Auditor_ID])
SELECT 1231, 1 UNION ALL
SELECT 1232, 2 UNION ALL
SELECT 1233, 3 UNION ALL
SELECT 1234, 2
GO

SELECT ad.[Auditor_ID], au.[Year], au.[Quarter], COUNT(*)
FROM #jntbl_AuditToAuditor ad
INNER JOIN #tbl_Audit au
ON ad.[Audit_ID] = au.[Audit_ID]
GROUP BY ad.[Auditor_ID], au.[Year], au.[Quarter]
GO

DROP TABLE #jntbl_AuditToAuditor, #tbl_Audit
GO




Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx


Want to help yourself?

http://msdn.microsoft.com/en-us/library/ms130214.aspx

http://weblogs.sqlteam.com/brettk/

http://brettkaiser.blogspot.com/


Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-06 : 14:02:19
Make this small change and see if it fits your requirement?

DECLARE @CurrentYear smallint -- Current year
DECLARE @Quarter varchar (5)
SET @CurrentYear = (SELECT DATENAME(yy, GETDATE()))
SET @Quarter = 'Q' + CAST ((SELECT DATENAME(qq, GETDATE())) as varchar(5))
SELECT v.Auditor_ID,
CASE
WHEN t.ScheduledYear is NULL THEN @CurrentYear ELSE t.ScheduledYear END AS ScheduledYear,
CASE
WHEN t.ScheduledQuarter is NULL THEN @Quarter ELSE t.ScheduledQuarter END AS ScheduledQuarter,
COUNT (t.Audit_ID) as AuditCount,
tb.Auditor_ID
FROM (dbo.v_AuditorName as v
FULL OUTER JOIN dbo.jntbl_AuditToAuditor as j ON j.Auditor_ID= v.Auditor_ID
FULL OUTER JOIN dbo.tbl_Audit as t on j.Audit_ID = t.Audit_ID)
AND (t.ScheduledYear= @CurrentYear or t.ScheduledYear is NULL)
AND (t.ScheduledQuarter = @Quarter or t.ScheduledQuarter is NULL)

FULL JOIN dbo.v_AuditorName as tb on tb.Auditor_ID = v.Auditor_ID
GROUP BY v.Auditor_ID, t.ScheduledYear, t.ScheduledQuarter, tb.Auditor_ID
ORDER BY t.ScheduledYear ASC
PRINT @Quarter
PRINT @CurrentYear


------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

tkepongo
Yak Posting Veteran

62 Posts

Posted - 2012-01-10 : 11:36:02
quote:
Originally posted by visakh16

Make this small change and see if it fits your requirement?

DECLARE @CurrentYear smallint -- Current year
DECLARE @Quarter varchar (5)
SET @CurrentYear = (SELECT DATENAME(yy, GETDATE()))
SET @Quarter = 'Q' + CAST ((SELECT DATENAME(qq, GETDATE())) as varchar(5))
SELECT v.Auditor_ID,
CASE
WHEN t.ScheduledYear is NULL THEN @CurrentYear ELSE t.ScheduledYear END AS ScheduledYear,
CASE
WHEN t.ScheduledQuarter is NULL THEN @Quarter ELSE t.ScheduledQuarter END AS ScheduledQuarter,
COUNT (t.Audit_ID) as AuditCount,
tb.Auditor_ID
FROM (dbo.v_AuditorName as v
FULL OUTER JOIN dbo.jntbl_AuditToAuditor as j ON j.Auditor_ID= v.Auditor_ID
FULL OUTER JOIN dbo.tbl_Audit as t on j.Audit_ID = t.Audit_ID)
AND (t.ScheduledYear= @CurrentYear or t.ScheduledYear is NULL)
AND (t.ScheduledQuarter = @Quarter or t.ScheduledQuarter is NULL)

FULL JOIN dbo.v_AuditorName as tb on tb.Auditor_ID = v.Auditor_ID
GROUP BY v.Auditor_ID, t.ScheduledYear, t.ScheduledQuarter, tb.Auditor_ID
ORDER BY t.ScheduledYear ASC
PRINT @Quarter
PRINT @CurrentYear


------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/





Hi there,

Sorry I've been off work for a couple days so I haven't had a chance to check. The solution you provided still doesn't show records for the auditors who have had previous audits. It still shows the records for auditors who haven't had any previous audits (meaning that they don't have records of their Auditor_ID in the jntbl_AuditToAuditor table).

For the eight missing auditors, I get this in the results:

Auditor_ID| ScheduledYear|ScheduledQuarter|AuditCount|Auditor_ID
NULL 2012 Q1 8 NULL
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-10 : 11:42:24
which is the master table for Auditor?

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

tkepongo
Yak Posting Veteran

62 Posts

Posted - 2012-01-10 : 11:56:59
quote:
Originally posted by visakh16

which is the master table for Auditor?

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/





I have a View called dbo.v_AuditorName , which displays the Auditor_ID and Full Name.

There is also a table called tbl_Auditor, which displays Auditor_ID and Employee_Id.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-10 : 11:57:56
which is the master set?

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

tkepongo
Yak Posting Veteran

62 Posts

Posted - 2012-01-10 : 12:03:17
quote:
Originally posted by visakh16

which is the master set?

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/





tbl_Auditor is the master set.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-10 : 12:22:48
then start with tbl_Auditor and LEFT JOIN other tables to it if you want to include all auditor info in output

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

tkepongo
Yak Posting Veteran

62 Posts

Posted - 2012-01-10 : 12:25:28
quote:
Originally posted by visakh16

then start with tbl_Auditor and LEFT JOIN other tables to it if you want to include all auditor info in output

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/





I tried that and it's still missing the 8 records :(
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-10 : 12:33:08
it wont if you dont have any where conditions based on left joined table. if at all you need to have additional filters move them to ON condition of LEFT JOINs rather than in WHERE condition

read the below article for the idea

http://weblogs.sqlteam.com/jeffs/archive/2007/05/14/criteria-on-outer-joined-tables.aspx

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

tkepongo
Yak Posting Veteran

62 Posts

Posted - 2012-01-11 : 13:43:59
quote:
Originally posted by visakh16

it wont if you dont have any where conditions based on left joined table. if at all you need to have additional filters move them to ON condition of LEFT JOINs rather than in WHERE condition

read the below article for the idea

http://weblogs.sqlteam.com/jeffs/archive/2007/05/14/criteria-on-outer-joined-tables.aspx

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/





Sorry, but I don't understand. My WHERE clause doesn't filter anything from the left join table though.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2012-01-12 : 00:10:46
then it wont miss anything from your base table (ie left side table). thats what LEFT JOIN is there for

show your used query please

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

tkepongo
Yak Posting Veteran

62 Posts

Posted - 2012-01-17 : 19:29:38
So I created a function to pull this query off


CREATE FUNCTION v_AuditorCount (@Quarter VARCHAR(5), @CurrentYear SMALLINT)
RETURNS TABLE
AS
RETURN

SELECT v.Auditor_ID,
CASE
WHEN j.ScheduledYear is NULL THEN @CurrentYear ELSE j.ScheduledYear END AS ScheduledYear,
CASE
WHEN j.ScheduledQuarter is NULL THEN @Quarter ELSE j.ScheduledQuarter END AS ScheduledQuarter,
COUNT (t.Audit_ID) AS AuditCount
FROM dbo.v_AuditorName AS v
INNER JOIN
( SELECT Auditor_ID, a.Audit_ID, ScheduledQuarter, ScheduledYear
FROM
( SELECT v.Auditor_ID, NULL AS [Audit_ID]
FROM dbo.v_AuditorName AS v
UNION ALL
SELECT jt.Auditor_ID, jt.Audit_ID
FROM dbo.jntbl_AuditToAuditor AS jt
) AS jt LEFT JOIN tbl_Audit AS a ON jt.Audit_ID = a.Audit_ID
) AS j
ON j.Auditor_ID = v.Auditor_ID
LEFT OUTER JOIN
dbo.tbl_Audit AS t ON j.Audit_ID = t.Audit_ID
WHERE (t.ScheduledYear= @CurrentYear or t.ScheduledYear is NULL)
AND (t.ScheduledQuarter = @Quarter or t.ScheduledQuarter is NULL)
GROUP BY v.Auditor_ID,j.ScheduledYear, j.ScheduledQuarter
GO


SELECT Auditor_ID, ScheduledYear,ScheduledQuarter,SUM (AuditCount) as AuditCount
FROM v_AuditorCount('Q3', 2010)
GROUP BY Auditor_ID, ScheduledYear,ScheduledQuarter
Go to Top of Page
   

- Advertisement -