Резюме
Как сделать так, чтобы непрограммисты могли написать запрос, подобный следующему?
select
table_name.*
, foreign_table_1.name
, foreign_table_2.name
from
table_name
left outer join foreign_table foreign_table_1 on foreign_table_1.id = foreign_1_id
left outer join foreign_table foreign_table_2 on foreign_table_2.id = foreign_1_id
;
Контекст
У меня такая ситуация:
create table table_name (
id integer primary key autoincrement not null
, foreign_key_1_id integer not null
, foreign_key_2_id integer not null
, some_other_column varchar(255) null
);
create table foreign_table (
id integer primary key autoincrement not null
, name varchar(255) null
);
... в котором оба foreign_key_1_id
и foreign_key_2_id
ссылаются foreign_table
. (Очевидно, это упрощено и абстрагировано.) Чтобы запросить и получить соответствующие значения, я мог бы сделать что-то вроде этого:
select
table_name.*
, foreign_table_1.name
, foreign_table_2.name
from
table_name
left outer join foreign_table foreign_table_1 on foreign_table_1.id = foreign_1_id
left outer join foreign_table foreign_table_2 on foreign_table_2.id = foreign_1_id
;
(то есть псевдоним foreign_table
в соединении, чтобы правильно связать вещи.) Это отлично работает. Однако некоторые из моих клиентов хотят использовать SQL Maestro для запроса таблиц. Эта программа использует информацию внешнего ключа для связывания таблиц с помощью довольно простого интерфейса («Visual Query Builder»). Например, пользователь может выбрать несколько таблиц, и SQL Maestro заполнит объединения, как показано здесь:
(источник: sqlmaestro.com )
(это диаграмма с их сайта, просто для иллюстрации.)
Эта стратегия прекрасно работает, если внешние ключи ссылаются только на одну таблицу. Ситуация с множественными ссылками, кажется, сбивает с толку, потому что это скрежетает SQL следующим образом:
SELECT
table_name.some_other_column,
foreign_table.name
FROM
table_name
INNER JOIN foreign_table ON (table_name.foreign_key_1_id = foreign_table.id)
AND (table_name.foreign_key_2_id = foreign_table.id)
... потому что внешние ключи определены следующим образом:
create table table_name (
id integer primary key autoincrement not null
, foreign_key_1_id integer not null
, foreign_key_2_id integer not null
, some_other_column varchar(255) null
---------------------------
-- The part that changed:
---------------------------
, foreign key (foreign_key_1_id) references foreign_table(id)
, foreign key (foreign_key_2_id) references foreign_table(id)
);
create table foreign_table (
id integer primary key autoincrement not null
, name varchar(255) not null
);
Это проблема, потому что вы возвращаете только 1 foreign_table.name
значение, тогда как часто есть 2 отдельных значения.
Вопрос
Как мне определить внешние ключи, чтобы справиться с этой ситуацией? (Возможно ли это или имеет смысл сделать это? Я не думаю, что это будет иметь большое значение при проверке ограничений, поэтому я подумал, что по этой причине я не могу найти какую-либо информацию.) Мой конец цель состоит в том, чтобы сделать запрос этой информации легким для моих клиентов, и, хотя такая ситуация случается не каждый день, отнимает много времени / расстраивает необходимость помогать людям проходить через нее каждый раз, когда она появляется.
Если нет способа решить мою проблему с внешним ключом, можете ли вы предложить какие-либо альтернативы? У меня уже есть несколько способов получить от людей эту информацию через представления, но людям часто требуется больше гибкости, чем эта.