SQL шаг за шагом объединяет влево по разным столбцам и сопоставляет значения - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть две таблицы.Обе таблицы содержат имя участника, но некоторые из них написаны с ошибками.Например, у TableA есть «Bryan», но та же самая партия записана как «Brian» в TableB.

Я хочу присоединиться к таблице A слева с таблицей B со следующими вещами.

1-й, попробуйте присоединиться слеваТаблица B на PartyName (Точное совпадение, в основном совпадение 100%, сначала присоединится)

2-й, затем все, что осталось, попробуйте объединить их с таблицей B на сумму (если имя не совпадает, попытайтесь присоединитьсяс совпадающей суммой) - в выборке они (Пиналь, Брайан)

3-й, если имя и сумма не совпадают, то сопоставьте сумму с разницей +1 или -1 (в приведенном выше примере это Филипп ($ 251 / $ 250)) и Сара ($ 320,36 / $ 321)

TABLE-A

+-----------+--------+
| PartyName | Amount |
+-----------+--------+
| Pinal     | 200    |
| Charles   | 150    |
| Thomas    | 600    |
| Bryan     | 450    |
| Philip    | 251    |
| Sara      | 320.36 |
+-----------+--------+

TABLE-B

+------------+---------+------------------+
| VPartyName | VAmount | VTransactionCode |
+------------+---------+------------------+
| Peenal     |     200 | ac92ks92lk       |
| Charles    |     150 | a1dg254agfa      |
| Thomas     |     600 | 3tfgqwae4        |
| Brian      |     450 | defg4ae5dfsd     |
| Phillip    |     250 | adg54afdfad      |
| Sarah      |     321 | dg4a5fgd44yg     |
+------------+---------+------------------+

Требуется следующий ВЫХОД

+-----------+--------+-------------------+
| PartyName | Amount |  TransactionCode  |
+-----------+--------+-------------------+
| Pinal     | 200    | ac92ks92lk        |
| Charles   | 150    | a1dg254agfa       |
| Thomas    | 600    | 3tfgqwae4         |
| Bryan     | 450    | defg4ae5dfsd      |
| Philip    | 251    | adg54afdfad       |
| Sara      | 320.36 | dg4a5fgd44yg      |
+-----------+--------+-------------------+

РЕДАКТИРОВАТЬ: ниже приведен пример таблицы, он предназначен для объяснения дублирующейся проблемы при выполнении обоих запросов, предложенных здесь Сергом и Вироном.

CREATE TABLE #A(PartyName varchar(100), Amount float)
insert into #A values

('A',200),  
('B',200),  
('C',200),  
('D',450),  
('E',251),  
('F',320.36)

CREATE TABLE #B(VPartyName varchar(100), VAmount float, VTransactionCode varchar(100))
INSERT INTO #B VALUES
('Peenal',200,'ac92ks92lk'),
('Charles',200,'a1dg254agfa'),
('Thomas ',600,'3tfgqwae4'),
('Brian  ',450,'defg4ae5dfsd'),
('Phillip',250,'adg54afdfad'),
('Sarah  ',321,'dg4a5fgd44yg')

Ответы [ 3 ]

0 голосов
/ 25 сентября 2019

Это то, как вы добиваетесь того, что вы описываете

SELECT A.PartyName
, A.Amount
, ISNULL(ISNULL(B1.VTransactionCode, B2.VTransactionCode), B3.VTransactionCode)
FROM A
LEFT JOIN B B1
    ON A.PartyName = B1.VPartyName
LEFT JOIN B B2
    ON B2.VPartyName NOT IN (
            SELECT PartyName
            FROM A
            )
        AND A.Amount = B2.VAmount
LEFT JOIN B B3
    ON B3.VPartyName NOT IN (
            SELECT PartyName
            FROM A
            )
        AND B3.VAmount NOT IN (
            SELECT Amount
            FROM A
            WHERE PartyName NOT IN (
                    SELECT VPartyName
                    FROM B
                    )
            )
        AND B3.VAmount BETWEEN A.Amount - 1.0
            AND A.Amount + 1.0

с большим набором Данных, чем тот, который вы предоставляете.Возможно, я пропустил одну или две буквы «V» перед столбцом таблицы B

0 голосов
/ 25 сентября 2019

Я думаю, что вы хотите проверить записи, чтобы вы могли использовать для этого OUTER APPLY на основе 3 различных предложенных условий, как показано ниже

CREATE TABLE #tableA(PartyName varchar(100), Amount float)
insert into #tableA values
('Pinal',200),  
('Charles',150),  
('Thomas',600),  
('Bryan',450),  
('Philip',251),  
('Sara',320.36)

CREATE TABLE #tableB(VPartyName varchar(100), VAmount float, VTransactionCode varchar(100))
INSERT INTO #tableB VALUES
('Peenal',200,'ac92ks92lk'),
('Charles',150,'a1dg254agfa'),
('Thomas ',600,'3tfgqwae4'),
('Brian  ',450,'defg4ae5dfsd'),
('Phillip',250,'adg54afdfad'),
('Sarah  ',321,'dg4a5fgd44yg')

select a1.*,
    coalesce(b1.VTransactionCode, b2.VTransactionCode, b3.VTransactionCode) as VTransactionCode
from #tableA a1
outer apply(select b1.VPartyName, b1.VTransactionCode 
            from #tableB b1 where b1.VPartyName = a1.PartyName) b1  -- If PartyName = VPartyName
outer apply(select b2.VPartyName, b2.VTransactionCode 
            from #tableB b2 
            where b2.VAmount = a1.Amount -- If Amount = VAmount
            and b1.VPartyName is null) b2  --Name doesn't match
outer apply(select b3.VPartyName, b3.VTransactionCode 
            from #tableB b3 
            where b3.VPartyName <> a1.PartyName --Name doesn't match
            and b3.VAmount <> a1.Amount  --Amount doesn't match
            and (b3.VAmount-a1.Amount) between -1 and 1) b3  -- Amount difference between -1 to 1
where coalesce(b1.VPartyName, b2.VPartyName, b3.VPartyName) is not null -- Restricted records based on conditions

ВЫХОД :

    PartyName   Amount
    Pinal       200
    Charles     150
    Thomas      600
    Bryan       450
    Philip      251
    Sara        320.36
0 голосов
/ 25 сентября 2019

Использование OR в ON

select a.PartyName, a.Amount, b.VTransactionCode
from TABLEA a
left join TABLEB b on b.VPartyName = a.PartyName or b.VAmount between a.Amount - 1.0 and a.Amount + 1.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...