为什么以下查询返回无限行?我本来希望该EXCEPT条款终止递归..
with cte as (
select *
from (
values(1),(2),(3),(4),(5)
) v (a)
)
,r as (
select a
from cte
where a in (1,2,3)
union all
select a
from (
select a
from cte
except
select a
from r
) x
)
select a
from r
Run Code Online (Sandbox Code Playgroud)
想象一下,您有两个不同的表/查询,它们应该具有/返回相同的数据。您想验证这一点。像下面的示例一样显示每个表中任何不匹配的行的简单方法是什么,比较每一列?假设表中有 30 列,其中许多是 NULLable。
当没有 PK 或每个 PK 可能有重复项时,仅加入 PK 列是不够的,并且必须使用 30 个正确处理 NULL 的连接条件进行 FULL JOIN 以及讨厌的 WHERE 条件将是一场灾难排除匹配的行。
通常,当我针对未经整理或未完全理解的数据编写新查询时,问题最严重,并且 PK 在逻辑上可用的可能性极低。我想出了两种不同的方法来解决问题,然后比较它们的结果,差异突出了我不知道的数据中的特殊情况。
结果需要如下所示:
Which Col1 Col2 Col3 ... Col30
------ ------ ------ ------ ------
TableA Cat 27 86 -- mismatch
TableB Cat 27 105 -- mismatch
TableB Cat 27 87 -- mismatch 2
TableA Cat 128 92 -- no corresponding row
TableB Lizard 83 NULL -- no corresponding row
Run Code Online (Sandbox Code Playgroud)
如果[Col1, Col2]确实是一个复合键并且我们在最终结果中按它们排序,那么我们可以很容易地看到 A 和 B 有一行不同的应该是相同的,并且每一行都有一行不在另一行中。
在上面的例子中,两次看到第一行是不可取的。
这是用于设置示例表和数据的 …
该EXCEPT运营商已在SQL Server 2005中引入的,但之间有什么区别NOT IN和EXCEPT?
它也这样做吗?我想用一个例子做一个简单的解释。
sql-server-2005 sql-server sql-server-2008-r2 operator except
我有两个数据库服务器,通过链接服务器连接。两者都是 SQL Server 2008R2 数据库,链接服务器连接是通过常规“SQL Server”链接使用当前登录的安全上下文建立的。链接的服务器都在同一个数据中心,所以连接应该不是问题。
我使用以下查询来检查列的哪些值identifier可远程使用,但不能在本地使用。
SELECT
identifier
FROM LinkedServer.RemoteDb.schema.[TableName]
EXCEPT
SELECT DISTINCT
identifier
FROM LocalDb.schema.[TableName]
Run Code Online (Sandbox Code Playgroud)
在两个表上的列上都有非聚集索引identifier。本地大约有 260 万行,远程只有 54 行。然而,在查看查询计划时,70% 的执行时间用于“执行远程查询”。此外,在研究完整的查询计划时,估计的本地行数是1而不是2695380(这是仅选择后面的查询时的估计行数EXCEPT)。
执行此查询时,确实需要很长时间。
不禁让人疑惑:这是为什么呢?估计是“刚刚”结束,还是链接服务器上的远程查询真的那么昂贵?
我们正在做一个 ETL 过程。当一切都说完后,有一堆表格应该是相同的。验证这些表(在两个不同的服务器上)实际上相同的最快方法是什么?我说的是架构和数据。
我可以在表上做一个散列,就像我可以在单个文件或文件组上一样 - 将一个与另一个进行比较。我们有 Red-Gate 数据比较,但由于有问题的表每个都包含数百万行,我想要一些性能更高的东西。
一种让我感兴趣的方法是对 union 语句的这种创造性使用。但是,如果可能的话,我想进一步探索散列的想法。
发布答案更新
对于任何未来的访客......这是我最终采取的确切方法。它工作得很好,我们在每个数据库的每个表上都这样做。感谢下面的答案为我指明了正确的方向。
CREATE PROCEDURE [dbo].[usp_DatabaseValidation]
@TableName varchar(50)
AS
BEGIN
SET NOCOUNT ON;
-- parameter = if no table name was passed do them all, otherwise just check the one
-- create a temp table that lists all tables in target database
CREATE TABLE #ChkSumTargetTables ([fullname] varchar(250), [name] varchar(50), chksum int);
INSERT INTO #ChkSumTargetTables ([fullname], [name], [chksum])
SELECT DISTINCT
'[MyDatabase].[' + S.name + '].['
+ T.name + ']' …Run Code Online (Sandbox Code Playgroud) 在一些 SQL Server 开发人员中,普遍认为NOT IN速度非常慢,应该重写查询,以便它们返回相同的结果,但不要使用“evil”关键字。(示例)。
这有什么道理吗?
例如,SQL Server 中是否存在一些已知错误(哪个版本?)导致使用NOT IN的查询比使用的等效查询具有更差的执行计划
LEFT JOIN结合了NULL支票或(SELECT COUNT(*) ...) = 0在WHERE条款中?目前,我正在比较两个包含独特StoreKey/ProductKey组合的数据集。
第一个数据集具有StoreKey/ProductKey2012 年 1 月开始到 2014 年 5 月结束之间的唯一销售组合(结果 = 450K 行)。第二个数据集具有独特的StoreKey/ProductKey组合,销售从 2014 年 6 月开始,直到今天(结果 = 190K 行)。
我正在寻找StoreKey/ProductKey属于第 2 组但不在第 1 组的组合 - 即从 6 月初开始销售的新产品。
到目前为止,我已将两个数据集转储到临时表中,为两个表的两个键创建索引,并使用该EXCEPT语句查找唯一项。
比较如此大的数据集的最有效方法是什么?有没有更有效的方法来进行这种大型比较?
performance sql-server sql-server-2008-r2 except query-performance
我希望能够轻松检查查询中提供的表中不存在哪些唯一标识符。
为了更好地解释,这是我现在要做的,以检查表中不存在列表“1、2、3、4”的哪些 ID:
SELECT * FROM dbo."TABLE" WHERE "ID" IN ('1','2','3','4'),假设该表不包含 ID 为 2 的行。#N/A都在表中没有出现的值上。我认为必须有更好的方法来做到这一点。理想情况下,我正在寻找类似的东西
要检查的列表 -> 查询要检查的表 -> 不在表中的列表成员
在 SQL Server 中,Except运算符如何在幕后工作的内部算法是什么?它是否在内部获取每一行的哈希值并进行比较?
David Lozinksi 进行了一项研究,SQL:在不存在新记录的地方插入新记录的最快方法他表明,对于大量行,Except 语句是最快的;与我们下面的结果密切相关。
假设:我认为 Left join 会最快,因为它只比较 1 列,Except 花费的时间最长,因为它必须比较所有列。
有了这些结果,现在我们的想法是,Except 自动并在内部获取每一行的哈希值?我查看了除非执行计划,它确实使用了一些哈希。
背景:我们的团队正在比较两个堆表。表 A 不在表 B 中的行被插入到表 B 中。
堆表(来自旧文本文件系统)没有主键/guids/标识符。有些表有重复的行,所以我们找到每一行的Hash,并去除重复,并创建主键标识符。
1)首先我们运行一个except语句,排除(哈希列)
select * from TableA
Except
Select * from TableB,
Run Code Online (Sandbox Code Playgroud)
2)然后我们在HashRowId上的两个表之间运行左连接比较
select *
FROM dbo.TableA A
left join dbo.TableB B
on A.RowHash = B.RowHash
where B.Hash is null
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,Except Statement Insert 是最快的。
结果实际上与 David Lozinksi 的测试结果接近
performance sql-server hashing sql-server-2016 except performance-tuning
比较两个大型结果/行集的最有效方法的当前建议似乎是使用EXCEPT运算符。随着行大小的增加(更改@last 值),下面这个自包含的 SQL 脚本变得非常低效。我试图在组合表中找到唯一的条目,但没有任何改进。
DECLARE @first AS INT, @step AS INT, @last AS INT;
-- This script is comparing two record sets using EXCEPT
-- I want to find additions from OLD to NEW
-- As number of rows increase performance gets terrible
-- I don't have to use two tables. I could use one combined table but I want the same result as quickly as possible
-- Compare 100 to 110 rows - 0 seconds
-- Compare …Run Code Online (Sandbox Code Playgroud)