Оператор SQL - динамическое объединение столбцов из разных таблиц в один набор результатов - PullRequest
0 голосов
/ 03 октября 2011

Я не уверен, что это возможно с SQL (скажем, мы выполняем на DB2) - на самом деле, я бы сказал, что это не так, но подумал, что я бы хотел спросить некоторых людей, которые более опытны в SQL, чем я. Я описал проблему и то, что я хотел бы случиться ниже. Пожалуйста, дайте мне знать, если вы видите способ сделать это, если нет, я думаю, я иду по пути извлечения данных в пакетном режиме или что-то подобное. Большое спасибо.

MAIN TABLE

| REF_TABLE   | RECORD_NO      | GROUPID  |
|   TABLE1    |   1            |  BLUE    |
|   TABLE1    |   2            |  BLUE    |
|   TABLE2    |   3            |  GREEN   |
|   TABLE3    |   4            |  BLUE    |
|   TABLE2    |   5            |  GREEN   |
|   TABLE4    |   6            |  BLUE    |

TABLE1

|  RECORD_NO |   NAME    | VALUE     |
|   1        |   NAMEX   |  RANDOM1  |
|   2        |   NAMEY   |  RANDOM2  |

TABLE2

|  RECORD_NO |   NAME    |  VALUE     |
|   3        |   NAMEB   |  RANDOM10  |
|   5        |   NAMEC   |  RANDOM9   |

TABLE3

| RECORD_NO  | NAME      | VALUE      |
|    4       |   NAMET   |  RANDOM77  |

TABLE4

| RECORD_NO  | NAME      | VALUE      |
|   6        |   NAMET   |  RANDOM77  |
|   7        |   NAMEZ   |  RANDOM99  |

Итак, у меня есть несколько критериев для запроса ОСНОВНОЙ ТАБЛИЦЫ, например

SELECT REF_TABLE, RECORD_NUMBER WHERE GROUPID = 'BLUE'

Но я также хочу включить соответствующие значения из других таблиц, на которые ссылаются через REF_TABLE. Таким образом, результат будет:

| REF_TABLE   | RECORD_NUMBER  | NAME    | VALUE     |
|   TABLE1    |   1            | NAMEX   |  RANDOM1  |
|   TABLE1    |   2            | NAMEY   |  RANDOM2  |
|   TABLE3    |   4            | NAMET   |  RANDOM77 |
|   TABLE4    |   6            | NAMET   |  RANDOM77 |

В этом случае столбцы TABLE1, TABLE3 и TABLE4 объединяют свои имена и значения в один набор результатов. Таблица, конечно, извлекается из столбца ref_table главной таблицы. Список таблиц ссылок конечный, поэтому я могу жестко закодировать имена таблиц в инструкциях SQL в запросе (чтобы избежать динамической установки имени таблицы), например. IF TABLE1 SELECT FROM SCHEMA.TABLE1 (maybe CASE).

Реструктуризация таблиц невозможна, и число возвращаемых результатов может составлять 10000.

Желательно, чтобы все это было одним запросом.

Спасибо.

Ответы [ 2 ]

1 голос
/ 03 октября 2011

Один может также вывести союзы из ответа Хемаля Паньи из поля зрения и в ваш запрос ...

SELECT record_no, groupid, name, value
FROM main_table INNER JOIN ref_table1 on main_table.record_no = ref_table1.record_no
WHERE main_table.ref_table = 'TABLE1'

UNION ALL

SELECT record_no, groupid, name, value
FROM main_table INNER JOIN ref_table2 on main_table.record_no = ref_table2.record_no
WHERE main_table.ref_table = 'TABLE2'

UNION ALL

etc, etc...

Это, вероятно, намного быстрее, чем tryign, чтобы использовать CASE ...

SELECT
  main_table.record_no,
  main_table.groupid,
  CASE main_table.ref_table WHEN 'Table1' THEN Table1.name
                            WHEN 'Table2' THEN Table2.name
                            etc, etc
  END,
  CASE main_table.ref_table WHEN 'Table1' THEN Table1.value
                            WHEN 'Table2' THEN Table2.value
                            etc, etc
  END
FROM
  main_table
LEFT JOIN
  Table1
    ON  main_table.record_no = Table1.record_no
    AND main_table.ref_table = 'Table1'
LEFT JOIN
  Table2
    ON  main_table.record_no = Table2.record_no
    AND main_table.ref_table = 'Table2'
etc, etc


Я бы, однако, рекомендовал против любого из этих вариантов. Такое ощущение, что ваша схема разработана с учетом естественного поведения SQL. Вам может понадобиться новая структура или лучше подходить для другой среды. Однако, не зная больше деталей, невозможно дать совет относительно естественной реляционной структуры, которая бы отвечала вашим потребностям без необходимости такого «условного объединения».


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

1 голос
/ 03 октября 2011

использование case, безусловно, возможно и должно работать.

Другой вариант -

create view REF_TABLE as
  select 'TABLE1' as TABLE_NAME, RECORD_NO, NAME, VALUE from TABLE1 
  UNION select 'TABLE2' as TABLE_NAME, RECORD_NO, NAME, VALUE from TABLE2 
  ...

А затем

select RECORD_NO, GROUPID, NAME, VALUE 
from MAIN_TABLE 
  join REF_TABLE on MAIN_TABLE.REF_TABLE = REF_TABLE.TABLE_NAME and
                    MAIN_TABLE.RECORD_NO = REF_TABLE.RECORD_NO

и т. Д.

РЕДАКТИРОВАТЬ:

Не знаете, почему выхочу избежать зрения. Учитывая вашу схему, она может быть полезна и в других местах и ​​даст вам значительный выигрыш в производительности, если вы сможете материализовать свои представления (посмотрите, если вы не знаете, какие они есть)

Запросиспользование кейса было бы чем-то следующим.Я не очень четко понимаю синтаксис SQL-сервера, поэтому у вас будет над этим работать.

select m.RECORD_NO, m.GROUP_ID,
case when REF_TABLE = 'TABLE1' then t1.NAME, t1.VALUE
else when REF_TABLE = 'TABLE2' then t2.NAME, t2.VALUE
...
end case,
from MAIN_TABLE M
  left outer join TABLE1 T1 on M.RECORD_NO = T1.RECORD_NO
  left outer join TABLE2 T2 on M.RECORD_NO = T2.RECORD_NO
....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...