如何从表中选择存在多行的单行

时间:2014-05-22 15:30:03

标签: sql sql-server tsql select

我有两张表th_Therapy_Noteth_Approved。当th_Therapy_Note中的注释获得批准后,应用程序会将记录插入th_Approved

注释可能会在获得批准后被拒绝有几个原因(不要问我为什么,因为我没有设计这个应用程序,哈哈)。因此,如果注释在被批准后被拒绝,则会插入另一个th_Approved条目。

th_Approved.th_approved_isApproved是一个布尔(位)列,因此根据状态,此表中的注释条目为true或false

因此th_Approved的{​​{1}}状态可能存在同一个音符的多行,最后一个条目是最新条目且状态正确

以下查询的主要目的是选择准备好“最终确定”的注释。以下查询的问题位于上一个th_Approved.th_approved_isApproved过滤器“inner join”这是选择有效获得批准的注释,这意味着他们应该在AND th_Approved.th_approved_isApproved = 1和{{1}中有一个条目} 是真的。

这适用于th_Approved中包含单个条目的注释,但th_Approved.th_approved_isApproved中包含多个条目的注释(如上所述)表示如果该特定注释的最后一个条目为false则存在问题。查询仍然会选中它,因为至少有一个th_Approved条目为true,即使最后一个正确状态为false也是如此。我只需要查看最后一个条目就能确定一个音符的正确状态,并根据状态选择或不选择。

查询的最后一部分(th_Approved)仅适用于我的测试,因为此笔记有多个条目,但最终不会有这个。

如何解决我的问题?我一直在寻找几种没有运气的策略.....希望我有道理:)谢谢

th_Approved.th_approved_isApproved

3 个答案:

答案 0 :(得分:1)

您可以使用" MAX"技巧(或" MIN"或类似)。在日期或唯一列上是典型的。

以下是一个使用MAX(OrderDate)的通用Northwind示例(客户有多个订单)。

如果有2个订单具有相同的订单日期,则下面的逻辑会分崩离析,并且这些日期是" max"日期。因此,首选可以订购的唯一标识符)

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'

答案 1 :(得分:0)

无法访问您的数据集进行测试,这是我能给您的最佳选择。 本质上我正在做的是使用CTE和TSQL命令ROW NUMBER使用您拥有的任何日期函数过滤掉重复项。然后将过滤后的列表放入主查询中。

 ;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

答案 2 :(得分:0)

由于您在th_Approved上有序列ID,因此我会使用它。 id的整数比较是完美的。日期/日期时间比较有时会增加问题。

所以我试试这个:

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