Will Will - 2 months ago 18
SQL Question

Updating a table with mutliple criteria from another table

I have inherited a database that contains among others, two relevant tables, one for Clients and one for Matters. Clients may have more than one matter, and these two tables are linked by a Client ID field.

As part of a de-identifying process, seven years after a file has been closed we are required to remove the first names, last names and date of birth of clients in the Clients table, however we want to otherwise retain the record so we are able to keep track of what work we have done in the past.

I want to create an update query that will replace the identifying data with de-identified data when a client fulfills these conditions:


  • The client has no matters that are currently open (i.e. that have a 'null' in
    the file closure date field in the Matters table).

  • The client has no matters that have closed less than seven years ago.

  • The client has one or more matters that have closed more than seven years ago.



However I am unable to figure out how I can get this to work. Setting up an update query that would update the info in the Clients table if it has a corresponding matter that is older than seven years seems possible, but I can't figure out how to do it in such a way that wouldn't also update the info if the client still has matters open, or has matters younger than seven years. Could anyone point me in the right direction?

To expand further, so far my query involves two tables,
Clients
and
Matters
. The file closure date is in
Matters
and the client's identifying details are in
Clients
. So as far as I understand, it's more of a join problem than a criteria problem.

Client | MatterID | MatterClosureDate
-------|----------|------------------
Alice | 1 | 2008
Bruce | 2 | 2009
Carrol | 3 | 2009
Bruce | 250 | 2012


to illustrate, there are four relevant results from the two tables. Alice and Carrol are both clients who have no matters that are still open or recently closed, however Bruce has one matter that should disqualify him. At the moment though my query is not sophisticated enough to realize this, and returns this:

Client | MatterID | MatterClosureDate
-------|----------|------------------
Alice | 1 | 2008
Bruce | 2 | 2009
Carrol | 3 | 2009

Answer

Consider using correlated subqueries matched row-wise to each ClientID for each listed condition:

SELECT c.FirstName, m.MatterID, m.MatterClosureDate
FROM Clients c
INNER JOIN Matters m ON c.ID = m.ClientID

WHERE 
   (SELECT Count(*) FROM Matters sub 
    WHERE sub.ClientID = c.ID
    AND sub.MatterClosureDate IS NULL) = 0
AND
   (SELECT Count(*) FROM Matters sub 
    WHERE sub.ClientID = c.ID
    AND sub.MatterClosureDate > Year(Date()) - 7) = 0
AND
  (SELECT Count(*) FROM Matters sub 
   WHERE sub.ClientID = c.ID
   AND sub.MatterClosureDate <= Year(Date()) - 7) > 0;

-- FirstName    MatterID    MatterClosureDate
-- Alice        1           2008
-- Carrol       3           2009

And for the update query, convert above SELECT into UPDATE statement:

UPDATE Clients c
SET c.FirstName = 'XXXXX', 
    c.LastName = 'XXXXX',
    c.DOB = NULL 

WHERE 
  (SELECT Count(*) FROM Matters sub 
   WHERE sub.ClientID = c.ID
   AND sub.MatterClosureDate IS NULL) = 0
AND
  (SELECT Count(*) FROM Matters sub 
   WHERE sub.ClientID = c.ID
   AND sub.MatterClosureDate > Year(Date()) - 7) = 0
AND
  (SELECT Count(*) FROM Matters sub 
   WHERE sub.ClientID = c.ID
   AND sub.MatterClosureDate <= Year(Date()) - 7) > 0;

Alternatively, you can use Access' domain aggregate, DCount():

UPDATE Clients c    
SET c.FirstName = 'XXXXX', 
       c.LastName = 'XXXXX',
       c.DOB = NULL 

WHERE     
    DCount("*", "Matters", "ClientID = " & c.ID & " 
           AND MatterClosureDate IS NULL") = 0
AND
    DCount("*", "Matters", "ClientID = " & c.ID & " 
           AND MatterClosureDate  > Year(Date()) - 7") = 0
AND
    DCount("*", "Matters", "ClientID = " & c.ID & " 
           AND MatterClosureDate  <= Year(Date()) - 7") > 0