Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SQL中实现这种连接?_Sql_Sql Server_Join - Fatal编程技术网

如何在SQL中实现这种连接?

如何在SQL中实现这种连接?,sql,sql-server,join,Sql,Sql Server,Join,如何在SQL中实现这种连接 表1 +----+-----------+-----------+---------+ | ID | FILTER1 | FILTER2 | DATA1 | | 1 | filter1-A | filter2-A | data1-A | | 2 | filter1-B | filter2-B | data1-B | +----+-----------+-----------+---------+ 表2 +----+-----------+------

如何在SQL中实现这种连接

表1

+----+-----------+-----------+---------+
| ID | FILTER1   | FILTER2   | DATA1   |
| 1  | filter1-A | filter2-A | data1-A |
| 2  | filter1-B | filter2-B | data1-B |
+----+-----------+-----------+---------+
表2

+----+-----------+-----------+---------+
| ID | FILTER1   | FILTER2   | DATA1   |
| 1  | filter1-B | filter2-B | data2-B |
| 2  | filter1-C | filter2-C | data2-C |
+----+-----------+-----------+---------+
结果

+------------+-----------+---------+---------+
| FILTER1    | FILTER2   | DATA1   | DATA2   | 
| filter1-A  | filter2-A | data1-A | NULL    | 
| filter1-B  | filter2-B | data1-B | data2-B | 
| filter1-C  | filter2-C | NULL    | data2-C | 
+------------+-----------+---------+---------+

这称为完全外部联接

SELECT 
  ISNULL(T1.FILTER1, T2.FILTER1) AS FILTER_1, 
  ISNULL(T1.FILTER2, T2.FILTER2) AS FILTER_2,
  T1.DATA1 AS DATA_1, 
  T2.DATA1 AS DATA_2
FROM TABLE1 T1
FULL OUTER JOIN TABLE2 T2
  ON T1.FILTER1 = T2.FILTER1
 AND T1.FILTER2 = T2.FILTER2

这称为完全外部联接

SELECT 
  ISNULL(T1.FILTER1, T2.FILTER1) AS FILTER_1, 
  ISNULL(T1.FILTER2, T2.FILTER2) AS FILTER_2,
  T1.DATA1 AS DATA_1, 
  T2.DATA1 AS DATA_2
FROM TABLE1 T1
FULL OUTER JOIN TABLE2 T2
  ON T1.FILTER1 = T2.FILTER1
 AND T1.FILTER2 = T2.FILTER2
FULL OUTER JOIN
保留每个表中的每个记录,而不管另一个表中是否有匹配项

然后可以使用
COALESCE()

SELECT G.FILTER1, G.FILTER2, T1.DATA1, T2.DATA1 as DATA2 FROM
    (SELECT FILTER1, FILTER2
    FROM TABLE1
  UNION
    SELECT FILTER1, FILTER2
    FROM TABLE2
  GROUP BY FILTER1, FILTER2) as G
LEFT JOIN TABLE1 as T1 ON T1.FILTER1 = G.FILTER1 AND T1.FILTER2 = G.FILTER2
LEFT JOIN TABLE2 as T2 ON T2.FILTER1 = G.FILTER1 AND T2.FILTER2 = G.FILTER2
FULL OUTER JOIN
保留每个表中的每个记录,而不管另一个表中是否有匹配项


然后可以使用
COALESCE()
(有些使用
ISNULL()
)来扫描缺少的/NULL值,以找到第一个非NULL值。

您也可以使用
union all
group by
执行此操作——假设表中没有重复的表:

SELECT G.FILTER1, G.FILTER2, T1.DATA1, T2.DATA1 as DATA2 FROM
    (SELECT FILTER1, FILTER2
    FROM TABLE1
  UNION
    SELECT FILTER1, FILTER2
    FROM TABLE2
  GROUP BY FILTER1, FILTER2) as G
LEFT JOIN TABLE1 as T1 ON T1.FILTER1 = G.FILTER1 AND T1.FILTER2 = G.FILTER2
LEFT JOIN TABLE2 as T2 ON T2.FILTER1 = G.FILTER1 AND T2.FILTER2 = G.FILTER2
select filter_1, filter_2, max(data_1) as data_1, max(data_2) as data_2
from ((select filter_1, filter_2, data_1, NULL as data_2
       from table1
      ) union all
      (select filter_1, filter_2, NULL, data_2
       from table2
      )
     ) t
group by filter_1, filter_2;

我将此作为替代方案。首先,(对我来说)有趣的是,
union-all
/
groupby
的行为与
full-outer-join
的行为相同。更重要的是,如果您开始添加更多的表,那么
完全外部联接
方法将变得很麻烦。将此方法扩展到更多表是很容易的。

您也可以使用
union all
group by
来实现这一点——假设表中没有重复的表:

select filter_1, filter_2, max(data_1) as data_1, max(data_2) as data_2
from ((select filter_1, filter_2, data_1, NULL as data_2
       from table1
      ) union all
      (select filter_1, filter_2, NULL, data_2
       from table2
      )
     ) t
group by filter_1, filter_2;


我将此作为替代方案。首先,(对我来说)有趣的是,
union-all
/
groupby
的行为与
full-outer-join
的行为相同。更重要的是,如果您开始添加更多的表,那么
完全外部联接
方法将变得很麻烦。将此方法扩展到更多表很容易。

是的,我忘记将TABLE1.FILTER1和TABLE2.FILTER1合并到一个列中。我回答得太快了,专注于“加入”部分,让我编辑我的答案。ISNULL不是非标准的SQL bahavior吗?@user1759572-操作说明SQL-SERVER和ISNULL在那里是完全正常的。@user1759572我认为这是非标准的,我不是100%确定。但是问题是标记为sql server,它比合并(相当长)要短,所以…是的,我忘记了将TABLE1.FILTER1和TABLE2.FILTER1合并到一个列中。我回答得太快了,专注于“加入”部分,让我编辑我的答案。ISNULL不是非标准的SQL bahavior吗?@user1759572-操作说明SQL-SERVER和ISNULL在那里是完全正常的。@user1759572我认为这是非标准的,我不是100%确定。但是问题是标记为sql server,它比(相当长的)合并要短,所以…请验证我的逻辑:如果我知道TABLE1包含所有筛选器组合,我可以使用左连接而不使用合并,我的查询速度会快得多。@MattAlexander-合并几乎不会影响性能。即使在对大量输出记录执行标量函数时,与连接本身相比,标量函数几乎总是微不足道的。但是,是的,在您的新示例中,您可以使用左连接,这可能有性能优势,具体取决于索引等。请验证我的逻辑:如果我知道表1包含所有过滤器组合,我可以使用左连接,而不使用合并,而且我的查询速度会快得多。@matt-COALESCE几乎不会影响性能。即使在对大量输出记录执行标量函数时,与连接本身相比,标量函数几乎总是微不足道的。但是,在您的新示例中,可以使用左连接,这可能有性能优势,具体取决于索引等。为什么这比完全外部连接更可取?这似乎是阅读量的两倍……没有偏好,只是另一种方式而已。就性能而言,它的性能不如完全外部连接。为什么这比完全外部连接更好?这似乎是阅读量的两倍……没有偏好,只是另一种方式而已。就性能而言,它的性能不如完全外部联接。是否不需要联合中的第一个SELECT来显式地将NULL强制转换为正确的数据类型?如果不是,SQL Server使用什么规则来确定用NULL初始化的字段的数据类型?是否不需要联合中的第一个SELECT来显式地将NULL强制转换为正确的数据类型?如果不是,SQL Server使用什么规则来确定用NULL初始化的字段的数据类型?