Проблема с присоединением таблиц БД - PullRequest
0 голосов
/ 22 сентября 2009

У меня проблема при соединении таблиц (левое соединение)

table1:

id1  amt1
1    100
2    200
3    300

table2:

id2  amt2
1    150
2    250
2    350

мой запрос:

select id1,amt1,id2,amt2 from table1
left join table2 on table2.id1=table1.id2

Мое предполагаемое о / п:

      id1 amt1  id2 amt2
row1: 1   100   1    150
row2: 2   200   2    250
row3: 2   200   2    350

Я хочу o / p в строке 3 как

2 null 2 350

т.е. я хочу избежать повторения данных (amt1).

Ответы [ 4 ]

3 голосов
/ 22 сентября 2009

Это действительно проблема форматирования, которая лучше всего обрабатывается клиентом . Например, в SQL * Plus мы можем использовать BREAK ....

SQL> select t1.*, t2.* from t1, t2
  2  /

A   B   C   D           C1
--- --- --- --- ----------
aaa bbb ccc ddd        111
aaa bbb ccc ddd        222

SQL> break on a on b on c on d
SQL> select t1.*, t2.* from t1, t2
  2  /

A   B   C   D           C1
--- --- --- --- ----------
aaa bbb ccc ddd        111
                       222

SQL>

Примечание: в отсутствие какой-либо дополнительной информации я выбрал декартово произведение.

редактировать

BREAK - это команда SQL Plus, которая подавляет повторяющиеся столбцы в наших строках. Работает только в клиенте SQL Plus. Как и следовало ожидать, он описан в руководстве пользователя Oracle * SQL. Узнайте больше.

Я использовал BREAK в качестве примера правильного способа ведения дел, потому что он чистый и правильно реализует разделение интересов. Если вы используете другой клиент, вам нужно будет использовать его возможности форматирования. Можно настроить SQL (см. Ниже), но это снижает полезность запроса, потому что мы не можем повторно использовать запрос в других местах, которые не хотят подавлять дублированные значения.

В любом случае, вот одно решение, которое использует аналитическую функцию ROW_NUMBER() во встроенном представлении.

SQL> select * from t1
  2  /

A   B   C   D           ID
--- --- --- --- ----------
eee fff ggg hhh          1
aaa bbb ccc ddd          2

SQL> select * from t2
  2  /

        C1         ID
---------- ----------
       333          2
       111          1
       222          2
       444          2

SQL> select t1_id
  2         , case when rn = 1 then a else null end as a
  3         , t2_id
  4         , c1
  5  from (
  6      select t1.id as t1_id
  7             , row_number () over (partition by t1.id order by t2.c1) as rn
  8             , t1.a
  9             , t2.c1
 10             , t2.id as t2_id
 11      from t1, t2
 12      where t1.id = t2.id
 13      )
 14  order by t1_id, rn
 15  /

     T1_ID A        T2_ID         C1
---------- --- ---------- ----------
         1 eee          1        111
         2 aaa          2        222
         2              2        333
         2              2        444

SQL>

Я решил не использовать LAG(), потому что это работает только с фиксированными смещениями, и казалось вероятным, что число строк в T2 будет переменным.

0 голосов
/ 22 сентября 2009

Вы выполнили декартово произведение двух таблиц, поскольку не указали никаких критериев соединения. Для устранения дубликатов необходимо указать способ объединения таблиц.

Например, вы можете попробовать

select * from table1, table2 where table2.val = 111;

В вашем примере нет ключа объединения, поэтому нет очевидного значения для объединения таблиц. Но это более типичный пример, в обеих таблицах есть связанное значение, чтобы вы могли объединить их осмысленно.

0 голосов
/ 22 сентября 2009

Вы, кажется, делаете здесь перекрестное соединение . Я подозреваю, что вы хотели либо равное соединение , либо левое внешнее объединение .

0 голосов
/ 22 сентября 2009

Предполагая, что вы хотите, чтобы все данные были в одной строке, вы просто делаете выбор объединения ...

Выберите поле A из таблицы A союз Выберите поле B из таблицы B

Обратите внимание, что вам нужно привести тип данных к одинаковым для обеих таблиц.

Если вам нужен другой ответ, пожалуйста, лучше отформатируйте ожидаемый результат;)

Хорошо ...

Вы исправили форматирование ...

В приведенном выше случае я просто вернул бы 2 курсора из моего запроса. Данные примера не предоставляют поля для связи обеих таблиц, поэтому я не вижу способа объединить их разумным образом. Для sproc возможно возвратить несколько наборов результатов.

...