2016-07-05 75 views
1

我正在构建一个查询,我需要从MEMBERS表中检索所有记录,其中连接日期(datejoin)在两个日期之间,某个成员资格类型(mtypeid)之一和从一个特定的位置(siteid)。需要SQL逻辑可能子查询需要

然后,我需要从SCSCHEDULER(此表存储所有约会)表中撤回所有预定过去某个日期的成员的约会,具有某种类型的约会,并且仍然是活性。

我有以下,但我相信我需要在子查询中放置一些这种逻辑,因为我只为具有约会的成员返回数据。我需要至少为没有任何约会的成员以及那些有约会的成员和scscheduler数据从成员表中返回数据。

SELECT  MEMBERS.scancode, MEMBERS.lname, MEMBERS.fname, MEMBERTYPES.description, MEMBERS.status, MEMBERS.datejoin, EMPLOYEES.lname AS Expr1, 
         EMPLOYEES.fname AS Expr2, SCSCHEDULES.scheduledatefrom, SCSCHEDULES.timeduration, SCSCHEDULES.scheduledescription, 
         SCSCHEDULES.schedulestatus 
FROM   MEMBERS LEFT OUTER JOIN 
         SCSCHEDULES ON MEMBERS.memid = SCSCHEDULES.memid INNER JOIN 
         MEMBERTYPES ON MEMBERS.mtypeid = MEMBERTYPES.mtypeid INNER JOIN 
         EMPLOYEES ON MEMBERS.employeeid = EMPLOYEES.employeeid 
WHERE  (MEMBERS.datejoin BETWEEN @rvStartDate AND @rvEndDate) AND (MEMBERS.siteid = '779') AND (MEMBERS.mtypeid = '1' OR 
         MEMBERS.mtypeid = '10' OR 
         MEMBERS.mtypeid = '12' OR 
         MEMBERS.mtypeid = '28' OR 
         MEMBERS.mtypeid = '32' OR 
         MEMBERS.mtypeid = '33' OR 
         MEMBERS.mtypeid = '34' OR 
         MEMBERS.mtypeid = '35' OR 
         MEMBERS.mtypeid = '36' OR 
         MEMBERS.mtypeid = '40' OR 
         MEMBERS.mtypeid = '48') AND (SCSCHEDULES.scheduledatefrom >= @rvStartDate) AND (SCSCHEDULES.scheduledescription = 'First' OR 
         SCSCHEDULES.scheduledescription = 'Second') AND (SCSCHEDULES.schedulestatus = '1') 
+0

注意@Merlin,你可以通过使用IN()来缩短你的'WHERE MEMEBER.mtypeid = ...或...'。打字少了很多。 https://msdn.microsoft.com/en-us/library/ms177682.aspx – scsimon

回答

1

当您尝试WHERE子句中筛选对SCSCHEDULES(等后外连接),你最终会下降,你想保持行。他们需要被放置在连接条件或包裹起来派生表如下内:

SELECT m.scancode, m.lname, m.fname, mt.description, m.status, m.datejoin, 
     e.lname AS Expr1, e.fname AS Expr2, 
     s.scheduledatefrom, s.timeduration, s.scheduledescription, s.schedulestatus 
FROM MEMBERS AS m 
     LEFT OUTER JOIN 
     (
     SELECT * FROM SCSCHEDULES 
     WHERE 
       scheduledatefrom >= @rvStartDate 
      AND scheduledescription IN ('First', 'Second') 
      AND schedulestatus = '1' 
     ) AS s 
      ON m.memid = s.memid 
     INNER JOIN MEMBERTYPES AS mt 
      ON m.mtypeid = mt.mtypeid 
     INNER JOIN EMPLOYEES AS e 
      ON m.employeeid = e.employeeid 
WHERE  m.datejoin BETWEEN @rvStartDate AND @rvEndDate 
     AND m.siteid = '779' 
     AND m.mtypeid IN (
      '1', '10', '12', '28', '32', '33', '34', '35', '36', '40, '48' 
     ); 
1

LEFT JOIN,环境对所有的,但第一个表应ON子句中去,而不是WHERE条款:

SELECT m.scancode, m.lname, m.fname, mt.description, m.status, m.datejoin, 
     e.lname AS Expr1, e.fname AS Expr2, 
     s.scheduledatefrom, s.timeduration, s.scheduledescription, s.schedulestatus 
FROM MEMBERS m LEFT OUTER JOIN 
    SCSCHEDULES s 
    ON MEMBERS.memid = s.memid AND scheduledatefrom >= @rvStartDate AND 
     scheduledescription IN ('First', 'Second') AND 
     schedulestatus = '1' INNER JOIN 
    MEMBERTYPES mt 
    ON m.mtypeid = mt.mtypeid INNER JOIN 
    EMPLOYEES e 
    ON m.employeeid = e.employeeid 
WHERE m.datejoin BETWEEN @rvStartDate AND @rvEndDate AND 
     m.siteid = '779' AND 
     m.mtypeid IN ('1', '10', '12', '28', '32', '33', '34', '35', '36', '40, '48'); 

注意:如果您的ID是数字,那么您应该删除单引号。混合类型可能会混淆优化器。

另请注意,表别名使查询更易于编写和读取。