我正在构建一个查询,我需要检索MEMBERS表中的所有记录,其中连接日期(datejoin)介于两个日期之间,某个成员资格类型(mtypeid)之一,以及特定位置(siteid) )。
然后,我需要从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 :(得分:1)
当您尝试过滤SCSCHEDULES
子句中的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 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 :(得分: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是数字,那么您应该删除单引号。混合类型可能会使优化器混淆。
另请注意,表别名使查询更易于编写和阅读。