首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Server 2008 R2中的long UNION语句中类似的WHERE子句

Server 2008 R2中的long UNION语句中类似的WHERE子句
EN

Stack Overflow用户
提问于 2013-03-04 21:21:13
回答 4查看 943关注 0票数 0

在存储过程中,我需要将长INSERT的结果转换为临时表。WHERE子句对于处于SELECT DISTINCT中的所有表都是相同的。

简化为可读性,如下所示:

代码语言:javascript
运行
复制
INSERT INTO #MyTemp
  SELECT col1, col2, col3 FROM tab1 WHERE col1 in (SELECT DISTINCT myId FROM TabIds) UNION
  SELECT col1, col2, col3 FROM tab2 WHERE col1 in (SELECT DISTINCT myId FROM TabIds) UNION
  SELECT col1, col2, col3 FROM tab3 WHERE col1 in (SELECT DISTINCT myId FROM TabIds) UNION
  .
  .
  .
  SELECT col1, col2, col3 FROM tab20 WHERE col1 in (SELECT DISTINCT myId FROM TabIds) 

虽然TabIds是一个小的临时表,通常有3-6条记录,但这似乎是非常不方便的。

有更好的方法吗?

总结我的问题:

我是否可以只做一次SELECT DISTINCT myId FROM TabIds,并将其分配给一种数组/列表/集(而不是另一个临时表),然后在WHERE子句中使用它,如果有这种方法,那么对于这样一个小的(3-6 recs)临时表来说真的重要吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-03-06 14:21:25

我忽略了您的要求(“不对另一个临时表”),因为我不认为这是有充分根据的。试着看看这个解决方案是否提供了更好的性能:

代码语言:javascript
运行
复制
SELECT i = myId
  INTO #x 
  FROM dbo.TabIds -- please always use schema prefix
  GROUP BY myId;

CREATE UNIQUE CLUSTERED INDEX x ON #x(i);

INSERT INTO #MyTemp(col1, col2, col3)
SELECT col1, col2, col3
FROM
(
  SELECT col1, col2, col3 FROM dbo.tab1 WHERE EXISTS -- likely better than IN
    (SELECT 1 FROM #x WHERE i = tab1.col1)
  UNION ALL 
  SELECT col1, col2, col3 FROM dbo.tab2 WHERE EXISTS 
    (SELECT 1 FROM #x WHERE i = tab2.col1)
  UNION ALL

  ...

  UNION ALL
  SELECT col1, col2, col3 FROM dbo.tab20 WHERE EXISTS 
    (SELECT 1 FROM #x WHERE i = tab20.col1)
) AS x
GROUP BY col1, col2, col3; -- likely more efficient than `UNION` to remove dupes

当然,如果在所有20个表中对col1进行索引,并且该索引包括col2col3,这将是最好的。

我建议使用视图的原因并不是因为我认为它会使代码运行得更快。只需创建一个视图,为您生成此UNION,从而简化此代码(以及重复此单调UNION的任何其他代码)。这是为了方便,而不是为了性能--尽管我需要明确的是,使用视图并不会神奇地使事情变慢。有时我可以,但这是一个危险和不合逻辑的理由,以避免意见。

最后,我强烈地考虑正常化。为什么这20张不同的桌子一开始都可以放在一张桌子上?

代码语言:javascript
运行
复制
CREATE TABLE dbo.Normal
(
  SourceTableID INT,
  col1 <data type>,
  col2 <data type>,
  col3 <data type>
);

-- indexes / constraints

INSERT dbo.Normal
SELECT 1, col1, col2, col3 FROM dbo.tab1
UNION ALL
SELECT 2, col1, col2, col3 FROM dbo.tab2
UNION ALL

...

UNION ALL
SELECT 20, col1, col2, col3 FROM dbo.tab20;

现在,您的所有查询都可以简单地引用这个新表。如果您通常只查找其中的一个源(例如tab5),那么在SourceTableID上进行索引或分区将是有用的。

票数 2
EN

Stack Overflow用户

发布于 2013-03-04 21:25:38

从概念上讲,对于一次性和数据加载来说,您所做的一切都很好。不过,我希望这不是生产代码中更大的模式的一部分。

票数 2
EN

Stack Overflow用户

发布于 2013-03-04 21:33:10

您要寻找的是一个公共表表达式。

我的rusty有点生疏,但是使用CTE,您的查询可能会如下所示:

代码语言:javascript
运行
复制
WITH TabIds_CTE AS (SELECT DISTINCT myId FROM TabIds)
INSERT INTO #MyTemp
SELECT col1, col2, col3 FROM tab1 WHERE col1 IN (SELECT * FROM TabIds_CTE)
UNION ALL ...
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15211358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档