简体   繁体   中英

How to select a single row where multiple rows exist from a table

I have two tables th_Therapy_Note and th_Approved . When a note in th_Therapy_Note gets approved, the application inserts a record to th_Approved .

A note can get rejected for several reasons after it has been approved (don't ask me why, as I did not design this app, lol). So if a note is rejected after being approved, another entry to th_Approved is inserted.

th_Approved.th_approved_isApproved is a boolean (bit) column, so depending on the status, the note entry in this table for this column in true or false

So multiple lines for the same note can exist in th_Approved with different th_Approved.th_approved_isApproved status, the last entry being the most recent one and correct status

The main purpose for the below query is to select notes that are ready to be 'finalized'. The issue with the below query is in the last inner join filter ' AND th_Approved.th_approved_isApproved = 1 ' This is selecting notes that effectively have been approved, meaning they should have an entry in th_Approved and th_Approved.th_approved_isApproved is true.

This works perfect for notes with single entries in th_Approved , but notes with multiple entries in th_Approved (as explained above) represent an issue if the last entry for that particular note is false. The query will still pick it up because there is at least one entry with th_Approved.th_approved_isApproved as true, even when last correct status is false. I need to only look at this last entry to be able to determine the correct status for a note and select it or not depending on the status.

Last part of the query ( and th_Therapy_Note.th_note_id=16239 ) is just for my testing as this note has multiple entries, but the final will not have this.

How can I solve my issue? I have been looking at several strategies with no luck.....Hopefully I made sense :) thanks

 SELECT Distinct Convert(varchar,th_Therapy_Note.th_note_id) as NOTEID, '054' as PROGCODE, Rtrim(ch.child_caseNumber) as CASEID, 
                        Case th_TherapyType.shortname when 'ST' then 'SP' else rtrim(th_TherapyType.shortname) end as SERVTYPE, Convert(varchar,th_Therapy_Note.th_note_dateofservice,101) as DELSERVDATE, 
                        Cast(((Select sum(th_TherapyServiceProvided.units) From th_TherapyServiceProvided where th_DirectServices.th_ds_id = th_TherapyServiceProvided.th_ds_id)/60) as varchar) as SERVHRS, 
                        Cast(((Select sum(th_TherapyServiceProvided.units) From th_TherapyServiceProvided where th_DirectServices.th_ds_id = th_TherapyServiceProvided.th_ds_id)%60) as varchar) as SERVMIN, 
                  '1' as METHOD, isnull(th_Users.trad_id, ' ') as SPROVNUM, th_Users.th_user_lname, '' as COVISIT
FROM         th_Therapy_Note INNER JOIN
                  child_tbl AS ch ON th_Therapy_Note.child_id = ch.child_recordId INNER JOIN
                  th_DirectServices ON th_Therapy_Note.th_note_id = th_DirectServices.th_note_id INNER JOIN
                  LookUp_contactType ON th_Therapy_Note.contact_type_id = LookUp_contactType.recId INNER JOIN
                  th_Users ON th_Therapy_Note.service_coordinator = th_Users.th_user_email INNER JOIN
                  th_TherapyType ON th_Therapy_Note.therapy_type = th_TherapyType.id INNER JOIN
                  th_Approved ON th_Therapy_Note.th_note_id = th_Approved.th_note_id AND th_Approved.th_approved_isApproved = 1
WHERE     (ch.child_recordId =
                      (SELECT     MAX(child_recordId) AS Expr1
                        FROM          child_tbl
                        WHERE      (child_caseNumber = ch.child_caseNumber)))
      and th_Therapy_Note.th_note_dateofservice > '4/22/2014' and th_Therapy_Note.th_note_id=16239

You can use a "MAX" trick (or "MIN" or similar). On a date or unique column is typical.

Here is a generic Northwind example that uses the MAX(OrderDate) (where a customer has more than one order).

The logic below falls apart if there are 2 orders with the same order-date, and those dates are the "max" date. So a unique identifier that is orderable is preferred)

Use Northwind
GO

Select cust.* , ords.* 
from dbo.Customers cust

        LEFT OUTER JOIN dbo.Orders ords

                ON 
                (
                    ords.CustomerID = cust.CustomerID

                    AND ords.OrderDate = 
                        (SELECT MAX(OrderDate) 
                        FROM dbo.Orders innerords  
                        WHERE innerords.CustomerID = cust.CustomerID
                        )
                     )

where cust.CustomerID = 'ALFKI'

