Это можно сделать, но у вас должен быть источник всех допустимых типов и предполагается, что пользователь/приложение будет запрашивать представление только для допустимого типа. Другими словами, предположим, что таблица T является вашей «таблицей типов», и все ваши таблицы B, C и D имеют (или могут иметь) FK, определенные на T.
В этом случае ваш вид опр. было бы:
CREATE OR REPLACE VIEW V AS
SELECT A.ID, BT.TYPE BTYPE, CT.TYPE CTYPE, DT.DTYPE DTYPE, ...
FROM A
CROSS JOIN T BT
CROSS JOIN T CT
CROSS JOIN T DT
LEFT JOIN B ON A.ID = B.ID AND B.TYPE = BT.TYPE
LEFT JOIN C ON A.ID = C.ID AND C.TYPE = CT.TYPE
LEFT JOIN D ON A.ID = D.ID AND D.TYPE = DT.TYPE;
Конечно, если бы в модели был фиксированный набор допустимых типов, вы могли бы заменить T на (SELECT 'X' TYPE FROM DUAL UNION ALL SELECT 'Y' FROM DUAL UNION ALL ...)
Единственная разница между:
SELECT
-- Some fields.
FROM a
LEFT JOIN b ON a.id = b.id AND b.type = x
LEFT JOIN c ON a.id = c.id AND c.type = y
LEFT JOIN d ON a.id = d.id AND d.type = z
и
SELECT * FROM V WHERE B_TYPE = X AND C_TYPE = Y AND D_TYPE = Z
если бы X, Y или Z не были "действительными" типами (в этом случае определение представления не вернуло бы строк).
РЕДАКТИРОВАТЬ: Уточнение за комментарий; Я предполагал, что «тип» является общим доменом для таблиц B, C и D. Если B.type отличается от C.type (т. е. B.TYPE — это NUMERIC(9), а C.type — это VARCHAR(2) и D.TYPE имеет значение NUMERIC(1)), тогда перекрестные соединения должны ссылаться на каждый «набор допустимых значений типа» независимо:
CREATE OR REPLACE VIEW V AS
SELECT A.ID, BT.TYPE BTYPE, CT.TYPE CTYPE, DT.DTYPE DTYPE, ...
FROM A
CROSS JOIN (--SELECT ALL DISTINCT VALID B.TYPE VALUES--) BT
CROSS JOIN (--SELECT ALL DISTINCT VALID C.TYPE VALUES--) CT
CROSS JOIN (--SELECT ALL DISTINCT VALID D.TYPE VALUES--) DT
LEFT JOIN B ON A.ID = B.ID AND B.TYPE = BT.TYPE
LEFT JOIN C ON A.ID = C.ID AND C.TYPE = CT.TYPE
LEFT JOIN D ON A.ID = D.ID AND D.TYPE = DT.TYPE;
Тем не менее, у вас действительно есть такое же ограничение: встроенное в определение представления. должен быть некоторым конечным источником «всех допустимых типов B», «всех допустимых типов C» и «всех допустимых типов D». За исключением этого, это невозможно в чистом SQL (на самом деле, в терминах чистого SQL это становится неразрешимой проблемой — представление, которое поддерживает фильтрацию по любой мыслимой комбинации значений без фильтров, должно возвращать все мыслимые комбинации значений. ..)
person
KevinKirkpatrick
schedule
13.11.2015
left join
делает это довольно сложным. Я мог бы предложить вам задать другой вопрос с лучшими примерами таблиц и типов предложенийwhere
, которые вы хотите поддерживать. Может быть способ сделать это. Просто переключиться наinner join
— одно из возможных решений. - person Gordon Linoff   schedule 13.11.2015INNER JOIN
, но поскольку я всегда хочу возвращать все строки из левой таблицы (a
), думаю, мне нуженLEFT JOIN
. - person Anders   schedule 13.11.2015where c.type is null or c.type = x
- person a_horse_with_no_name   schedule 13.11.2015c
есть мах дляa
, гдеtype
равноw
. Тогда эта строка не будет включена в вопрос, посколькуc.type
будетw
, а неnull
илиx
. Мне нужно, чтобы каждая строка вa
была включена в результат. - person Anders   schedule 13.11.2015