我想用视图表简化数据,MainView但是很难弄清楚。
MainView
我有一个Fact特定于客户,语言和状态的表。该Fact表中的ID来自FactLink仅具有一FactLinkID列的表。该Status表的一Order列需要显示在汇总视图中,而不是StatusID。我Main的Fact表在多列中引用了该表。
Fact
FactLink
FactLinkID
Status
Order
StatusID
Main
最终的目标是能够通过的复合索引查询视图表LanguageID,StatusOrder,ClientID更简单地比我之前,抓住了最大的指定StatusOrder和指定ClientID或ClientID1。所以,这就是我希望以期简化桌子。
LanguageID
StatusOrder
ClientID
所以,
主要的
ID | DescriptionID | DisclaimerID | Other ----+---------------+--------------+------------- 50 | 1 | 2 | Blah 55 | 4 | 3 | Blah Blah
事实
FactID | LanguageID | StatusID | ClientID | Description -------+------------+----------+----------+------------ 1 | 1 | 1 | 1 | Some text 1 | 2 | 1 | 1 | Otro texto 1 | 1 | 3 | 2 | Modified text 2 | 1 | 1 | 1 | Disclaimer1 3 | 1 | 1 | 1 | Disclaimer2 4 | 1 | 1 | 1 | Some text 2
事实链接
ID -- 1 2 3 4
状态
ID | Order ---+------ 1 | 10 2 | 100 3 | 20
主视图
MainID | StatusOrder | LanguageID | ClientID | Description | Disclaimer | Other -------+-------------+------------+----------+---------------+-------------+------ 50 | 10 | 1 | 1 | Some text | Disclaimer1 | Blah 50 | 10 | 2 | 1 | Otro texto | NULL | Blah 50 | 20 | 1 | 2 | Modified text | NULL | Blah 55 | 10 | 1 | 1 | Some text 2 | Disclaimer2 | Blah Blah
这是我仅用一个引用该Fact表的列来实现它的方法:
DROP VIEW IF EXISTS dbo.KeywordView GO CREATE VIEW dbo.KeywordView WITH SCHEMABINDING AS SELECT t.KeywordID, f.ClientID, f.Description Keyword, f.LanguageID, s.[Order] StatusOrder FROM dbo.Keyword t JOIN dbo.Fact f ON f.FactLinkID = t.KeywordID JOIN dbo.Status s ON f.StatusID = s.StatusID GO CREATE UNIQUE CLUSTERED INDEX KeywordIndex ON dbo.KeywordView (KeywordID, ClientID, LanguageID, StatusOrder)
我之前的查询查询了除此以外的所有内容StatusOrder。但是添加StatusOrder似乎会使事情复杂化。这是我先前的查询,不含StatusOrder。当我在只有一个Fact链接列的表上创建视图时,它大大简化了事情,但是事实证明将其扩展到两个或更多列是困难的!
SELECT Main.ID, COALESCE(fDescription.Description, dfDescription.Description) Description, COALESCE(fDisclaimer.Description, dfDisclaimer.Description) Disclaimer, Main.Other FROM Main LEFT OUTER JOIN Fact fDescription ON fDescription.FactLinkID = Main.DescriptionID AND fDescription.ClientID = @clientID AND fDescription.LanguageID = @langID AND fDescription.StatusID = @statusID -- This actually needs to get the largest `StatusOrder`, not the `StatusID`. LEFT OUTER JOIN Fact dfDescription ON dfDescription.FactLinkID = Main.DescriptionID AND dfDescription.ClientID = 1 AND dfDescription.LanguageID = @langID AND dfDescription.StatusID = @statusID ... -- Same for Disclaimer WHERE Main.ID = 50
不确定这是否是解决此问题的最有效或最优雅的方法。但是我终于想到了一种方法。以下解决方案的问题是无法再对其进行索引。因此,现在想一想如何做到这一点,而不必将其包装在派生表中。
SELECT x.ID, x.StatusOrder, x.LanguageID, x.ClientID, x.Other, MAX(x.Description), MAX(x.Disclaimer) FROM ( SELECT Main.ID, s.StatusOrder, f.LanguageID, f.ClientID, f.Description, NULL Disclaimer, Main.Other FROM Main JOIN Fact f ON f.FactID = Main.DescriptionID JOIN Status s ON s.StatusID = f.StatusID UNION ALL SELECT Main.ID, s.StatusOrder, f.LanguageID, f.ClientID, NULL Description, f.Description Disclaimer, Main.Other FROM Main JOIN Fact f ON f.FactID = Main.DisclaimerID JOIN Status s ON s.StatusID = f.StatusID ) x GROUP BY x.ID, x.StatusOrder, x.LanguageID, x.ClientID, x.Other