MS Access SQL连接仅显示额外的记录

时间:2018-10-01 04:00:06

标签: sql ms-access

我试图在匹配一对一的行后显示剩余的记录。连接两个表后如何显示多余/剩余的记录?

假设我有两个表A和B。它们在一天结束时都显示相同的交易。但是,表A具有有关记录的更多详细信息,但是更新较晚。另一方面,表B的交易信息有限,但是要在表A之前几个小时进行更新。

我需要一个查询,该查询可以返回表B中尚未出现在表A中的记录。

TABLE A
+-------+-----+---------+----------+---------------------------+
| NAME  |  ID | AMOUNT  |   TYPE   |    PROCESSED TIMESTAMP    |
+-------+-----+---------+----------+---------------------------+
|  ABC  | 123 | -420.07 | PURCHASE | 2018-09-06-08.26.32.000000|
|  ABC  | 123 |  420.07 | REFUND   | 2018-09-06-07.12.18.000000|
|  BBC  | 456 |   -5.00 | PURCHASE | 2018-09-06-10.25.13.000000|
+-------+-----+---------+----------+---------------------------+

TABLE B
+----+----------+---------------------------+
| ID |  AMOUNT  |    RECEIVED TIMESTAMP     |
+----+----------+---------------------------+
|123 |  -420.07 | 2018-09-05-09.26.15.000000|
|123 |   420.07 | 2018-09-05-08.12.03.000000|
|123 |  -420.07 | 2018-09-05-08.40.00.000000|
|456 |    -5.00 | 2018-09-05-08.45.00.000000|
+----+----------+---------------------------+

QUERY RESULTS
+----+----------+
| ID |  AMOUNT  |
+----+----------+
|123 |  -420.07 |
+----+----------+

我可以设法找到与“余额外” ID相关的所有记录,但是我只需要多余的特定记录即可。

SELECT * FROM b
WHERE id 
IN
(SELECT d.id AS id 
FROM
    (SELECT * FROM
        (SELECT id, ROUND(SUM(amount),2) AS balance FROM a GROUP BY id) c
    RIGHT JOIN
        (SELECT id, ROUND(SUM(amount),2) AS balance FROM b GROUP BY id) d
    ON c.id = d.id
WHERE c.balance <> d.balance))

产量...

+----+----------+
| ID |  AMOUNT  |
+----+----------+
|123 |  -420.07 |
|123 |   420.07 |
|123 |  -420.07 |
+----+----------+

2 个答案:

答案 0 :(得分:0)

您需要阅读有关joins的更多信息。有3个基本的连接可以使生活简单得多。

INNER JOIN:首先,不要求这样做,但是您提供的用于查找余额项的查询太复杂了。可以通过内部联接进行简化。 内部联接是一种设置操作,基本上将从匹配条件的两个表(集合)中获取数据。

select * from 
    (
        (select id, sum(amount) from a group by id) group_A
        INNER JOIN (select id, sum(amount) from b group by id) group_B
        ON group_A.id = group_B.id
        WHERE group_A.balance != group_B.balance
    )

左/右外部联接::左外部联接是一项操作,它将返回两个集合中存在的所有数据,以及左集合中而非右集合中的数据。正确的连接对正确的集合必不可少的相同操作。重要的是要注意,此处不存在的那条多余记录将为空。

由于您希望表B中存在记录但表A中不存在记录,因此有多种实现方法,一种方法是获取两个表中都存在的记录(内部联接),然后获取表B中的所有记录,但是不在较早完成的内部联接中。使用内部联接示例中的group_A / group_B定义。

select id from b where id not in (
select id from group_A INNER JOIN group_B on group_A.id = group_B.id)

或者您可以执行右外部联接,然后使用从表A提取的字段的属性为null,可以过滤出所需的ID。

select group_B.id from group_A RIGHT OUTER JOIN group_B ON group_A.id = group_B.id
where group_A.id is null

请使用联接上的主键,以获取用户@ComputerVersteher提到的正确结果

答案 1 :(得分:0)

我认为,您应该添加PK col。
我无法将数据与表A和B匹配,也无法在表B上分隔两行。

+----+----------+---------------------------+
| ID |  AMOUNT  |    RECEIVED TIMESTAMP     |
+----+----------+---------------------------+
|123 |  -420.07 | 2018-09-05-09.26.15.000000|<-
|123 |   420.07 | 2018-09-05-08.12.03.000000|
|123 |  -420.07 | 2018-09-05-08.40.00.000000|<-
|456 |    -5.00 | 2018-09-05-08.45.00.000000|
+----+----------+---------------------------+

我添加了新的col(deal_no)并制成了它。
https://www.db-fiddle.com/f/3GfZoQwGhBLf7YWf2RucBF/4

select tmp_B.deal_no, tmp_B.id, tmp_B.amount, tmp_A.deal_no
  from tmp_B
       left outer join tmp_A
                    on tmp_A.deal_no = tmp_B.deal_no
 where tmp_A.deal_no is null