【问题标题】:What's the best way to union two queries with distinct values in a single column, prioritizing the first query?在单个列中合并两个具有不同值的查询并优先考虑第一个查询的最佳方法是什么?
【发布时间】:2013-09-30 08:31:46
【问题描述】:

需要在 Oracle 和 SQL Server 之间与数据库无关,尽管我也不介意听到特定于 SQL Server 的示例。

我确定标题根本不清楚,所以让我解释一下我的想法。我在想两个问题。第一个可能会从给定表中提取一堆数据,包括主键。第二个只会拉入每个主键并将所有其他列留空。

然后我想以这样一种方式将它们联合在一起,即每当第一个查询中缺少主键时,第二个查询中的行就会被拉入。否则,如果主键存在于第一个查询中,第二个查询中的行被忽略。

快速示例:

第一个查询拉入两列(第一列是主键):

1   1

2   1

第二个查询拉进来:

1   NULL

2   NULL

3   NULL

所以我希望整个查询都被引入:

1  1

2  1

3  NULL

在性能方面,实现这一目标的最佳方法是什么?考虑一个可能有大量行和列的示例,第一个查询可能非常消耗性能(尽管第二个当然应该总是很简单,只需从列表中提取主键并填充其余部分列输出为 NULL 或静态值)。

【问题讨论】:

  • SSIS 查找转换可能是一个好方法。它可以比较数据源并根据条件选择数据。 SSIS Oracle Attunity 可以非常快地将数据加载到 Oracle 或从 Oracle 加载数据,但它需要 Enterprise SQL 版本。通过链接服务器会很慢。

标签: sql sql-server performance oracle


【解决方案1】:

您不能使用联合,因为 SQL 会认为 1、2 和 1,NULL 是不同的。

不知道您的架构,我会在伪代码中尝试以下操作:

select *
from query_1
union all
select primary_key
from query_2
where query_2.PK not in(select PK from query_1)

这只会返回 query_2 中不在 query_1 中的主键,并为您提供一个干净的联合,其中 query_1 结果优先于 query_2 结果。只为第一个查询选择主键应该既快速又简单,但如果不是这种情况,请告诉我,我可以尝试根据您的架构提出更复杂的查询。

【讨论】:

  • 我喜欢这种方法,但“不加入”往往很慢。 sql server 和 oracle 都支持 minus 关键字,因此该部分可以是 query_2.pk 所在的位置(从 query_2 中选择 pk 减去从 query_1 中选择 pk)
  • @DanBracuk 这是真的。不确定他的数据是否会运行得更快,但它有机会。但是,MINUS 仅适用于 Oracle,在 SQL Server 中除外。
  • 所以我想到了这一点,但就像我上面所说的那样,查询 1 可能是性能密集型的,现在我们运行它两次加上不输入。
  • @JS 我希望只选择主键会很快。如果没有,请尝试 bluefeet 的解决方案。如果这不起作用,请告诉我们,我们可以考虑使用公用表表达式或临时表。这将让您缓存 query_1 的结果并重新使用临时表中的数据而不是运行两次。
【解决方案2】:

听起来你想在两个表或查询上使用FULL OUTER JOIN

select 
  coalesce(q1.col1, q2.col1) col1,
  coalesce(q1.col2, q2.col2) col2
from query1 q1
full outer join query2 q2
  on q1.col1 = q2.col1;

SQL Fiddle with Demo

这将连接主键列上的两个查询(示例查询中的col1),然后您可以在列上使用COALESCE 以返回col1col2 的第一个非空值等。

【讨论】:

  • 哦,我喜欢。谢谢。
猜你喜欢
  • 2021-09-27
  • 2021-02-07
  • 2019-09-20
  • 1970-01-01
  • 2021-10-15
  • 2020-02-18
  • 2017-05-18
  • 1970-01-01
相关资源
最近更新 更多