我有一个查询从三个表中使用LEFT OUTER JOIN为两个连接提取数据。我需要查询返回最左边的(Salesrep表)信息,即使两个右表中没有相应的数据(分别是开处方者和处方药)。当我在WHERE子句中没有日期参数的情况下运行此查询时,我得到了预期的返回值,但是一旦我包含日期参数,我就不会返回任何没有salesrep匹配数据的地方。我至少需要查看查询中请求的salesrep表列。
以下是查询...非常感谢任何帮助。
SELECT salesrep.salesrepid as SalesRepID,
salesrep.fname as SalesrepFName,
salesrep.lname as SalesRepLName,
salesrep.fname+' '+salesrep.lname as SalesRepFullName,
prescriber.dea_no as PDeaNo,
prescriber.lname+', '+prescriber.fname as DocName,
CONVERT(VARCHAR(8), prescriptions.filldate, 1) as FillDate,
prescriptions.drugname as DrugName,
prescriptions.daysupply as Supply,
prescriptions.qtydisp as QtyDisp,
prescriptions.rx_no as Refill,
prescriptions.copay as Sample,
ROUND(prescriptions.AgreedToPay-(prescriptions.AgreedToPay*.07),2) as AgreedToPay,
prescriptions.carrierid as CarrierID
FROM salesrep
LEFT OUTER JOIN prescriber on salesrep.salesrepid = prescriber.salesrepid
LEFT OUTER JOIN prescriptions on prescriber.dea_no = prescriptions.dea_no
WHERE salesrep.salesrepid = 143 AND
prescriptions.filldate >= '09-01-12' AND
prescriptions.filldate <= '09-17-12'
ORDER BY prescriptions.filldate
答案 0 :(得分:64)
您应该将prescriptions.filldate
上的约束移动到联接的ON
条件中,并将其从where
子句中删除:
LEFT OUTER JOIN prescriptions ON prescriber.dea_no = prescriptions.dea_no
AND prescriptions.filldate >= '09-01-12'
AND prescriptions.filldate <= '09-17-12'
否则,prescriptions
中没有null
的{{1}}结尾的条目和prescriptions.filldate
条款会将它们抛弃。
答案 1 :(得分:14)
Here 您可以找到有关查询处理阶段的简要说明(这对大多数DBMS来说都很常见)。你会发现,对于OUTER JOIN:
当您将条件放在接触外表行的WHERE子句中时,它们都被丢弃。您应该简单地将该条件放在ON子句中,因为在附加外部行之前对其进行评估。
那么,那些条件:
prescriptions.filldate >= '09-01-12' AND
prescriptions.filldate <= '09-17-12'
应该移入ON子句。
答案 2 :(得分:0)
这是因为您的prescriptions.filldate
不等式会过滤掉salesrep
列中没有值的prescriptions.filldate
行。
因此,如果存在空值(没有来自右表的匹配数据),则整个行(包括salesrep数据)将被日期过滤器过滤掉 - 因为null
不会介于两者之间日期。
答案 3 :(得分:0)
此fiddle有助于说明这一点:
放置在ON子句中的限制在连接之前被处理,而放置在WHERE子句中的限制在连接之后被处理。
请注意,内部联接无关紧要,而外部联接则很重要。在docs
中有更多详细信息表t1
| num | name |
| --- | ---- |
| 1 | a |
| 2 | b |
| 3 | c |
表t2
| num | value |
| --- | ----- |
| 1 | xxx |
| 3 | yyy |
| 5 | zzz |
ON子句中的加入条件
SELECT * FROM t1
LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx';
| num | name | num | value |
| --- | ---- | --- | ----- |
| 1 | a | 1 | xxx |
| 2 | b | | |
| 3 | c | | |
WHERE子句中的加入条件
SELECT * FROM t1
LEFT JOIN t2 ON t1.num = t2.num
WHERE t2.value = 'xxx';
| num | name | num | value |
| --- | ---- | --- | ----- |
| 1 | a | 1 | xxx |