JOIN 3 沒有 Union ALL 的表,也沒有具有多個 ID 的嵌套查詢
不確定這是否可能,但我想在沒有
UNION ALL
或嵌套查詢的情況下加入具有多個 ID 的多個表。您可以在此處查看相關問題,該問題在表格視圖中顯示所有內容。我想創建一個table view
但不允許使用上面提到的內容。我已經想出瞭如何使用UNION ALL
.所以,我有一個
Main
表,它引用了一個名為Fact
. 該Fact
表包含可由 、 或 (revision) 引用LanguageID
的ClientID
數據StatusID
。Main
和表通過稱為(為簡單起見未顯示)Fact
的中間表相關聯。FactLink
MainView
我想得到的最終結果可索引表如下所示:主視圖
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 55 | 10 | 1 | 2 | NULL | Disclaimer3 | Blah Blah DROP TABLE IF EXISTS #main CREATE TABLE #main ( ID INT NOT NULL, DescriptionID INT NOT NULL, DisclaimerID INT NOT NULL, Other NVARCHAR(500) ) Drop table if exists #fact CREATE TABLE #fact ( FactID INT NOT NULL, LanguageID INT NOT NULL, StatusID INT NOT NULL, ClientID INT NOT NULL, Description NVARCHAR(MAX) ) DROP TABLE IF EXISTS #status CREATE TABLE #status ( StatusID INT NOT NULL, [Order] INT NOT NULL ) INSERT INTO #main (ID, DescriptionID, DisclaimerID, Other) VALUES (50, 1, 2, 'Blah'), (55, 4, 3, 'Blah Blah') INSERT INTO #fact (FactID, LanguageID, StatusID, ClientID, Description) VALUES (1, 1, 1, 1, N'Some text'), (1, 2, 1, 1, N'Otro texto'), (1, 1, 3, 2, N'Modified text'), (2, 1, 1, 1, N'Disclaimer1'), (3, 1, 1, 1, N'Disclaimer2'), (3, 1, 2, 1, N'Disclaimer3'), (4, 1, 1, 1, N'Some text 2') INSERT INTO #status (StatusID, [Order]) VALUES (1, 10), (2, 100), (3, 20)
這是我到目前為止所擁有的。但它不包括最後一個條目,也沒有考慮
StatusOrder
. 我不知道從這裡去哪裡。SELECT t.ID, t.Other, fDescription.Description, fDisclaimer.Description Disclaimer, COALESCE(fDescription.LanguageID, fDisclaimer.LanguageID) LanguageID, COALESCE(fDescription.ClientID, fDisclaimer.ClientID) ClientID, COALESCE(fDescription.StatusID, fDisclaimer.StatusID) StatusID FROM #main t JOIN #fact fDescription ON fDescription.FactID = t.DescriptionID LEFT OUTER JOIN #fact fDisclaimer ON fDisclaimer.FactID = t.DisclaimerID AND fDisclaimer.ClientID = fDescription.ClientID AND fDisclaimer.LanguageID = fDescription.LanguageID AND fDisclaimer.StatusID = fDescription.StatusID
我會按要求回答問題,但我希望它不會解決您的實際問題。您希望將您在另一篇文章中的查詢轉換為可以轉換為索引視圖的查詢。我看到的最大問題是您的數據模型要求將“事實”表的多行中的數據組合成單行。這樣的要求與索引視圖功能作鬥爭。許多T-SQL 限制似乎是圍繞停止這種類型的操作(以及其他操作)而設計的:
對於您的問題,該列表中最重要的條目是對 MAX、MIN、自聯接、子查詢、APPLY 和 UNPIVOT 的禁止。所有這些都可用於重寫您的 UNION ALL 查詢,但它們都不允許在索引視圖中使用。有一種方法可以重寫它,但你只會陷入更深的困境。您從以下查詢開始:
SELECT Main.ID, s.[Order], 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.[Order], 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;
至少有一種方法可以以有效的索引視圖定義的方式重寫該查詢。首先創建一個只有兩行的虛擬表:
CREATE TABLE DIM_NUMBERS (NUM INT NOT NULL); INSERT INTO DIM_NUMBERS VALUES (1), (2);
然後,您可以像這樣定義您的視圖:
CREATE VIEW dbo.X_VIEW WITH SCHEMABINDING AS SELECT Main.ID, s.[Order], f.LanguageID, f.ClientID, CAST(CASE WHEN d.NUM = 1 THEN f.Description ELSE NULL END AS NVARCHAR(2000)) [Description], CAST(CASE WHEN d.NUM = 2 THEN f.Description ELSE NULL END AS NVARCHAR(2000)) Disclaimer, Main.Other FROM dbo.Main CROSS JOIN dbo.DIM_NUMBERS d JOIN dbo.Fact f ON (f.FactID = Main.DescriptionID AND d.NUM = 1) OR (f.FactID = Main.DisclaimerID AND d.NUM = 2) JOIN dbo.Status s ON s.StatusID = f.StatusID; CREATE UNIQUE CLUSTERED INDEX IDX_X_VIEW ON dbo.X_VIEW (ID, [Order], LanguageID, ClientID, [Description], Disclaimer, Other);
我已重寫您的查詢以不使用 UNION ALL,但我沒有包含 GROUP BY,因為索引視圖中不允許使用 MIN 和 MAX。沒有任何聚合函式可以幫助您,因為您有一個 NVARCHAR 列。如果您有一個數字列,那麼您可能可以使用 SUM(COALESCE(COLUMN_NAME, 0)) 列來解決這個問題,但您不能將 SUM 聚合應用於 NVARCHAR。
我不會嘗試將查詢硬塞到索引視圖定義中,而是嘗試考慮其他解決方案。您可以將結果儲存在表格中嗎?根據描述列的長度,該列與索引視圖之間的空間差異可能不會那麼大。你能以某種有幫助的方式改變數據模型嗎?