嵌套查询的问题

时间:2011-04-21 20:13:49

标签: mysql

我正在尝试在结果列表中检索满足两个条件的ID列表: 1)该ID在指定时间7/1 / 2009-6 / 30/2010内提供服务(由推荐或注释确定) 2)ID在指定时间之前未出现

我已经提出了这个长期查询,但它仍然带回了那些有以前服务的人:

SELECT DISTINCT c.id, 
                c.lastname, 
                c.firstname 
FROM   roundtable rt 
       INNER JOIN clients c 
         ON c.id = rt.clientid 
       LEFT OUTER JOIN notes n 
         ON c.id = n.clientid 
       LEFT OUTER JOIN referral rf 
         ON c.id = rf.clientid 
WHERE  ( rf.referraldate>='2009-07-01' 
         AND rf.referraldate<='2010-06-30' ) 
        OR ( n.createddate>='2009-07-01' 
             AND n.createddate<='2010-06-30' ) 
           AND c.id NOT IN (SELECT DISTINCT clt.id 
                            FROM   roundtable rtb 
                                   INNER JOIN clients clt 
                                     ON clt.id = rtb.clientid 
                                   LEFT OUTER JOIN notes nts 
                                     ON clt.id = nts.clientid 
                                   LEFT OUTER JOIN referral ref 
                                     ON clt.id = ref.clientid 
                            WHERE  ( rf.referraldate < '2009-07-01' ) 
                                    OR ( n.createddate < '2009-07-01' )) 
ORDER  BY c.lastname, 
          c.firstname 

例如:ID,ReferralDate,NoteCreatedDate
              4,2 / 2 / 2008,3 / 12/2008
              4,7 / 15 / 2009,7 / 30/2009
              6,5 / 30 / 2008,2 / 26/2007
              8,7 / 20 / 2009,3 / 20/2008
              9,7 / 20 / 2009,10 / 3/2009

因此ID 4,6和8不应该在返回列表中,因为ID 4在该时间段之外具有先前的推荐和注释,并且ID 6在该时间段之外具有推荐和注释,而ID 8在外部具有一个注释时间段。在这种情况下,ID 9应该是唯一返回的,因为它具有该时间段中的日期而没有先前的记录。

谢谢!

3 个答案:

答案 0 :(得分:1)

SELECT DISTINCT 
          c.id
        , c.lastname
        , c.firstname
FROM 
    roundtable rt 
    INNER JOIN 
            clients c
                    on c.id = rt.clientid 
    LEFT OUTER JOIN 
            notes n 
                    on c.id = n.clientid 
    LEFT OUTER JOIN  
            referral rf 
                    on c.id = rf.clientid 
WHERE 
        (rf.referraldate BETWEEN '2009-07-01' AND '2010-06-30' or n.createddate BETWEEN '2009-07-01' and '2010-06-30')
AND 
        c.id not in (SELECT DISTINCT 
                                      clt.id 
                     FROM 
                        roundtable rtb
                        INNER JOIN
                                    clients clt 
                                            on clt.id = rtb.clientid
                        LEFT OUTER JOIN 
                                    notes nts 
                                            on clt.id = nts.clientid
                        LEFT OUTER JOIN  
                                    referral ref 
                                            on clt.id = ref.clientid
                    WHERE 
                            (rf.referraldate < '2009-07-01' or  n.createddate <'2009-07-01'))
ORDER BY 
        c.lastname, c.firstname

答案 1 :(得分:0)

你真的不需要加入,因为你没有把数据拉回来。您可以简单地检查在符合条件的任何一个表中是否存在记录。 EXISTS关键字也非常好,因为它一找到匹配就会停止查看。

SET @begin_date = '2009-07-01';
SET @end_date = '2010-06-30';

SELECT
    c.id,
    c.lastname,
    c.firstname
FROM
    clients c
WHERE
    EXISTS (
        SELECT
            *
        FROM
            referrer r
        WHERE
            r.clientid = c.id
        AND
            r.referraldate >= @begin_date
        AND
            r.referraldate <= @end_date)
OR
    EXISTS (
        SELECT
            *
        FROM
            notes n
        WHERE
            n.clientid = c.id
        AND
            n.createdate >= @begin_date
        AND
            n.createdate <= @end_date)
ORDER BY
    c.lastname,
    c.firstname;

答案 2 :(得分:0)

它看起来像是一个复制粘贴错误。您在子查询中使用了不同的表别名,但WHERE

除外

你写了

      WHERE  ( rf.referraldate < '2009-07-01' ) 
                       OR ( n.createddate < '2009-07-01' ) 

我认为你的意思

     WHERE  ( ref.referraldate < '2009-07-01' ) 
                       OR ( nts.createddate < '2009-07-01' ) 

另外,当罗比接受你的需要和额外的一套parens。因为他不需要嵌套parens

,所以在他之间使用它会更容易

e.g。

WHERE
(
    (rf.referraldate>='2009-07-01' 
       AND rf.referraldate<='2010-06-30' ) 
     OR ( n.createddate>='2009-07-01' 
     AND n.createddate<='2010-06-30' ) 
)
AND NOT IN (....