Query help

  • I have two tables. The first (tblInternalAuditRequirement) houses internal audits that are required for our company. The second (tblInternalAuditAssignment) houses all audits that have been assigned. I would like to be able to find the InternalAuditRequirementID and AuditTeamID of Audit Requirements that don't have any outstanding audits (essentially where there are no audits where the Completion Date is null, AND where the audits might not have been assigned yet). The query below takes care of the first part of finding the ones that don't have any null completion dates. However, I'm having a hard time figuring out how to also include the ones that haven't been assigned yet.

    Query to get results:

    SELECT tblInternalAuditRequirement.InternalAuditRequirementID, AuditTeamID

    FROM tblInternalAuditRequirement INNER JOIN

    (SELECT tblInternalAuditAssignment.InternalAuditRequirementID

    FROM tblInternalAuditAssignment

    WHERE (tblInternalAuditAssignment.CompletionDate IS NOT NULL)

    GROUP BY tblInternalAuditAssignment.InternalAuditRequirementID) AS CompletedAudits ON

    tblInternalAuditRequirement.InternalAuditRequirementID = CompletedAudits.InternalAuditRequirementID

    WHERE (Enabled = 'True')

    CURRENT RESULTS:

    InternalAuditRequirementIDAuditTeamID

    1 1

    8 1

    14 1

    19 1

    23 1

    DESIRED RESULTS:

    InternalAuditRequirementIDAuditTeamID

    1 1

    8 1

    14 1

    16 2

    19 1

    23 1

    27 3

    DDL for table creation and sample data:

    CREATE TABLE [tblInternalAuditAssignment](

    [AuditAssignmentID] [int] IDENTITY(1,1) NOT NULL,

    [EmployeeID] [int] NOT NULL,

    [InternalAuditRequirementID] [int] NOT NULL,

    [DateAssigned] [datetime] NOT NULL,

    [CompletionDate] [datetime] NULL,

    [Comments] [varchar](max) NULL,

    CONSTRAINT [PK_tblInternalAuditAssignment] PRIMARY KEY CLUSTERED

    (

    [AuditAssignmentID] ASC

    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

    GO

    CREATE TABLE [tblInternalAuditRequirement](

    [InternalAuditRequirementID] [int] IDENTITY(1,1) NOT NULL,

    [AuditID] [int] NOT NULL,

    [AuditDescription] [varchar](75) NOT NULL,

    [Reoccurence] [tinyint] NOT NULL,

    [LastAuditSent] [datetime] NULL,

    [Enabled] [bit] NOT NULL,

    [AuditTeamID] [int] NOT NULL,

    CONSTRAINT [PK_tblInternalAuditRequirement] PRIMARY KEY CLUSTERED

    (

    [InternalAuditRequirementID] ASC

    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

    ) ON [PRIMARY]

    GO

    SET IDENTITY_INSERT [tblInternalAuditAssignment] ON

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (82, 191, 1, CAST(0x0000A35700000000 AS DateTime), CAST(0x0000A35700000000 AS DateTime), NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (83, 940, 2, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (84, 39, 3, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (85, 234, 4, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (86, 954, 5, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (87, 619, 6, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (88, 858, 7, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (89, 604, 8, CAST(0x0000A35700000000 AS DateTime), CAST(0x0000A35700000000 AS DateTime), NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (90, 518, 9, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (91, 716, 10, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (92, 891, 11, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (93, 966, 12, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (94, 191, 13, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (95, 940, 14, CAST(0x0000A35700000000 AS DateTime), CAST(0x0000A35700000000 AS DateTime), NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (96, 39, 15, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (98, 234, 17, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (99, 619, 18, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (100, 858, 19, CAST(0x0000A35700000000 AS DateTime), CAST(0x0000A35700000000 AS DateTime), NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (101, 604, 20, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (102, 518, 21, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (103, 716, 22, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (104, 966, 23, CAST(0x0000A35700000000 AS DateTime), CAST(0x0000A35700000000 AS DateTime), NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (105, 191, 24, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (106, 940, 25, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    INSERT [tblInternalAuditAssignment] ([AuditAssignmentID], [EmployeeID], [InternalAuditRequirementID], [DateAssigned], [CompletionDate], [Comments]) VALUES (107, 945, 26, CAST(0x0000A35700000000 AS DateTime), NULL, NULL)

    GO

    SET IDENTITY_INSERT [tblInternalAuditAssignment] OFF

    GO

    SET IDENTITY_INSERT [tblInternalAuditRequirement] ON

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (1, 1, N'GMP Audit of Poly 1', 7, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (2, 1, N'GMP Audit of Poly 2', 7, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (3, 1, N'GMP Audit of Poly 3', 7, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (4, 1, N'GMP Audit of Poly 4', 7, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (5, 1, N'GMP Audit of Poly 3', 7, NULL, 1, 2)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (6, 1, N'GMP Audit of Jar Line', 21, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (7, 1, N'GMP Audit of Fruit Mixer', 14, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (8, 1, N'GMP Audit of Machine Packaging', 7, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (9, 1, N'GMP Audit of Hand Pack', 7, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (10, 1, N'GMP Audit of Hay Baler', 7, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (11, 1, N'GMP Audit of Hay Baler', 7, NULL, 1, 2)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (12, 1, N'GMP Audit of Stick Room', 7, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (13, 1, N'GMP Audit of Pre Mix', 7, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (14, 1, N'GMP Audit of Flow Wrapper', 7, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (15, 1, N'GMP Audit of Mixing', 7, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (16, 1, N'GMP Audit of Mixing', 7, NULL, 1, 2)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (17, 1, N'GMP Audit of Grain Handling', 7, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (18, 2, N'GMP Audit of Warehouse A', 14, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (19, 2, N'GMP Audit of Warehouse B', 14, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (20, 2, N'GMP Audit of Warehouse C', 14, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (21, 2, N'GMP Audit of Warehouse D', 14, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (22, 2, N'GMP Audit of Warehouse E', 14, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (23, 2, N'GMP Audit of Warehouse F', 14, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (24, 2, N'GMP Audit of Warehouse G', 14, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (25, 2, N'GMP Audit of Warehouse H', 14, NULL, 1, 1)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (26, 3, N'Exterior Inspection (condition of exterior of plant)', 14, NULL, 1, 3)

    GO

    INSERT [tblInternalAuditRequirement] ([InternalAuditRequirementID], [AuditID], [AuditDescription], [Reoccurence], [LastAuditSent], [Enabled], [AuditTeamID]) VALUES (27, 4, N'Food Defense Inspection', 14, NULL, 1, 3)

    GO

    SET IDENTITY_INSERT [tblInternalAuditRequirement] OFF

    GO

    Thanks for any insight.

  • Thank you for the nice sample and well formed question!

    You are slightly over-complicating the query, check the parenthesis in the where clause.

    😎

    SELECT

    AR.InternalAuditRequirementID

    ,AR.AuditTeamID

    FROM tblInternalAuditRequirement AR

    LEFT OUTER JOIN tblInternalAuditAssignment AA

    ON AR.InternalAuditRequirementID = AA.InternalAuditRequirementID

    WHERE (AA.CompletionDate IS NOT NULL OR AA.InternalAuditRequirementID IS NULL)

    AND AR.Enabled = 'True'

    Results

    InternalAuditRequirementID AuditTeamID

    -------------------------- -----------

    1 1

    8 1

    14 1

    16 2

    19 1

    23 1

    27 3

  • Thanks for the compliment on the sample and explanation... However, I still didn't explain it 100% correctly :-). The query you gave is exactly what I asked for, but I need to throw another wrench in to the mix. Each audit can be assigned more than once. It's possible that one is completed, and the other one isn't. If there are ANY that are not complete, I would like to eliminate that from the results.

    To simulate this with the data already created, add a record in tblInternalAuditAssignment with an InternalAuditRequirementID of 8 and with no completion date (the rest of the fields can be arbitrary numbers/dates). The results should be the same, except with the InternalAuditRequirementID of 8 missing because there is at least one audit with that number that isn't completed. I think that's what I was trying to accomplish when I was using a GROUP clause, but didn't do it correctly. The desired results would be as shown below, but the results of the query you gave would produce the same results as before:

    InternalAuditRequirementID AuditTeamID

    -------------------------- -----------

    1 1

    14 1

    16 2

    19 1

    23 1

    27 3

    Sorry for not being 100% clear - no matter how hard I try, I always forget something.

    Kevin

  • While as a rule, I'm somewhat loathe to the idea of using correlated subqueries, I believe this should do what you're asking. This keeps the left join and ensures there are no records in the right table with a null completion date. At this point, the additional check where aa.InternalAuditRequirementID is null is moot because it's covered by the subquery.

    select

    ar.InternalAuditRequirementID,

    ar.AuditTeamID,

    *

    from tblInternalAuditRequirement ar

    left outer join tblInternalAuditAssignment aa

    on ar.InternalAuditRequirementID = aa.InternalAuditRequirementID

    where not exists (select aa2.InternalAuditRequirementID

    from tblInternalAuditAssignment aa2

    where aa.InternalAuditRequirementID = aa2.InternalAuditRequirementID

    and aa2.CompletionDate is null)

    and ar.Enabled = 'true'

    -- EDIT: I threw that query together somewhat hastily. It seems to work for the sample data, but make sure to verify that it does everything you want against the full data set. There's quite a bit of funky null logic going on.

    Executive Junior Cowboy Developer, Esq.[/url]

  • skilly2 (6/27/2014)


    Thanks for the compliment on the sample and explanation... However, I still didn't explain it 100% correctly :-). The query you gave is exactly what I asked for, but I need to throw another wrench in to the mix. Each audit can be assigned more than once. It's possible that one is completed, and the other one isn't. If there are ANY that are not complete, I would like to eliminate that from the results.

    To simulate this with the data already created, add a record in tblInternalAuditAssignment with an InternalAuditRequirementID of 8 and with no completion date (the rest of the fields can be arbitrary numbers/dates). The results should be the same, except with the InternalAuditRequirementID of 8 missing because there is at least one audit with that number that isn't completed. I think that's what I was trying to accomplish when I was using a GROUP clause, but didn't do it correctly. The desired results would be as shown below, but the results of the query you gave would produce the same results as before:

    InternalAuditRequirementID AuditTeamID

    -------------------------- -----------

    1 1

    14 1

    16 2

    19 1

    23 1

    27 3

    Sorry for not being 100% clear - no matter how hard I try, I always forget something.

    Kevin

    No worries, here it is

    😎

    USE tempdb;

    GO

    ;WITH AUDIT_ASSIGNEMENT AS

    (

    SELECT

    X.InternalAuditRequirementID

    ,X.AuditAssignmentID

    ,ISNULL(X.CompletionDate,CAST(0 AS DATETIME)) AS CompletionDate

    FROM tblInternalAuditAssignment X

    )

    ,AUDIT_LIST AS

    (

    SELECT

    AR.InternalAuditRequirementID

    ,AR.AuditTeamID

    ,AA.AuditAssignmentID

    ,NULLIF((MIN(AA.CompletionDate) OVER

    (

    PARTITION BY AA.InternalAuditRequirementID

    )),CAST(0 AS DATETIME)) AS CompletionDate

    FROM tblInternalAuditRequirement AR

    LEFT OUTER JOIN AUDIT_ASSIGNEMENT AA

    ON AR.InternalAuditRequirementID = AA.InternalAuditRequirementID

    WHERE AR.Enabled = 'True'

    )

    SELECT

    AL.InternalAuditRequirementID

    ,AL.AuditTeamID

    FROM AUDIT_LIST AL

    WHERE (AL.CompletionDate IS NOT NULL OR AL.AuditAssignmentID IS NULL)

    ORDER BY AL.InternalAuditRequirementID;

    Results

    InternalAuditRequirementID AuditTeamID

    -------------------------- -----------

    1 1

    14 1

    16 2

    19 1

    23 1

    27 3

Viewing 5 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic. Login to reply