左联接2个表,结果看起来像内部联接

时间:2018-07-03 08:24:21

标签: sql sql-server-2008 tsql

问题可能很容易,但是我对SQL还是很陌生,所以去吧。

我要完成的工作:

我有TableATableBTableA包含我的大部分数据,但是,如果ID和日期范围匹配,则应使用TableB中的数据来修改其中一列(修改后的结果)。

这是我的查询:

SELECT 
    t1.ID, t1.a, t1.b, t1.c, t1.d, t1.e, t1.f, t1.g, t1.h, t1.i, 
    (t1.totalcost  - (ISNULL(t2.cost, 0) * ISNULL(t2.qty,0))) AS modified_result, 
    t1.j, t1.k, t1.createdate
FROM 
    TableA as t1
LEFT JOIN 
    TableB AS t2 ON t1.ID = t2.ID
WHERE 
    t1.createdate BETWEEN '2018-06-19' AND '2018-06-23' 
    AND t2.createdate BETWEEN '2018-06-19' AND '2018-06-23' 
    AND t2.trans_type = 'H'
ORDER BY
    t1.createdate

TableA中大约有2000多个记录满足了TableA的那些条件,而TableB中只有少数匹配的记录。运行此查询将产生与TableB结果相等的行号,对我来说,这看起来像是内部联接。

我的WHERE部分可能有错,但我看不到它。

4 个答案:

答案 0 :(得分:2)

我不确定技术方面,但是我会根据我的工作经验来答复您

WHERE子句中过滤t2时。 DBMS过滤JOIN

之后的整个结果

如果您想使用subQuery而不是t2保留t1的所有行,或者将过滤器t2移至加入条件示例

使用子查询代替T2

SELECT t1.ID, t1.a, t1.b, t1.c, t1.d, t1.e, t1.f, t1.g, t1.h, t1.i, 
(t1.totalcost  - (ISNULL(t2.cost, 0) * ISNULL(t2.qty,0))) as modified_result, 
t1.j, t1.k, t1.createdate
FROM TableA as t1
LEFT JOIN (
    SELECT *
    FROM TableB t2 
    WHERE t2.createdate between '2018-06-19' and '2018-06-23' and t2.trans_type = 'H'
) AS t2 ON t1.ID = t2.ID
WHERE t1.createdate between '2018-06-19' and '2018-06-23' 
ORDER BY t1.createdate

移动过滤器t2以加入条件

SELECT t1.ID, t1.a, t1.b, t1.c, t1.d, t1.e, t1.f, t1.g, t1.h, t1.i, 
(t1.totalcost  - (ISNULL(t2.cost, 0) * ISNULL(t2.qty,0))) as modified_result, 
t1.j, t1.k, t1.createdate
FROM TableA as t1
LEFT JOIN TableB AS t2 ON t1.ID = t2.ID and t2.createdate between '2018-06-19' and '2018-06-23' and t2.trans_type = 'H'
WHERE t1.createdate between '2018-06-19' and '2018-06-23' 
ORDER BY t1.createdate

上面我没有测试过的代码

希望有帮助。

答案 1 :(得分:1)

SELECT 
    t1.ID, t1.a, t1.b, t1.c, t1.d, t1.e, t1.f, t1.g, t1.h, t1.i, 
    (t1.totalcost  - (ISNULL(t2.cost, 0) * ISNULL(t2.qty,0))) AS modified_result, 
    t1.j, t1.k, t1.createdate
FROM 
    TableA as t1
LEFT JOIN 
    TableB AS t2 ON t1.ID = t2.ID AND t2.createdate BETWEEN '2018-06-19' AND '2018-06-23' 
    AND t2.trans_type = 'H'
WHERE 
    t1.createdate BETWEEN '2018-06-19' AND '2018-06-23' 

ORDER BY
    t1.createdate

答案 2 :(得分:0)

这是您的住所条件

    WHERE t1.createdate between '2018-06-19' and '2018-06-23' and t2.createdate 
    between '2018-06-19' and '2018-06-23' ***and t2.trans_type = 'H'***

在这里,您的行将按照跨类型进行过滤...基本上是在限制行

答案 3 :(得分:-1)

LEFT OUTER JOIN子句中包含来自WHERE表的条件不会神奇地将其转换为INNER JOIN;无需在ON子句中包含所有条件的“特殊规则”。

这里发生的事情是,没有WHERE子句的查询将从NULL返回一些t2值,然后通过包括不包含此别名的条件来排除这些值NULL个值。

如果您要像这样重写查询,那么它将按您希望的那样工作:

SELECT t1.ID, t1.a, t1.b, t1.c, t1.d, t1.e, t1.f, t1.g, t1.h, t1.i, 
(t1.totalcost  - (ISNULL(t2.cost, 0) * ISNULL(t2.qty,0))) as modified_result, 
t1.j, t1.k, t1.createdate
FROM TableA as t1
LEFT JOIN TableB AS t2 ON t1.ID = t2.ID
WHERE t1.createdate between '2018-06-19' and '2018-06-23' and (t2.createdate IS NULL OR t2.createdate 
between '2018-06-19' and '2018-06-23') and (t2.trans_type IS NULL OR t2.trans_type = 'H')
ORDER BY t1.createdate