2015-08-15 3 views
0

Возможно ли динамическое объединение таблиц с использованием SQL (или PL/SQL)?Динамический или условный Присоединиться

У меня есть Таблица с несколькими столбцами. Каждый столбец ниже имеет свою отдельную таблицу, за исключением id.

| id | AA | BB | CC | DD | EE | 
|-----|----|----|----|----|----| 
| 123 | 0 | 0 | 1 | 1 | 1 | 
| 456 | 1 | 1 | 0 | 1 | 1 | 
| 789 | 1 | 0 | 1 | 0 | 0 | 
....... 

Основываясь на значении столбцов, мне нужно объединить таблицы.

  • Для ид = 123 Я хотел бы присоединиться к CC, DD, EE таблицы.
  • Для ид = 456 Я хотел бы присоединиться к AA, BB, DD, EE таблицы.
  • Для ид = 789 Я хотел бы присоединиться к AA, CC таблицы.
  • И так далее.
  • И, наконец, объединение результата в одну таблицу.
  • Кроме того, таблицы AA, BB, CC, DD, EE имеют одинаковый набор столбцов.

Пример данные:

Таблица А.А.

| id | Value | 
|-----|-------| 
| 456 | bbb | 
| 789 | ccc | 

Таблица BB

| id | Value | 
|-----|-------| 
| 789 | ccc | 
| 456 | bbb | 

Таблица CC

| id | Value | 
|-----|-------| 
| 123 | aaa | 
| 789 | ccc | 

Таблица DD

| id | Value | 
|-----|-------| 
| 123 | aaa | 

Таблица EE

| id | Value | 
|-----|-------| 
| 123 | aaa | 

Ожидаемый результат

| id | Value | 
|-----|-------| 
| 123 | abc | 
| 789 | ccc | 

id 456 не будет частью окончательного результата, поскольку он будет отфильтрован при присоединении.

Возможно ли это сделать в SQL или PL/SQL (предпочтительный простой SQL).Также: я хочу сделать INNER JOIN.

+0

Вы должны отредактировать свой запрос с данными образца * и * желаемыми результатами. –

+0

Какую причину вы положили после этого значения? И можете ли вы разместить DDL для таблиц? –

+0

Это была опечатка.Обновлен вопрос –

ответ

0

испрашиваемого для JOIN из TableA и таблицы А.А. через EE (и все это UNION Ed вверх), вероятно, следует искать похожий на выход из

WITH 
TableAUnpivot AS (
    SELECT 
    id 
    , tableName 
    -- , value 
    FROM 
    TableA UNPIVOT EXCLUDE NULLS 
     (VALUE FOR(tableName) IN ("AA", "BB", "CC", "DD", "EE") 
    ) 
), 
DataTablesCombined AS (
    SELECT 'AA' tableName, id, value FROM AA UNION ALL 
    SELECT 'BB', id, value FROM BB UNION ALL 
    SELECT 'CC', id, value FROM CC UNION ALL 
    SELECT 'DD', id, value FROM DD UNION ALL 
    SELECT 'EE', id, value FROM EE 
), 
ReadyForJoin AS (
    SELECT 
    id 
    , tableName 
    , value 
    FROM TableAUnpivot 
    JOIN DataTablesCombined 
    USING (tableName, id) 
), 
LookLikeAJoin AS (
    SELECT 
    * 
    FROM ReadyForJoin 
    PIVOT (MIN(value) FOR tableName 
     IN ('AA' AS AA, 'BB' AS BB, 'CC' AS CC, 'DD' AS DD, 'EE' AS EE)) 
) 
SELECT 
    * FROM LookLikeAJoin ORDER BY id 
; 

, который для данных выборки является

| ID |  AA |  BB |  CC |  DD |  EE | 
|-----|--------|--------|--------|--------|--------| 
| 123 | (null) | (null) | aaa | aaa | aaa | 
| 456 | bbb | bbb | (null) | (null) | (null) | 
| 789 | ccc | (null) | ccc | (null) | (null) | 

, где клетка отличается от NULL, тогда и только тогда:

  • было установлено в TableA и
  • было присвоено значение в соответствующей таблице AA через EE.

NB: Для этого, чтобы работать на всех, все s в TableA должен быть NULL маньяков.

При условии, что это идет в правильном направлении: как продолжить дальше?

Самый простой способ, как представляется, заменить окончательный SELECT на

SELECT 
    id, COALESCE(aa, bb, cc, dd, ee) value FROM LookLikeAJoin WHERE id != 456 ORDER BY id 
; 

(Учитывая, в аЬс для опечатка ...)

Смотрите выше action: SQL Fiddle.

Прокомментируйте, если и как это требует регулировки/дальнейшие детали.

+0

Большое спасибо! Вы находитесь на месте с требованием, и похоже, что это будет работать нормально. Я продолжу проверку этого и дам вам знать, если что-то еще понадобится. –

1

Вы присоединяетесь к всем таблицам и вытащите нужные столбцы. Обратите внимание, что SQL-запрос определяет набор столбцов, которые фиксированы для всех строк. Таким образом, на самом деле нет смысла «условно» присоединяться к таблице. Где вы собираетесь использовать столбцы?

Для ваших целей вы хотите left join:

select <columns that you want> 
from table t left join 
    students s 
    on . . . left join 
    classes c 
    on . . . left join 
    . . . 

EDIT:

Ваш пересмотрела вопрос является очень разные, и должен был еще один вопрос. Но, я думаю, что это делает то, что вы хотите:

select 
from a join 
    (select 1 as aa, 0 as bb, 0 as cc, 0 as dd, 0 as ee, id, value from aa union all 
     select 0 as aa, 1 as bb, 0 as cc, 0 as dd, 0 as ee, id, value from bb union all 
     select 0 as aa, 0 as bb, 1 as cc, 0 as dd, 0 as ee, id, value from cc union all 
     select 0 as aa, 0 as bb, 0 as cc, 1 as dd, 0 as ee, id, value from dd union all 
     select 0 as aa, 0 as bb, 0 as cc, 0 as dd, 1 as ee, id, value from ee 
    ) o 
    on a.id = o.id and 
     a.aa = o.aa and a.bb = o.bb and a.cc = o.cc and a.dd = o.dd and a.ee = o.ee; 
+0

Левое соединение не будет работать. Я обновил вопрос, чтобы быть более ясным. –

+0

Спасибо за ответ. Я попробую это. Однако таблица с 1 и 0 небольшое подмножество фактической таблицы. Фактическая таблица будет содержать еще много строк и комбинаций. –

+0

@ ZAKB ... Можно ответить только на заданный вами вопрос. Если у вас другой вопрос, вы должны задать ему другой вопрос. –