我试图在匹配一对一的行后显示剩余的记录。连接两个表后如何显示多余/剩余的记录?
假设我有两个表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 |
+----+----------+
答案 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