Without access to your dataset to test this with this is the best I can give you. In essence what I am doing is filtering out the duplicates using a CTE and the TSQL command ROW NUMBER using whatever date function you have. then placing the filtered out list into your main query.

 ;with fixDuplicateCTE(
 SELECT m.th_note_id, m.tag
 FROM ( SELECT TH_NOTE_ID ROW_NUMBER OVER(partition by th_note_id ORDER BY [SOME DATE FUNCTION YOU HAVE!!!!!] desc) as tag  FROM th_approved) as m 
 INNER JOIN th_approved AS a on m.th_note_id = a.th_note_id 
 WHERE m.tag = 1
 )

 SELECT Distinct Convert(varchar,th_Therapy_Note.th_note_id) as NOTEID, '054' as PROGCODE, Rtrim(ch.child_caseNumber) as CASEID, 
                        Case th_TherapyType.shortname 
                                when 'ST' then 'SP' else rtrim(th_TherapyType.shortname) end as SERVTYPE, Convert(varchar,th_Therapy_Note.th_note_dateofservice,101) as DELSERVDATE, 
                        Cast(((Select sum(th_TherapyServiceProvided.units) From th_TherapyServiceProvided where th_DirectServices.th_ds_id = th_TherapyServiceProvided.th_ds_id)/60) as varchar) as SERVHRS, 
                        Cast(((Select sum(th_TherapyServiceProvided.units) From th_TherapyServiceProvided where th_DirectServices.th_ds_id = th_TherapyServiceProvided.th_ds_id)%60) as varchar) as SERVMIN, 
                  '1' as METHOD, isnull(th_Users.trad_id, ' ') as SPROVNUM, th_Users.th_user_lname, '' as COVISIT
FROM         th_Therapy_Note 
INNER JOIN              child_tbl AS ch ON th_Therapy_Note.child_id = ch.child_recordId 
INNER JOIN                  th_DirectServices ON th_Therapy_Note.th_note_id = th_DirectServices.th_note_id 
INNER JOIN                  LookUp_contactType ON th_Therapy_Note.contact_type_id = LookUp_contactType.recId
 INNER JOIN                  th_Users ON th_Therapy_Note.service_coordinator = th_Users.th_user_email 
 INNER JOIN                  th_TherapyType ON th_Therapy_Note.therapy_type = th_TherapyType.id 
 INNER JOIN                  fixDuplicateCTE ON th_Therapy_Note.th_note_id = th_Approved.th_note_id AND th_Approved.th_approved_isApproved = 1
WHERE     (ch.child_recordId =
                      (SELECT     MAX(child_recordId) AS Expr1
                        FROM          child_tbl
                        WHERE      (child_caseNumber = ch.child_caseNumber)))
      and th_Therapy_Note.th_note_dateofservice > '4/22/2014' and th_Therapy_Note.th_note_id=16239

Since you have a sequential ID on th_Approved, then I'd use that. Integer comparison on id is perfect. Date/Datetime comparison can sometimes add problems.

So I'd try this:

SELECT Distinct
  Convert(varchar,th_Therapy_Note.th_note_id) as NOTEID,
  '054' as PROGCODE,
  Rtrim(ch.child_caseNumber) as CASEID, 
  Case th_TherapyType.shortname
    when 'ST' then 'SP'
    else           rtrim(th_TherapyType.shortname)
  end as SERVTYPE,
  Convert(varchar,th_Therapy_Note.th_note_dateofservice,101) as DELSERVDATE,
  Cast(((
    Select sum(th_TherapyServiceProvided.units)
    From th_TherapyServiceProvided
    where th_DirectServices.th_ds_id = th_TherapyServiceProvided.th_ds_id)/60) as varchar
  ) as SERVHRS, 
  Cast(((
    Select sum(th_TherapyServiceProvided.units)
    From th_TherapyServiceProvided
    where th_DirectServices.th_ds_id = th_TherapyServiceProvided.th_ds_id)%60) as varchar
  ) as SERVMIN, 
  '1' as METHOD,
   isnull(th_Users.trad_id, ' ') as SPROVNUM,
   th_Users.th_user_lname, '' as COVISIT
FROM th_Therapy_Note
INNER JOIN child_tbl AS ch ON th_Therapy_Note.child_id = ch.child_recordId
INNER JOIN th_DirectServices ON th_Therapy_Note.th_note_id = th_DirectServices.th_note_id INNER JOIN LookUp_contactType ON th_Therapy_Note.contact_type_id = LookUp_contactType.recId INNER JOIN th_Users ON th_Therapy_Note.service_coordinator = th_Users.th_user_email
INNER JOIN th_TherapyType ON th_Therapy_Note.therapy_type = th_TherapyType.id
INNER JOIN th_Approved ON th_Approved.th_approved_id=(
   SELECT MAX(th_approved_id)
   FROM th_Approved
   WHERE th_Therapy_Note.th_note_id = th_Approved.th_note_id)
WHERE ch.child_recordId = (
    SELECT MAX(child_recordId)
    FROM child_tbl
    WHERE child_caseNumber = ch.child_caseNumber)
  AND th_Therapy_Note.th_note_dateofservice > '4/22/2014'
  AND th_Approved.th_approved_isApproved = 1
  AND th_Therapy_Note.th_note_id=16239

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM