MS Access SQL join отображает только дополнительные записи - PullRequest
0 голосов
/ 01 октября 2018

Я пытаюсь отобразить оставшиеся записи после сопоставления строк один к одному.Как отобразить лишние / оставшиеся записи после объединения двух таблиц?

Предположим, у меня есть две таблицы A и B. Они обе отображают одни и те же транзакции в конце дня.Тем не менее, таблица A содержит более подробную информацию о записях, но уже поздно обновляться.Таблица B, с другой стороны, содержит ограниченную информацию о транзакциях, но обновляется за несколько часов до Таблицы A.

Мне нужен запрос, который может вернуть, какие записи еще не появились в Таблице A из Таблицы B.

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 |
+----+----------+

Мне удается найти все записи, связанные с идентификатором, который "забалансовый", но мне нужны только дополнительные записи:

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 голосов
/ 01 октября 2018

Я думаю, вам следует добавить кол. PK.
Я не могу сопоставить данные с таблицами A и B и не могу разделить 2 строки в таблице 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
0 голосов
/ 01 октября 2018

Вам нужно больше узнать о объединениях .Есть 3 основных соединения, которые могут сделать жизнь намного проще.

ВНУТРЕННЕЕ СОЕДИНЕНИЕ: Во-первых, это не запрашивается, но запрос, который вы указали для нахождения внебалансовых позиций, слишком сложен.Это может быть упрощено внутренним соединением.Внутреннее соединение - это операция набора, которая в основном будет получать данные из обеих таблиц (набор), которые соответствуют условию.

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, как нулевое, можно отфильтроватьтребуемый идентификатор.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...