Как вернуть значения из той же таблицы?
У меня есть две таблицы A и B. Я хочу вернуть все записи из A и только совпадения из B. Я могу использовать левое соединение для этого. Но после присоединения я хочу вернуть записи, основанные на флаге в той же таблице.
Таблица А: | Col1 | Col2 | |------|------| | 123 | 12 | | 456 | 34 | | 789 | 56 | Таблица Б: | Col1 | Col2 | Col3 | Col4 | Col5 | |------|------|------|------|------| | 123 | 12 | NULL | Я | 1 | | 456 | 34 | NULL | E | 1 | | 111 | 98 | NULL | Я | 1 | | 222 | 99 | NULL | E | 1 | | 123 | 12 | AB | NULL | 2 | | 456 | 34 | CD | NULL | 2 | | 123 | 12 | EF | NULL | 2 | | 111 | 98 | GH | NULL | 2 | | 222 | 99 | IJ | NULL | 2 |
После того, как осталось соединение A и B, вот как будет выглядеть результат:
| Col1 | Col2 | Col3 | Col4 | Col5 | | ------ | ------ | ------ | ------ | ------ | | 123 | 12 | NULL | Я | 1 | | 456 | 34 | NULL | E | 1 | | 123 | 12 | AB | NULL | 2 | | 456 | 34 | CD | NULL | 2 | | 123 | 12 | EF | NULL | 2 | | 789 | 56 | NULL | NULL | NULL |
Значения 1 и 2 в Col5 указывают, нужно ли заполнять Col4 или Col3. 1 для Col4 и 2 для Col3.
Я хочу вернуть все записи для "I" (но исключая запись с "I") в Col4, которая будет выглядеть следующим образом:
| Col1 | Col2 | Col3 | Col4 | Col5 |
|------|------|------|--------|------|
| 123 | 12 | AB | (null) | 2 |
| 123 | 12 | EF | (null) | 2 |
Я также хочу вернуть записи для 'E' (снова исключая запись с 'E') в col4, но для всех значений, отличных от одного в Col3. В этом случае CD. Который будет выглядеть так:
| Col1 | Col2 | Col3 | Col4 | Col5 | | ------ | ------ | ------ | -------- | ------ | | 456 | 34 | AB | (ноль) | 2 | | 456 | 34 | EF | (ноль) | 2 | | 456 | 34 | GH | (ноль) | 2 | | 456 | 34 | IJ | (ноль) | 2 |
Может кто-нибудь подсказать, как справиться с этим в SQL?
3 ответа
Хорошо, я считаю, что следующие два запроса достигают желаемых результатов. Вы можете увидеть весь пример кода через следующую скрипту SQL.
Правило существования:
select A.*
, B.Col3
, B.Col4
, B.Col5
from TableA A
JOIN TableB B
on A.Col1 = B.Col1
and A.Col2 = B.Col2
and B.Col5 = 2
where exists (select 1 from TableB C
where C.col1 = B.col1 and C.col2 = B.col2
and c.col4 = 'I' AND C.col5 = 1)
| Col1 | Col2 | Col3 | Col4 | Col5 |
|------|------|------|--------|------|
| 123 | 12 | AB | (null) | 2 |
| 123 | 12 | EF | (null) | 2 |
Правило исключения:
select A.*
, B.Col3
, B.Col4
, B.Col5
from TableA A
CROSS JOIN TableB B
where b.col5 = 2
and exists (select 1 from TableB C
where C.col1 = a.col1 and C.col2 = a.col2
and c.col4 = 'E' AND C.col5 = 1)
and b.col3 not in (select col3 from TableB b
where b.col1 = a.col1 and b.col2 = a.col2 and b.col5 = 2)
| Col1 | Col2 | Col3 | Col4 | Col5 |
|------|------|------|--------|------|
| 456 | 34 | AB | (null) | 2 |
| 456 | 34 | EF | (null) | 2 |
| 456 | 34 | GH | (null) | 2 |
| 456 | 34 | IJ | (null) | 2 |
Результат для меня:-
;with cte1 As(select a.col1,a.col2 from A a left join B b on a.col1 =b.col2 and a.col2=b.col2 where b.col4 = 'I'),cte2 As(select b.col3,b.col4,b.col5 from from A a left join B b on a.col1 =b.col2 and a.col2=b.col2 where b.col4 <> 'I')
Результат для E:-
select a.col1,a.col2,b.col3,b.col4,b.col5 from cte1 a cross join cte2 b
;with cte1 As(select a.col1,a.col2 from A a left join B b on a.col1 =b.col2 and a.col2=b.col2 where b.col4 = 'E'),cte2 As(select b.col3,b.col4,b.col5 from from A a left join B b on a.col1 =b.col2 and a.col2=b.col2 where b.col4 <> 'E')
select a.col1,a.col2,b.col3,b.col4,b.col5 from cte1 a cross join cte2 b
select c.col1, c.col2
from
(select a.col1, a.col2, b.col3 from a inner join table b on a.id = b.id
where "condition" ) c
where c.col1 = "condition"
Это сценарий. Объяснение:
Внутри () я написал первый выбор. Там вы будете делать выбор с вашими объединениями и вашими условиями. В конце выбора я написал "c", которое является именем таблицы, сгенерированной из суб-выбора. Затем вы выберете некоторые значения из сгенерированной таблицы и отфильтруете их, где они будут влиять на результаты, сгенерированные таблицей, созданной с помощью дополнительного выбора.
РЕДАКТИРОВАТЬ: я использовал имена вашего вопроса, чтобы сделать его проще