Я читал документацию и просматривал часто задаваемые вопросы и не нашел ответа на этот вопрос, что, вероятно, означает, что это невозможно сделать. Моя реальная ситуация немного сложнее, но я попытаюсь упростить ее для этого вопроса. Для каждого из прошлых лет у меня есть таблицы заголовков/деталей с внешним ключом, связывающим их. Дата года указана в заголовке! Я хочу иметь возможность запрашивать все таблицы, объединенные в разные годы.
Я настроил представления, соответствующие формату «SELECT + UNION ALL». Я также наложил проверочные ограничения на таблицы заголовков, чтобы ограничить их значения соответствующим годом. Это позволяет оптимизатору запросов SQL Server запрашивать только определенные таблицы при выполнении запроса, ограниченного предложением WHERE. Потрясающий. До этого момента эту информацию можно было найти везде и всюду, выполнив поиск Partitioned Views.
Я хочу выполнить такую же оптимизацию запросов с подробными таблицами, но не могу понять. В подробной записи нет ничего, что указывало бы, к какому году она принадлежит, без соединения с записью заголовка; Это означает, что ограничение внешнего ключа — единственное ограничение, от которого я должен отказаться.
Единственное решение, о котором я подумал, — это добавить столбец «год» в подробные таблицы, а затем добавить еще одно предложение where к запросам. Могу ли я что-нибудь сделать, чтобы создать секционированное представление таблиц сведений, используя существующее ограничение внешнего ключа?
Вот некоторые DDL для справки:
CREATE TABLE header2008 (
hid INT PRIMARY KEY,
dt DATE CHECK ('2008-01-01' <= dt AND dt < '2009-01-01')
)
CREATE TABLE header2009 (
hid INT PRIMARY KEY,
dt DATE CHECK ('2009-01-01' <= dt AND dt < '2010-01-01')
)
CREATE TABLE detail2008 (
did INT PRIMARY KEY,
hid INT FOREIGN KEY REFERENCES header2008(hid),
value INT
)
CREATE TABLE detail2009 (
did INT PRIMARY KEY,
hid INT FOREIGN KEY REFERENCES header2009(hid),
value INT
)
GO
CREATE VIEW headerAll AS
SELECT * FROM header2008 UNION ALL
SELECT * FROM header2009
GO
CREATE VIEW detailAll AS
SELECT * FROM detail2008 UNION ALL
SELECT * FROM detail2009
GO
--This only hits the header2008 table (GOOD)
SELECT *
FROM headerAll h
WHERE dt = '2008-04-04'
--This hits the header2008, detail2008, and detail 2009 tables. (BAD)
SELECT *
FROM headerAll h
INNER JOIN detailAll d ON h.hid = d.hid
WHERE dt = '2008-04-04'