查看 Table 超过 Language/Client/Status Table

View Table over Language/Client/Status Table

我想通过视图 table、MainView 来简化我的数据,但我很难搞清楚。

我有一个 Fact table 是特定于客户、语言和状态的。 Fact table 中的 ID 来自 FactLink table,它只有一个 FactLinkID 列。 Status table 有一个 Order 列需要显示在聚合视图中,而不是 StatusID。我的 Main table 在多个列中引用了 Fact table。

最终目标是能够比以前更简单地通过 LanguageIDStatusOrderClientID 的复合索引查询视图 table , 抓取最大的指定 StatusOrder 和指定的 ClientIDClientID 1。所以,这就是我希望用视图 table.

简化的内容

所以,

主要

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

FactLink

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 table:

的列来实现它
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 链接列的 table 上创建视图时,它大大简化了事情,但事实证明将其扩展到两个或更多列很困难!

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

不确定这是解决此问题的最有效或最优雅的方法。但我终于想到了一个办法。下面的解决方案的问题是它不能再被索引。所以,现在要弄清楚如何做到这一点,而不必将其包装在派生的 table.

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