SQL Server里的INTERSECT ALL

原文:SQL Server里的INTERSECT ALL

在上一篇文章里,我讨论了INTERSECT设置操作的基础,它和INNER JOIN的区别,还有为什么需要好的索引设计支持。今天我想谈下SQL Server里并未实现的INTERSECT ALL操作。

INTERSECT ALL是SQL特性的一部分,但SQL Server并不考虑它。和INTERSECT操作的区别非常简单:INTERSECT ALL不会剔除重复行。在SQL Server里的好处是你可以模拟INTERSECT ALL。我们来试下,再次创建2个表,并插入一些行。 

 1 -- Create the 1st table
 2 CREATE TABLE t1
 3 (
 4     Col1 INT,
 5     Col2 INT,
 6     Col3 INT
 7 )
 8 GO
 9
10 -- Create the 2nd table
11 CREATE TABLE t2
12 (
13     Col1 INT,
14     Col2 INT
15 )
16 GO
17
18 -- Insert some records into both tables
19 INSERT INTO t1 VALUES (1, 1, 1), (2, 2, 2), (2, 2, 2), (3, 3, 3)
20 INSERT INTO t2 VALUES (2, 2), (2, 2), (3, 3)
21 GO

你会发现,第2个表包含重复记录——在表里值为2的记录出现了2次。现在当你在2个表之间进行INTERSECT,值为2的记录在结果集只出现1次。重复行被剔除了。

如果你想保留重复行,你必须使它们唯一。这里的一个方法是使用自SQL Server 2005后引入的ROW_NUMBER()窗口函数。使用这个函数你为每个重复记录生成唯一的行号。因此你的重复记录变成了唯一,“重复”行如期望的返回2次。下列代码显示了这个技术:

 1 -- You can preserve duplicate rows by making them unique with the ROW_NUNBER() Windowing Function.
 2 WITH IntersectAll AS
 3 (
 4     SELECT
 5         ROW_NUMBER() OVER (PARTITION BY Col1, Col2 ORDER BY (SELECT 0)) AS RowNumber,
 6         Col1,
 7         Col2
 8     FROM t1
 9
10     INTERSECT
11
12     SELECT
13         ROW_NUMBER() OVER (PARTITION BY Col1, Col2 ORDER BY (SELECT 0)) AS RowNumber,
14         Col1,
15         Col2
16     FROM t2
17 )
18 SELECT Col1, Col2 FROM IntersectAll
19 GO

小结

SQL Server里INTERSECT操作的一个副作用是重复行会剔除不会在结果集里返回。如果你想保留它们,你需要使它们唯一,例如应用ROW_NUMBER() 计算。

感谢关注! 

时间: 2024-09-23 19:51:05

SQL Server里的INTERSECT ALL的相关文章

SQL Server里的INTERSECT

原文:SQL Server里的INTERSECT 在今天的文章里,我想讨论下SQL Server里的INTERSECT设置操作.INTERSECT设置操作彼此交叉2个记录集,返回2个集里列值一样的记录.下图演示了这个概念.   INTERSECT与INNER JOIN 你会发现,它和2个表间的INNER JOIN几乎一样.但今天我会介绍它们之间的一些重要区别.让我们从创建作为输入的2个简单表开始.  1 -- Create the 1st table 2 CREATE TABLE t1 3 (

分析MS SQL Server里函数的两种用法

server|函数 SQL Server里函数的两种用法(可以代替游标) 1. 因为update里不能用存储过程,然而要根据更新表的某些字段还要进行计算.我们常常采用游标的方法,这里用函数的方法实现. 函数部分: 以下是引用片段: CREATE FUNCTION [DBO].[FUN_GETTIME] (@TASKPHASEID INT) RETURNS FLOAT AS BEGIN DECLARE @TASKID INT, @HOUR FLOAT, @PERCENT FLOAT, @RETUR

SQL Server里函数的两种用法(可以代替游标)

server|函数|游标 SQL Server里函数的两种用法(可以代替游标)1. 因为update里不能用存储过程,然而要根据更新表的某些字段还要进行计算.我们常常采用游标的方法,这里用函数的方法实现. 函数部分:CREATE FUNCTION [DBO].[FUN_GETTIME] (@TASKPHASEID INT) RETURNS FLOAT AS BEGIN   DECLARE @TASKID INT,          @HOUR FLOAT,           @PERCENT

SQL Server里如何查询表结构

环境:SQL Server 2008 R2 问题:查询表结构命令 对MySQL和Oracle数据库熟悉的朋友知道用desc就可以查询一张表的结构,但是在SQL Server里执行desc命令会报错. desc Student; --关键字 'desc' 附近有语法错误. 现提供两条命令查询表结构: 1.sp_help table_name; 如: sp_help Student; 执行效果如下: 2.sp_columnstable_name; 如: sp_columns Student; 执行效

在SQL Server里把SQL语句结果生成文本文件

在SQL Server里可以调用DOS下的命令行工具bcp来实现把表里的数据或者SQL语句结果生成文本文件. BCP命令的参数格式: BCP {dbtable | query} {in | out | queryout | format} datafile [-m maxerrors] [-f formatfile] [-e errfile] [-F firstrow] [-L lastrow] [-b batchsize] [-n native type] [-c character type

SQL Server里函数的两种用法

SQL Server里函数的两种用法(可以代替游标) 1. 因为update里不能用存储过程,然而要根据更新表的某些字段还要进行计算.我们常常采用游标的方法,这里用函数的方法实现. 函数部分: 以下是引用片段: CREATE FUNCTION [DBO].[FUN_GETTIME] (@TASKPHASEID INT) RETURNS FLOAT AS BEGIN DECLARE @TASKID INT, @HOUR FLOAT, @PERCENT FLOAT, @RETURN FLOAT IF

sql server-请问在SQL SERVER里,有两个表的查询问题怎么解决

问题描述 请问在SQL SERVER里,有两个表的查询问题怎么解决 一个teacher表,一个stu_info表,现在要查询teacher表中每个教师教师名和的学生数 解决方案 join一下 select t.name, count(s.teacherid) from teachers t join stu_info on t.id = stu_info.teacherid where s.teacherid=t.name 解决方案二: SELECT tearcher.name, COUNT(

SQL Server里Grouping Sets的威力

原文:SQL Server里Grouping Sets的威力 在SQL Server里,你有没有想进行跨越多个列/纬度的聚集操作,不使用SSAS许可(SQL Server分析服务).我不是说在生产里使用开发版,也不是说安装盗版SQL Server. 不可能的任务?未必,因为通过SQL Server里所谓的Grouping Sets就可以.在这篇文章里我会给你概括介绍下Grouping Sets,使用它们可以实现哪类查询,什么是它们的性能优势. 使用Grouping Sets的聚合 假设你有个订单

在SQL Server里为什么我们需要更新锁

原文:在SQL Server里为什么我们需要更新锁 今天我想讲解一个特别的问题,在我每次讲解SQL Server里的锁和阻塞(Locking & Blocking)都会碰到的问题:在SQL Server里,为什么我们需要更新锁?在我们讲解具体需要的原因前,首先我想给你介绍下当更新锁(Update(U)Lock)获得时,根据它的兼容性锁本身是如何应对的. 一般来说,当执行UPDATE语句时,SQL Server会用到更新锁(Update Lock).如果你查看对应的执行计划,你会看到它包含3个部分