Как я могу написать этот запрос как полное соединение вместо объединения левое / правое соединение? - PullRequest
1 голос
/ 22 апреля 2011

вот код, показывающий входы и требуемый вывод.

По сути, я пытаюсь самостоятельно присоединиться, чтобы сопоставить результаты заявления моего брокера с моими внутренними записями.Таким образом, левый набор столбцов - это список брокера, правая часть - мой список.Если у брокера есть позиция, а у меня нет, то NULL справа.Если у меня есть позиция, а у брокера нет, слева - NULL.

Левое соединение + правое соединение + объединение работает точно так, как я хочу.Похоже, должно быть какое-то вуду, чтобы полное объединение могло получить это без двух селектов, но я не могу понять это.

drop table MatchPositions
go

create table MatchPositions
( 
    mt_source varchar (10),
    mt_symbol varchar (10),
    mt_qty float,
    mt_price float
)

go

insert into MatchPositions values ('BROKER', 'IBM', 100, 50.25)
insert into MatchPositions values ('BROKER', 'MSFT', 75, 30)
insert into MatchPositions values ('BROKER', 'GOOG', 25, 500)
insert into MatchPositions values ('BROKER', 'SPY', 200, 113)

insert into MatchPositions values ('MODEL', 'MSFT', 75, 30)
insert into MatchPositions values ('MODEL', 'GOOG', 25, 500)
insert into MatchPositions values ('MODEL', 'GLD', 300, 150)

go

select * from MatchPositions b
left join MatchPositions m on b.mt_symbol = m.mt_symbol and m.mt_source = 'MODEL'
where b.mt_source = 'BROKER'
union

select * from MatchPositions b
right join MatchPositions m on b.mt_symbol = m.mt_symbol and b.mt_source = 'BROKER'
where m.mt_source = 'MODEL'

и вот ожидаемый результат:

mt_source  mt_symbol  mt_qty                 mt_price               mt_source  mt_symbol  mt_qty                 mt_price
---------- ---------- ---------------------- ---------------------- ---------- ---------- ---------------------- ----------------------
NULL       NULL       NULL                   NULL                   MODEL      GLD        300                    150
BROKER     GOOG       25                     500                    MODEL      GOOG       25                     500
BROKER     IBM        100                    50.25                  NULL       NULL       NULL                   NULL
BROKER     MSFT       75                     30                     MODEL      MSFT       75                     30
BROKER     SPY        200                    113                    NULL       NULL       NULL                   NULL

Ответы [ 5 ]

4 голосов
/ 22 апреля 2011
;WITH T1 AS
(
SELECT *
FROM MatchPositions 
WHERE mt_source = 'BROKER'
), T2 AS
(
SELECT *
FROM MatchPositions 
WHERE mt_source = 'MODEL'
)
SELECT *
FROM T1 FULL JOIN T2 ON T1.mt_symbol = T2.mt_symbol
1 голос
/ 22 апреля 2011

Возможно использование функции isnull:

SELECT *
FROM MatchPositions b
  FULL JOIN MatchPositions m on b.mt_symbol = m.mt_symbol
                            and b.mt_source != m.mt_source
WHERE isnull(b.mt_source, 'BROKER') = 'BROKER'
  and isnull(m.mt_source, 'MODEL') = 'MODEL'
0 голосов
/ 22 апреля 2011

Попробуйте:

select *
from      MatchPositions broker
full join MatchPositions model  on model.mt_symbol =  broker.mt_symbol
                               and model.mt_source <> broker.mt_source
where ( broker.mt_source = 'BROKER' or broker.MT_SOURCE is null )
  and ( model.mt_source  = 'MODEL'  or model.MT_SOURCE is null )

Из первой таблицы логического источника вы хотите либо строки-посредники, либо пропущенные строки.

Из второй таблицы логического источника вы хотите либо строки моделиили пропущенные строки.

0 голосов
/ 22 апреля 2011
SELECT *
FROM MatchPositions b
  FULL JOIN MatchPositions m ON b.mt_symbol = m.mt_symbol
                            AND b.mt_source = 'BROKER'
                            AND m.mt_source = 'MODEL'

Это фильтрует таблицу по частям 'БРОКЕР' и 'МОДЕЛЬ' перед внешним соединением с ними.

0 голосов
/ 22 апреля 2011

Если ваша СУБД поддерживает FULL JOIN (также известный как FULL OUTER JOIN):

SELECT *
FROM (SELECT * FROM MatchPositions WHERE mt_source = 'BROKER') b
FULL
JOIN (SELECT * FROM MatchPositions WHERE mt_source = 'MODEL' ) m
  ON b.mt_symbol = m.mt_symbol

Это решение в основном такое же, как у Мартина, просто использует другой синтаксис, который может быть полезен, если ваша СУБД не поддерживает CTE.

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