繁体   English   中英

在 SQL 服务器的视图中使用临时表/临时变量或 CTE 的替代方法

[英]Alternative to using temp table/temp variables or CTE inside a view in SQL Server

我有一个场景,我必须创建一个视图,其中包含一堆各种 select 语句的 UNION。

SELECT DISTINCT ISNULL(ID,'ID') as Id, 
ISNULL(FIRST_NAME,'unknown') + ':' + 'Unknown' AS label,
ISNULL(VALUE,'unknown') AS [value]
  FROM [test].[emp].[OrgView]
  UNION
SELECT DISTINCT ISNULL(EMP_ID,'ID') as Id, 
ISNULL(LAST_NAME,'unknown') + ':' + 'Unknown' AS label,
ISNULL(VALUE,'unknown') AS [value]
  FROM [test].[emp].[OrgView]
  UNION
SELECT DISTINCT ISNULL(LICENSE,'ID') as Id, 
ISNULL(COMPANY,'unknown') + ':' + 'Unknown' AS label,
ISNULL(VALUE,'unknown') AS [value]
  FROM [test].[emp].[OrgView]
.
.
.
.
.
10 such selects

我尝试使用临时变量和临时表来避免对数据库进行 10 次不同的调用,但看起来它们在下面的视图中不起作用。

Create View [test].[emp].[MainView]
AS
select * into #tempTable from [test].[emp].[OrgView]
SELECT DISTINCT ISNULL(ID,'ID') as Id, 
ISNULL(FIRST_NAME,'unknown') + ':' + 'Unknown' AS label,
ISNULL(VALUE,'unknown') AS [value]
  FROM #tempTable
  UNION
SELECT DISTINCT ISNULL(EMP_ID,'ID') as Id, 
ISNULL(LAST_NAME,'unknown') + ':' + 'Unknown' AS label,
ISNULL(VALUE,'unknown') AS [value]
  FROM #tempTable
  UNION
SELECT DISTINCT ISNULL(LICENSE,'ID') as Id, 
ISNULL(COMPANY,'unknown') + ':' + 'Unknown' AS label,
ISNULL(VALUE,'unknown') AS [value]
  FROM #tempTable

不能将公用表表达式 (CTE) 与上述查询一起使用,因为它只能用于一次查找,而不能用于 rest 9。

在 Sql 服务器中做这件事的更好方法是什么?

我认为您想要CROSS APPLY而不是UNION 我有点不清楚你想把逻辑放在哪里,但这是一个想法:

SELECT DISTINCT v.Id, 
       (COALESCE(FIRST_NAME, 'unknown') + ':' + 'Unknown') AS label,
       COALESCE(VALUE,'unknown') AS [value]
FROM #tempTable CROSS APPLY
     (VALUES (COALESCE(ID, 'ID')),
             (COALESCE(EMP_ID, 'ID')),
             (COALESCE(LICENCE_ID, 'ID')),
             . . .
     ) v(id)

         

当您使用VIEW时,无论视图内部是什么,它都是对数据库的 1 调用。 因此无需使用临时表或表变量等。因此,您的原始查询在VIEW中可以正常工作,并且将是单个 SQL 调用。

CREATE VIEW [test].[emp].[MainView]
AS
SELECT .... FROM [test].[emp].[OrgView]
UNION
SELECT .... FROM [test].[emp].[OrgView]
....

它的效率是另一回事,我无法对此发表评论,因为您的问题中没有发布完整的逻辑。 但是,如果所有SELECT语句中的所有JOINWHERE子句彼此相似/兼容,那么您可以将它们与@gordon-linoff 建议的CROSS APPLY结合使用,但我看到您提到其中一个查询正在使用其他查询未共享查找,因此可能会也可能不会(您的帖子缺少详细信息)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM