SQL 服务器中 "Except All" 的替代方案
Alternative for "Except All" in SQL Server
标准 SQL 定义 EXCEPT ALL
其操作如下 (Postgres fiddle)
CREATE TABLE T1(X INT);
CREATE TABLE T2(X INT);
INSERT INTO T1 VALUES (1),(1),(2);
INSERT INTO T2 VALUES (1),(2);
SELECT X
FROM T1
EXCEPT ALL
SELECT X
FROM T2
这个returns
+---+
| X |
+---+
| 1 |
+---+
因为 T1
与 T2
中多了一个 1
行。
SQL 服务器只允许 EXCEPT
和
SELECT X
FROM T1
EXCEPT
SELECT X
FROM T2
returns 空结果集。我如何实施 EXCEPT ALL
?
尝试使用 where not exists 子句,这将使您无法获得不同的列表。
Use AdventureWorks2017;
Go
Create Table #A (a int, b varchar(1))
Insert into #A (a, b)
Select 1, 'A' UNION ALL
Select 1, 'A' UNION ALL
Select 1, 'A' UNION ALL
Select 2, 'B'
Create Table #B (a int, b varchar(1))
Insert into #B (a, b)
Select 2, 'B'
Select a, b
FROM #A
EXCEPT
Select a, b
From #B
Select a, b
from #A as a where not exists (Select 1 from #B as b
where a.a = b.a and a.b = b.b)
您可以通过运行上述代码看到where not exists子句和except子句之间的不同结果集。
希望对您有所帮助。
By definition、EXCEPT
returns 来自左侧输入查询但右侧输入查询未输出的不同行。
MS SQL Server 2017 架构设置:
CREATE TABLE MyTableA (ColA int, ColB int)
CREATE TABLE MyTableB (ColA int, ColB int)
INSERT INTO MyTableA (ColA, ColB) VALUES (15,1),(10,1),(2,1),(2,1),(16,1),(2,2),(3,3),(3,3)
INSERT INTO MyTableB (ColA, ColB) VALUES (1,1),(1,1),(1,1),(2,2),(4,5),(1,1),(4,5)
查询 1:
SELECT * FROM MyTableA
EXCEPT
SELECT * FROM MyTableB
| ColA | ColB |
|------|------|
| 2 | 1 |
| 3 | 3 |
| 10 | 1 |
| 15 | 1 |
| 16 | 1 |
查询 2:
Select *
from MyTableA as a where not exists (Select 1 from MyTableB as b
where a.ColA = b.ColA and a.ColB = b.ColB)
| ColA | ColB |
|------|------|
| 15 | 1 |
| 10 | 1 |
| 2 | 1 |
| 2 | 1 |
| 16 | 1 |
| 3 | 3 |
| 3 | 3 |
EXCEPT ALL
SQL 服务器不支持。随着表格
t1
a | b
--+--
1 | 1
1 | 1
1 | 1
1 | 2
1 | 2
1 | 3
和
t2
a | b
--+--
1 | 1
1 | 2
1 | 4
查询
select a, b from t1
except all
select a, b from t2
order by a, b;
会return
a | b
--+--
1 | 1
1 | 1
1 | 2
1 | 3
因为 t1 比 t2 多两 (1|1) 行,多 (1|2) 行和多 (1|3) 行。
要在 SQL 服务器中实现相同的效果,请对行进行编号:
select a, b from
(
select a, b, row_number() over (partition by a, b order by a) as rn from t1
except
select a, b, row_number() over (partition by a, b order by a) as rn from t2
) evaluated
order by a, b;
标准 SQL 定义 EXCEPT ALL
其操作如下 (Postgres fiddle)
CREATE TABLE T1(X INT);
CREATE TABLE T2(X INT);
INSERT INTO T1 VALUES (1),(1),(2);
INSERT INTO T2 VALUES (1),(2);
SELECT X
FROM T1
EXCEPT ALL
SELECT X
FROM T2
这个returns
+---+
| X |
+---+
| 1 |
+---+
因为 T1
与 T2
中多了一个 1
行。
SQL 服务器只允许 EXCEPT
和
SELECT X
FROM T1
EXCEPT
SELECT X
FROM T2
returns 空结果集。我如何实施 EXCEPT ALL
?
尝试使用 where not exists 子句,这将使您无法获得不同的列表。
Use AdventureWorks2017;
Go
Create Table #A (a int, b varchar(1))
Insert into #A (a, b)
Select 1, 'A' UNION ALL
Select 1, 'A' UNION ALL
Select 1, 'A' UNION ALL
Select 2, 'B'
Create Table #B (a int, b varchar(1))
Insert into #B (a, b)
Select 2, 'B'
Select a, b
FROM #A
EXCEPT
Select a, b
From #B
Select a, b
from #A as a where not exists (Select 1 from #B as b
where a.a = b.a and a.b = b.b)
您可以通过运行上述代码看到where not exists子句和except子句之间的不同结果集。
希望对您有所帮助。
By definition、EXCEPT
returns 来自左侧输入查询但右侧输入查询未输出的不同行。
MS SQL Server 2017 架构设置:
CREATE TABLE MyTableA (ColA int, ColB int)
CREATE TABLE MyTableB (ColA int, ColB int)
INSERT INTO MyTableA (ColA, ColB) VALUES (15,1),(10,1),(2,1),(2,1),(16,1),(2,2),(3,3),(3,3)
INSERT INTO MyTableB (ColA, ColB) VALUES (1,1),(1,1),(1,1),(2,2),(4,5),(1,1),(4,5)
查询 1:
SELECT * FROM MyTableA
EXCEPT
SELECT * FROM MyTableB
| ColA | ColB |
|------|------|
| 2 | 1 |
| 3 | 3 |
| 10 | 1 |
| 15 | 1 |
| 16 | 1 |
查询 2:
Select *
from MyTableA as a where not exists (Select 1 from MyTableB as b
where a.ColA = b.ColA and a.ColB = b.ColB)
| ColA | ColB |
|------|------|
| 15 | 1 |
| 10 | 1 |
| 2 | 1 |
| 2 | 1 |
| 16 | 1 |
| 3 | 3 |
| 3 | 3 |
EXCEPT ALL
SQL 服务器不支持。随着表格
t1 a | b --+-- 1 | 1 1 | 1 1 | 1 1 | 2 1 | 2 1 | 3
和
t2 a | b --+-- 1 | 1 1 | 2 1 | 4
查询
select a, b from t1
except all
select a, b from t2
order by a, b;
会return
a | b --+-- 1 | 1 1 | 1 1 | 2 1 | 3
因为 t1 比 t2 多两 (1|1) 行,多 (1|2) 行和多 (1|3) 行。
要在 SQL 服务器中实现相同的效果,请对行进行编号:
select a, b from
(
select a, b, row_number() over (partition by a, b order by a) as rn from t1
except
select a, b, row_number() over (partition by a, b order by a) as rn from t2
) evaluated
order by a, b;